Sending messages
Sending is asynchronous. The API puts the message in the queue and responds 202 right away; the actual send happens afterwards. The result arrives through the message.sent and message.status webhooks.
To send an image, video, audio or document, see Sending media.
POST /v1/instances/{instanceId}/messages/text
| Field | Type | Description |
|---|---|---|
to |
text, required | Phone number of the recipient (see below) |
text |
text, required | Message, 1 to 10,000 characters |
quotedMessageId |
text, optional | Identifier of the message being replied to, up to 128 characters |
curl -X POST https://api.zap.nigora.com.br/v1/instances/INSTANCIA_ID/messages/text \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{ "to": "5511999999999", "text": "Seu pedido saiu para entrega." }'Response (202):
{ "id": "…", "status": "queued" }Keep the id: it is how you match the response to the webhooks. Fields that are not in the table are rejected with 400.
The phone number
Section titled “The phone number”The API ignores everything that is not a digit, so +55 (11) 99999-9999 works. With 10 or 11 digits (area code and number), it adds the 55. The result must have 12 or 13 digits; otherwise the response is 400 with invalid_phone.
To reply to a received message, use its waMessageId in quotedMessageId.
Tracking the result
Section titled “Tracking the result”Set up the webhooks and you receive:
message.sent, when the message left the queue and was sent. The body carries theidreturned in the202, thewaMessageIdand thetype.message.status, on every change in the message’s status. Thestatusissent,delivered,readorfailed.
If sending fails after the message was accepted, message.status arrives with status: "failed" and an error field:
error |
What happened |
|---|---|
number_not_on_whatsapp |
The phone number is not on WhatsApp |
send_failed |
Sending failed after 3 attempts |
instance_suspended |
The instance was suspended before sending |
expired |
The message stayed in the queue for more than 7 days (for example, with the instance disconnected) |
media_too_large |
The file downloaded from the url exceeded the size limit |
media_download_failed |
The API could not download the media from the url |
Send queue
Section titled “Send queue”| Operation | Route | What it does |
|---|---|---|
| View the queue | GET /queue |
Returns { "waiting": n, "delayed": n }: messages waiting for their turn and messages with a retry scheduled |
| Clear the queue | DELETE /queue |
Removes messages that have not been sent yet and returns { "removed": n } |
Messages already sent are not affected by clearing. The removed ones are not sent.
Check whether a number is on WhatsApp
Section titled “Check whether a number is on WhatsApp”POST /v1/instances/{instanceId}/contacts/check accepts 1 to 50 phone numbers per call and requires the instance to be connected:
curl -X POST https://api.zap.nigora.com.br/v1/instances/INSTANCIA_ID/contacts/check \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{ "phones": ["5511999999999", "5511888888888"] }'The response is a list with one item per phone number: { "phone": "...", "exists": true, "jid": "..." }. When the number is not on WhatsApp, you get exists: false and no jid.
Sending errors
Section titled “Sending errors”| Status | Code | When |
|---|---|---|
400 |
validation_error |
Field missing, too large or not in the table; the message lists the fields |
400 |
invalid_phone |
Phone number outside the rules above |
402 |
instance_suspended |
Instance suspended or with a pending payment |
409 |
instance_not_connected |
Instance disconnected, when the disableQueueWhenDisconnected option is on in PATCH /settings |
422 |
contact_opted_out |
The contact asked not to receive messages |
With disableQueueWhenDisconnected off (the default), the API accepts the message even if the instance is disconnected and it waits in the queue.