Skip to content
Nigora Zap API

    Sign in Create account

    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
    Terminal window
    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 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.

    Set up the webhooks and you receive:

    1. message.sent, when the message left the queue and was sent. The body carries the id returned in the 202, the waMessageId and the type.
    2. message.status, on every change in the message’s status. The status is sent, delivered, read or failed.

    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
    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.

    POST /v1/instances/{instanceId}/contacts/check accepts 1 to 50 phone numbers per call and requires the instance to be connected:

    Terminal window
    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.

    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.