When to use this module

  • Upload images or documents for contacts or WhatsApp messages
  • Attach WhatsApp message media → upload, then use fileId in the message payload
  • Upload a CSV import fileMode=Import, pass fileId to the import endpoint

Endpoints

MethodRouteAuthDescription
POST/api/v1/Files/chunk🔑 API KeyUpload chunk(s) to Azure Blob (multipart/form-data)

Chunk Upload — Form Fields

The chunk upload endpoint accepts multipart/form-data. The endpoint handles both single-chunk (small) and multi-chunk (large) uploads — the difference is in how many calls you make.

FieldTypeRequiredDescription
FileIFormFilerequiredThe binary file chunk to upload
BlockIndexintrequiredZero-based chunk index (0 for first chunk)
TotalBlocksintrequiredTotal number of chunks for this file
ModeenumrequiredFirm / Profile / Contact / Message / Template / Import
FileIdGuid?optionalRequired for chunks after the first (BlockIndex > 0) to correlate parts

Single-Chunk Upload Flow

For small files (e.g., profile pictures, logos), send the entire file as one chunk with TotalBlocks=1.

POST /api/v1/Files/chunk { File, CurrentBlock=1, TotalBlocks=1, Mode=User } │ ▼ Upload blob to Azure → Create AzureFileObj record │ ▼ Return { FileId, URL, isComplete: true }

Multi-Chunk Upload Flow

For large files, split into chunks and send sequentially. The server stages each block until the final chunk triggers the commit.

POST /files/chunk { File, CurrentBlock=1, TotalBlocks=5, Mode=WhatsappMedia } → Uploads block 0 to Azure Staged Blocks → Returns { FileId: "new-guid", isComplete: false } POST /files/chunk { File, CurrentBlock=2, TotalBlocks=5, FileId="same-guid" } → Uploads block 1 → { isComplete: false } ... (blocks 2, 3) ... POST /files/chunk { File, CurrentBlock=5, TotalBlocks=5, FileId="same-guid" } → Uploads block 4 → Commits all blocks into final blob → Creates AzureFileObj record → Returns { FileId, URL, isComplete: true }
Always store the FileId from the first response and pass it in all subsequent chunk requests. The server uses it to group blocks before committing.

Blob Container Organization

All files are stored in a single Azure Blob container (configurable). The Mode determines the path prefix within the container.

ModeBlob PathUsage
Firmfirms/{firmId}/Logos (light, dark, favicon)
Profileprofiles/{userId}/User profile pictures
Contactcontacts/{firmId}/Contact profile pictures
Messagemessages/{firmId}/WhatsApp message attachments
Templatetemplates/{firmId}/WhatsApp template media files
Importimports/{firmId}/CSV contact import files

Upload Response

JSON
{
  "isSuccess": true,
  "data": {
    "fileId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "url": "https://accountname.blob.core.windows.net/uploads/profiles/userId/filename.jpg",
    "isComplete": true
  },
  "message": "File uploaded successfully"
}

Meta Resumable Upload (WhatsApp Media)

This flow runs inside the Worker service, not in the API. Client code only needs to upload to /files/chunk and pass the returned fileId in the message/template payload.
Client uploads file via POST /api/v1/Files/chunk │ ▼ API stores file in Azure Blob → returns FileId + URL │ ▼ Client passes FileId in WhatsApp message/template payload │ ▼ Worker picks up the task from RabbitMQ queue │ ▼ Worker downloads file from Azure Blob (streams to memory) │ ▼ Worker streams into Meta Graph API Resumable Upload endpoint │ ▼ Meta returns media handle → Worker uses handle in send-message call