Skip to content

Add recipients

View .md
POST

Up to 1,000 per call. Recipients are held to the rules POST /v2/messages holds to to. Validation happens in two steps with different outcomes:

  1. The request as a whole. A phone number written with spaces, dashes, dots or parentheses after its + is read as the E.164 number first. Then a recipient that is not a phone number, email address, BSUID or chat id makes the whole request 400, with details.errors[].path naming it (["contacts", 2, "recipient"]); so do 8-15 bare digits on an sms, sms_oneway, whatsapp, voice or smart campaign, with details.errors[].suggestion (+<digits>), as a send refuses them. Nothing is added.
  2. Each recipient against the campaign. A well-formed recipient the campaign cannot reach is skipped and reported in invalid and errors[{recipient, reason, code?}]: code: "unreachable_by_channel" for an email address on a phone campaign or a phone number on an email campaign; code: "ten_dlc_required" for a US/Canadian (+1) number on an sms or sms_oneway campaign while this project has no approved 10DLC campaign (the send would refuse it, as POST /v2/messages answers 403 ten_dlc_required). Repeats of a recipient already in the campaign or in the same call are skipped as duplicates. The others are added, and the call answers 201.

So 201 can mean some were not added: check invalid. A campaign that is not a draft answers 409 invalid_status.

Authorization

  • Authorizationheaderrequired

    Bearer YOUR_API_KEY. Create a key in the dashboard.

Path parameters

  • campaignIdstringrequired

    Campaign ID. The same ID works as broadcastId on /v1.

Body

application/json

  • contactsobject[]required

    List of contacts to add (max 1000 per request).

    Limitsmax items 1000
    4 properties
    • recipientstringrequired

      Phone number (E.164) or email address. On a telegram broadcast, the numeric chat ID of someone who has already written to your bot (838360395, or telegram:838360395); a phone number is rejected there, because a bot cannot start a chat.

    • templateVariablesobject

      Per-contact body variables. Key them to match the template body: by position (1, 2, ...) for positional templates, or by name (e.g. customer_name) for named templates. Zavu detects the template's format and sends the correct payload to Meta. Do not mix positional and named keys.

      1 properties
      • {key}string
    • templateButtonVariablesobject

      Per-contact button variables for dynamic URL/OTP buttons. Keys are the button index (0, 1, 2).

      1 properties
      • {key}string
    • templateHeaderVariablesobject

      Per-contact value for a text-header variable, keyed by 1. If omitted, Zavu resolves the header from templateVariables by the header placeholder's name.

      1 properties
      • {key}string

Responses

201Processed. `added` + `duplicates` + `invalid` equals the number sent.
  • addedintegerrequired

    Number of contacts successfully added.

  • duplicatesintegerrequired

    Number of duplicate contacts skipped.

  • invalidintegerrequired

    Number of invalid contacts rejected.

  • errorsobject[]

    Details about invalid contacts.

    3 properties
    • recipientstring
    • reasonstring

      Why it was not added, in words that are true of this recipient and this campaign.

    • codestring

      Set for unreachable_by_channel and ten_dlc_required. Absent on other reasons.

      One ofunreachable_by_channelten_dlc_required
400A malformed recipient, or bare digits on a phone campaign (`details.errors`, with `suggestion`); nothing added.
  • codestringrequired
  • messagestringrequired
  • detailsobject

    Machine-readable context. Keys that mean the same thing everywhere: - errors: present on every 400 invalid_request for an invalid body or query parameter, [{path, message, ...}], path naming the field (["to"], ["contacts", 2, "recipient"], ["limit"]). - recommendation: one sentence saying what to do next. - dashboardUrl: the dashboard screen that fixes it. - connect: on 409 no_channel, the channels this project can connect to reach the recipient, each {type, request, note, available, dashboardUrl?}; request is the exact call (POST /v2/channels with its body, or POST /v2/numbers), or null for a channel connected from the dashboard (WhatsApp, Instagram, Messenger). available: false says why in note (one-way SMS closed until business verification is approved). - address / from: the address the error is about, under the name the request used for it.

    1 properties
    • errorsobject[]
      3 properties
      • pathobject[]required
      • messagestringrequired
      • codestring
401Unauthorized.
  • codestringrequired
  • messagestringrequired
  • detailsobject

    Machine-readable context. Keys that mean the same thing everywhere: - errors: present on every 400 invalid_request for an invalid body or query parameter, [{path, message, ...}], path naming the field (["to"], ["contacts", 2, "recipient"], ["limit"]). - recommendation: one sentence saying what to do next. - dashboardUrl: the dashboard screen that fixes it. - connect: on 409 no_channel, the channels this project can connect to reach the recipient, each {type, request, note, available, dashboardUrl?}; request is the exact call (POST /v2/channels with its body, or POST /v2/numbers), or null for a channel connected from the dashboard (WhatsApp, Instagram, Messenger). available: false says why in note (one-way SMS closed until business verification is approved). - address / from: the address the error is about, under the name the request used for it.

    1 properties
    • errorsobject[]
      3 properties
      • pathobject[]required
      • messagestringrequired
      • codestring
404Campaign not found, or it belongs to another project.
  • codestringrequired
  • messagestringrequired
  • detailsobject

    Machine-readable context. Keys that mean the same thing everywhere: - errors: present on every 400 invalid_request for an invalid body or query parameter, [{path, message, ...}], path naming the field (["to"], ["contacts", 2, "recipient"], ["limit"]). - recommendation: one sentence saying what to do next. - dashboardUrl: the dashboard screen that fixes it. - connect: on 409 no_channel, the channels this project can connect to reach the recipient, each {type, request, note, available, dashboardUrl?}; request is the exact call (POST /v2/channels with its body, or POST /v2/numbers), or null for a channel connected from the dashboard (WhatsApp, Instagram, Messenger). available: false says why in note (one-way SMS closed until business verification is approved). - address / from: the address the error is about, under the name the request used for it.

    1 properties
    • errorsobject[]
      3 properties
      • pathobject[]required
      • messagestringrequired
      • codestring
409`invalid_status`: the campaign is not a draft (`details.status`).
  • codestringrequired
  • messagestringrequired
  • detailsobject

    Machine-readable context. Keys that mean the same thing everywhere: - errors: present on every 400 invalid_request for an invalid body or query parameter, [{path, message, ...}], path naming the field (["to"], ["contacts", 2, "recipient"], ["limit"]). - recommendation: one sentence saying what to do next. - dashboardUrl: the dashboard screen that fixes it. - connect: on 409 no_channel, the channels this project can connect to reach the recipient, each {type, request, note, available, dashboardUrl?}; request is the exact call (POST /v2/channels with its body, or POST /v2/numbers), or null for a channel connected from the dashboard (WhatsApp, Instagram, Messenger). available: false says why in note (one-way SMS closed until business verification is approved). - address / from: the address the error is about, under the name the request used for it.

    1 properties
    • errorsobject[]
      3 properties
      • pathobject[]required
      • messagestringrequired
      • codestring