API reference

Sending API messages and billing

POST /v1/messages sends an SMS or MMS to one external recipient from an authorized inbox. Each recipient send accepted by Waveline adds US$0.01 before tax to the workspace's integration usage. Reading messages or copying existing activity into a CRM has no integration sending fee.

Before sending

The connection needs messages.read and messages.write. Choose an inbox within its access that has a registered sending number, and ensure the workspace has an active invoice-backed subscription. Messaging registration, opt-out, and recipient-blocking requirements still apply.

Use an E.164 recipient number, such as +12065550123, and pass inbox_id as a string. A workspace connection must still select the sending inbox for each request. If you provide from, it must be an allowed sender for that inbox.

Send a text

The following Bash/cURL example sends a billable message when valid credentials and real values are supplied. Replace the example inbox and recipient. Set WAVELINE_SEND_REQUEST_ID to a unique ID for this intended send and save it with the request before making the API call.

curl --fail-with-body 'https://api.waveline.tel/v1/messages' \
  --header "Authorization: Bearer $WAVELINE_API_KEY" \
  --header 'Content-Type: application/json' \
  --header "Idempotency-Key: $WAVELINE_SEND_REQUEST_ID" \
  --data '{"inbox_id":"123","to":"+12065550123","body":"Your appointment is confirmed."}'

202 Accepted confirms that Waveline accepted the message for sending; it does not confirm delivery. Follow message.delivered and message.failed webhook events, or retrieve the message records to check the result. The integration appears as the sender in Waveline activity rather than an individual teammate.

Retry without sending twice

Use an Idempotency-Key containing 8–128 visible ASCII characters, such as a saved UUID. Retry an uncertain send with the same key, endpoint, and exact JSON body. Do not generate a new key after a timeout or billing-service error.

Message-send deduplication is permanent. Reusing a key for a different request produces a conflict; it does not revise the original message. Use a new key only for a genuinely new intended send. Persist the key and request in your own job record so a process restart cannot accidentally create another send.

Message fees and your invoice

Each accepted recipient send costs US$0.01 before tax, added to the workspace's subscription invoice. You do not receive a separate card charge for each message.

  • A rejected request creates no integration sending fee.
  • An accepted send costs 1 cent even if delivery later fails.
  • SMS segments and attachment parts do not add extra integration sending fees for that send.
  • A retry of the same accepted request does not add another fee.
  • Normal messaging charges and applicable taxes may also apply.

Workspace Owners and Admins can open the integration's Message usage section to review accepted sends, fees, and usage awaiting billing for the current UTC month. Other teammates do not see these usage totals. Usage marked invoiced has been added to an invoice; it does not mean the invoice has been paid. See Invoices and Billing History for reviewing invoices and payment status.

Send attachments

For MMS, reserve an upload with POST /v1/message-uploads, including the sending inbox, file name, MIME type, byte size, and SHA-256 hash. Upload exactly those bytes to the reserved content URL using the same Bearer credentials and the reserved MIME type. Once the response reports a ready attachment_id, include it in attachment_ids on the message request.

An upload belongs to its connection and inbox and can be consumed by one logical send. Retrying the same send reuses that identity. The message must contain text or attachments; text is limited to 1,600 characters, with at most 10 attachments totaling 5 MiB. Upload reservations expire, so complete the upload and send within the returned expiration time. This temporary upload expiration is separate from API-key lifetime.

See the messages and attachments reference for supported media types, required hash format, reservation responses, and downloads. API sending supports one external phone recipient per request; it does not offer internal messages or group-message composition.