Skip to content

API reference

Base URL: https://api.99billingsolutions.com. Every request is authenticated with your API key in the x-api-key header — see Authentication. Requests and responses are JSON with snake_case field names.

Response envelope

// success
{ "status": "success", "message": "…", "data": { … } }

// list
{ "status": "success", "message": "…", "data": { "items": [ … ], "cursor": "…", "has_more": true } }

// error
{ "status": "error", "message": "…", "error_code": "invalid_phone_number", "data": { "field": "to_number" } }

Endpoints

MethodPathPurpose
POST/v1/messages/sendSend one SMS
POST/v1/messages/bulk-sendSend the same SMS to up to 500 numbers
GET/v1/messagesList messages (cursor paginated)
GET/v1/messages/{id}One message with its event timeline
POST/v1/messages/batch-statusStatus of up to 100 messages
GET/POST/v1/campaignsPersonalised sends with {{variables}}
GET/POST/PUT/DELETE/v1/contactsContacts, tags and opt-outs
GET/POST/PUT/DELETE/v1/templatesReusable message templates
GET/POST/PUT/DELETE/v1/webhooksWebhook endpoints and delivery log
GET/v1/devicesPaired phones and their status
GET/v1/analytics/overviewSent / received / delivery-rate totals

Conventions

  • Phone numbers are E.164: a plus sign, country code and number, no spaces (+15551234567).
  • Timestamps are ISO 8601 with a UTC offset. Fields whose value is null are left out of responses.
  • Idempotency: pass request_id when sending; a repeat with the same value returns 409 duplicate_request with the original message id instead of sending twice.
  • Pagination: pass the cursor from the previous page; limit is 1–100 (default 25).
  • Rate limits return 429 with a Retry-After header — see Rate limits.
  • Message text is removed from our database 30 minutes after a message is sent or received, and the whole record after 24 hours. Store anything you need to keep on your side (webhooks are the easiest way).

Try it

Build a request in the API playground, or start with the quickstart.