Skip to main content
Use a BYO or exclusively rented dedicated number assigned to your project. Grant the API key that sender and the required scopes. Sending messages does not require an AI agent.
  1. Create a contact under /projects/{projectId}/contacts and record genuine opt-in through its /consent endpoint.
  2. Create a Utility or Marketing template through /templates. Supply sequential variables {{1}}, {{2}}, and one bounded example for each distinct variable. Organization name is not a template-creation field.
  3. For Live, submit the draft through /templates/{id}/submit and wait for Meta approval. If submission has an uncertain outcome, reconcile it; do not blindly resubmit.
  4. Send using POST /messages with a stable Idempotency-Key:
Template sends cannot include free text or a conversation reply. Match the exact variable count; each value must be nonempty and at most 1,000 characters. Up to 20 distinct variables are supported. Recipient numbers must use supported international E.164 format. The current service-key API supports template sends. Human free-text conversation replies require dashboard inbox authority and a recent inbound conversation; messages:send alone does not grant that permission.

Acceptance and delivery

HTTP 202 means the request and its charge were durably accepted. It does not mean Meta accepted, delivered or read the message. Save data.id, inspect GET /messages/{id} and subscribe to message.status. Statuses include Simulated, Queued, Sending, Accepted, Sent, Delivered, Read, Failed, NeedsReview and Cancelled. Provider acceptance is Accepted; successful delivery is Delivered. Unknown billable provider outcomes become NeedsReview rather than being blindly retried. Revoked keys, unavailable senders or suppression can block queued work. Later failure does not silently reverse the finalized acceptance charge. Reviewed financial corrections use ledger adjustments. Do not resend with a new idempotency key merely because delivery is delayed. Message metadata and content are separate permissions. messages:read exposes status, events and customer charges, not message bodies. The dashboard-only content endpoint is deliberately outside this developer reference.