Create Project
Create a new project. type selects the payload shape: broadcast (the default) sends one message to the audience; survey runs a multi-question flow with branching.
Phone numbers. Assign one or more sending numbers via phone_number_ids (up to 49). The project spreads new conversations randomly across the assigned numbers, and once a recipient has been messaged from a given number every later message to that recipient comes from the same number (sticky sender). A single legacy phone_number_id is still accepted and is treated as a one-element phone_number_ids.
Channel. channel defaults to 10dlc. For broadcast projects a 10dlc channel requires brand_id + campaign_id (and toll_free_verification_id must be omitted), while toll-free requires toll_free_verification_id with matching toll-free phone_number_ids (brand_id/campaign_id omitted). Survey projects always require campaign_id, on both channels.
Surveys. questions defines the whole flow: an intro at sequence 1, then multiple_choice/open_ended questions, optionally ending with an outro. Multiple-choice options can branch with next_sequence, and no_match_sequence routes unmatched replies; both are forward-only. Each question can be SMS or MMS (message_type + media_ids). Question text supports merge tags and {tracking_url}. Surveys need at least 2 questions and 1 phone number.
When link_tracking_enabled is true, link_tracking_destination_url and link_tracking_domain_id become required. The destination URL may embed the selected link_tracking_param_field anywhere via a placeholder named after it, e.g. https://test.com?utm_content=xyzd_{linkid} redirects as ...utm_content=xyzd_ABC123 (no separate &linkid= pair is appended). Without a placeholder the field is appended as its own query pair. A placeholder that does not match the selected field is rejected with a 400 (INVALID_LINK_PLACEHOLDER).
Opt-out footer. Broadcast messages automatically carry the STOP=END opt-out footer. Set opt_out_footer_enabled to false to disable it (defaults to true); surveys never carry the footer.
Drafts. contact_list_ids is optional. With at least one list the created project starts in awaiting_test status (send a test, then schedule). Without it the project is created as a draft; attach lists later via PATCH /projects/{id} and the project moves to awaiting_test automatically. Drafts cannot be tested or scheduled. The response’s completeness block shows what is still missing.
Authorizations
Authenticate every request by passing your API key in the X-API-Key header. Keys are scoped to your organization hierarchy.
Headers
Optional idempotency key: a unique string of 16-200 printable ASCII characters (a UUID is recommended). Retrying the write with the same key within 24 hours returns the stored response of the first call with an X-Idempotent-Replayed: true response header instead of executing it again. Reusing a key with a different request body returns 422 (IDEMPOTENCY_MISMATCH); a duplicate sent while the first call is still running returns 409 with a Retry-After header. Keys are scoped per endpoint and organization.
16 - 200Body
- Broadcast project
- Survey project
Unknown body properties are rejected with a 400 (strict validation).
sms, mms Project type. Optional for broadcast (the default).
broadcast Messaging channel. Defaults to 10dlc.
10dlc, toll-free Required when channel=10dlc; omit when channel=toll-free.
Required when channel=10dlc; omit when channel=toll-free.
Required when channel=toll-free; omit when channel=10dlc. Must match the verification behind the chosen phone_number_ids.
Sending phone number IDs (1-49). At least one of phone_number_ids or phone_number_id is required. New conversations are spread randomly across the numbers; each recipient is then pinned to one number.
1 - 49 elementsDeprecated. Use phone_number_ids. A single id is accepted and treated as a one-element phone_number_ids. Provide one of phone_number_ids or phone_number_id.
Optional. Omit to create the project as a draft with no audience; attach lists later via PATCH /projects/{id}. When present, must contain at least one list id.
1Where tracking links redirect. May embed the selected link parameter anywhere via a placeholder named after it, e.g. 'https://test.com?utm_content=xyzd_{linkid}' redirects as '...utm_content=xyzd_ABC123' (URL-encoded value, empty when the contact has none; the parameter is then not appended separately). A placeholder that does not match link_tracking_param_field is rejected with a 400 (INVALID_LINK_PLACEHOLDER). Without a placeholder the parameter is appended as its own query pair.
Contact field carried on tracking-link redirects. Use 'phone', a contact custom-field name, or omit for no param (default). By default the field's name becomes an appended query-param key with the contact's value; a matching {field} placeholder in link_tracking_destination_url embeds the value there instead.
64Whether the 'STOP=END' opt-out footer is appended to every outbound message. Defaults to true. Broadcast projects only; surveys never carry the footer.
