Messages API overview

The Messages API provides a RESTful HTTP interface for sending outbound SMS messages (single or batch, text or binary), retrieving and polling message delivery statuses, downloading inbound SMS messages, and deleting processed messages from the gateway.

Table of contents

Base path & user context

All Messages API endpoints operate relative to the V2 base path. The user account context is resolved implicitly from the authentication credentials supplied in the Authorization request header:

http://localhost:9509/api/v2

Authentication

Every request must include a valid Authorization header identifying the user account context. Two authentication schemes are supported:

  • Bearer Token (API Key): Authorization: Bearer <api_key>
  • Basic Authentication: Authorization: Basic <base64(username:password)>

Requests with missing or invalid credentials are rejected with 401 Unauthorized.

Data format conventions

  • Media type: Requests with a body and all JSON responses use Content-Type: application/json.
  • Property naming: JSON field names are strictly case-sensitive and use camelCase.
  • Null omission: Properties with null values (such as an omitted from sender, clientReference, or unused text/binary fields) are omitted from serialized JSON responses.
  • Phone numbers: Sender (from) and recipient (to) phone numbers follow the international E.164 format (e.g., "+36201002001").
  • Timestamps: All dates and timestamps are formatted as ISO 8601 strings with timezone offsets (e.g., "2026-10-21T10:21:00+02:00").
  • Message identifiers: Every message is assigned a unique server-generated UUID (messageId), which serves as the primary correlation key across retrieval, deletion, and webhook callback events.

Endpoints summary

Operation HTTP method Endpoint path Success status Documentation
Send a message POST /api/v2/messages 201 Created send_a_message.html
Send multiple messages POST /api/v2/messages:batchSend 202 Accepted send_multiple_messages.html
Retrieve a message GET /api/v2/messages/{messageId} 200 OK retrieve_a_message.html
List messages GET /api/v2/messages 200 OK list_messages.html
Batch get messages POST /api/v2/messages:batchGet 200 OK batch_get_messages.html
Delete a message DELETE /api/v2/messages/{messageId} 204 No Content delete_a_message.html
Batch delete messages POST /api/v2/messages:batchDelete 200 OK batch_delete_messages.html

Core concepts

Message folders

Every SMS message managed by the gateway resides in one of six logical folders representing its current lifecycle stage:

Folder Direction Description
inbox Inbound Messages received from external mobile subscribers by the gateway.
outbox Outbound Messages submitted by API clients and queued for immediate outbound dispatch.
postponed Outbound Messages scheduled for deferred outbound dispatch (scheduledAt > createdAt).
sent Outbound Outbound messages submitted to the mobile network or delivered to recipients.
notsent Outbound Outbound messages that were rejected or failed submission to the provider.
deleted Outbound Outbound messages cancelled or expired prior to dispatch.

Message delivery statuses

Outbound messages (outbox, postponed, sent, notsent) carry a status, a human-readable statusDescription, and an updatedAt timestamp tracking their delivery progress. (Inbound inbox messages and deleted messages omit delivery status fields.)

Status Folder scope Description
queued outbox, postponed SMS accepted by the gateway and queued awaiting dispatch.
rejected notsent Message rejected prior to submission due to validation or policy rules.
submitted sent Message successfully submitted to the telecom provider / SMSC.
partiallysubmitted sent Multi-part message partially submitted to the provider network.
submitfailed notsent Transmission attempt to the telecom provider / SMSC failed.
delivered sent Message confirmed delivered to the recipient handset.
partiallydelivered sent Multi-part message partially confirmed delivered.
deliveryfailed sent Handset delivery failed (e.g., unreachable, expired, or invalid subscriber).
viewed sent Recipient has read or viewed the message payload (where supported).

View projections (MessageView)

Retrieval endpoints (GET /api/v2/messages/{messageId}, GET /api/v2/messages, and POST /api/v2/messages:batchGet) accept an optional view parameter to control the level of detail returned for each message:

View Included fields
"basic" (default) Returns core message metadata (messageId, folder, from, to, type, createdAt, scheduledAt, expiresAt) and delivery status (status, statusDescription, updatedAt), omitting payload body fields (content, hexContent, userDataHeader, dataCoding).
"status_only" Returns only messageId and delivery status fields (status, statusDescription, updatedAt). Ideal for lightweight delivery status polling.
"full" Returns the complete message representation, including core metadata, delivery status, and payload content (content for "text" messages, or hexContent, userDataHeader, and dataCoding for "binary" messages).

Messaging workflows & sequence diagrams

Two primary parties communicate via the API:

  • HTTP API Application — your client application initiating HTTP requests (and optionally exposing an HTTP endpoint to receive webhook callbacks).
  • Ozeki SMS Gateway — the HTTP server connected to the Mobile Network Operator (MNO) to exchange SMS messages and delivery reports with mobile Handsets.

Send message (without callbacks)

When sending SMS messages without webhook callbacks, your application submits the message, polls the gateway until the message reaches a final delivery state (delivered, deliveryfailed, submitfailed, or rejected), and then deletes the message record from the gateway.

Workflow steps:

  1. Send the SMS to the SMS gateway: Call POST /api/v2/messages for a single message (or POST /api/v2/messages:batchSend for multiple messages). The gateway queues the message in the outbox folder (status: "queued") and returns its messageId.
  2. Poll delivery status: Periodically query GET /api/v2/messages/{messageId}?view=status_only (or POST /api/v2/messages:batchGet with "view": "status_only") until status transitions to a final state.
  3. Delete the SMS from the SMS gateway: Once processed, remove the message using DELETE /api/v2/messages/{messageId} (or POST /api/v2/messages:batchDelete).
sequenceDiagram autonumber participant App as HTTP API Application participant GW as Ozeki SMS Gateway participant MNO as Mobile Network Operator participant HS as Handset Note over App,GW: 1. Send the SMS to the SMS gateway App->>+GW: POST /api/v2/messages (to, content) GW-->>-App: 201 Created — messageId, folder: "outbox", status: "queued" GW->>+MNO: Submit SMS for delivery MNO-->>-GW: SMS accepted — submit reference MNO->>HS: Deliver SMS to handset MNO-)GW: Delivery report (DLR) — final status recorded Note over App,GW: 2. Poll delivery status information loop Poll until the message reaches a final state App->>+GW: GET /api/v2/messages/{messageId}?view=status_only GW-->>-App: 200 OK — messageId, status, statusDescription, updatedAt end Note over App,GW: 3. Delete the SMS from the SMS gateway App->>+GW: DELETE /api/v2/messages/{messageId} GW-->>-App: 204 No Content

Send message (using callbacks)

Instead of polling for delivery status updates, your application can receive real-time HTTP callbacks (message.status.updated events) pushed by the gateway whenever an outbound message transitions status.

Note: You can enable status callbacks either per message by supplying the webhook object ({"url": "...", "notify": true}) in POST /api/v2/messages / POST /api/v2/messages:batchSend, or globally for the user account by registering a webhook subscribed to "message.status.updated" via POST /api/v2/webhook.

Workflow steps:

  1. Send the SMS with a callback URL: Submit the message via POST /api/v2/messages (or POST /api/v2/messages:batchSend) including webhook.url (and webhook.notify: true). The gateway returns 201 Created with the assigned messageId.
  2. Wait for status update callbacks: As the message is submitted to the mobile network and delivered to the handset, the gateway sends HTTP POST requests containing a JSON array of message.status.updated event envelopes to your callback URL. Your application acknowledges each callback with a 2xx status code (e.g., 200 OK).
  3. Delete the SMS from the SMS gateway: After receiving the final delivery status (delivered, deliveryfailed, submitfailed, or rejected), delete the message via DELETE /api/v2/messages/{messageId} (or POST /api/v2/messages:batchDelete).
sequenceDiagram autonumber participant App as HTTP API Application participant GW as Ozeki SMS Gateway participant MNO as Mobile Network Operator participant HS as Handset Note over App,GW: 1. Send the SMS to the SMS gateway with a callback URL (webhook.url) App->>+GW: POST /api/v2/messages (to, content, webhook.url) GW-->>-App: 201 Created — messageId, folder: "outbox", status: "queued" GW->>+MNO: Submit SMS for delivery MNO-->>-GW: SMS accepted — submit reference GW->>+App: POST <webhook.url> — [{ type: "message.status.updated", payload: { status: "submitted" } }] App-->>-GW: 200 OK MNO->>HS: Deliver SMS to handset MNO-)GW: Delivery report (DLR) — final status recorded Note over App,GW: 2. Wait for the callback with delivered or failed status GW->>+App: POST <webhook.url> — [{ type: "message.status.updated", payload: { status: "delivered" | "deliveryfailed" } }] App-->>-GW: 200 OK Note over App,GW: 3. Delete the SMS from the SMS gateway App->>+GW: DELETE /api/v2/messages/{messageId} GW-->>-App: 204 No Content

Receive message (without callbacks)

When receiving inbound SMS messages without callbacks, your application periodically polls the inbox folder to download newly arrived messages and then deletes them from the gateway so they are not returned again on subsequent polls.

Workflow steps:

  1. Download incoming SMS messages from the inbox folder: Call GET /api/v2/messages?folder=inbox&view=full to retrieve incoming messages along with their text or binary payload content.
  2. Delete the downloaded incoming SMS messages: Remove the processed messages using DELETE /api/v2/messages/{messageId} for a single message or POST /api/v2/messages:batchDelete for multiple messages.
sequenceDiagram autonumber participant App as HTTP API Application participant GW as Ozeki SMS Gateway participant MNO as Mobile Network Operator participant SH as Sending Handset SH->>MNO: Send SMS to recipient number MNO->>GW: Deliver inbound SMS to gateway Note over GW: SMS stored in the inbox folder Note over App,GW: 1. Download the incoming SMS from the gateway App->>+GW: GET /api/v2/messages?folder=inbox&view=full GW-->>-App: 200 OK — messages (messageId, from, to, content) Note over App,GW: 2. Delete the downloaded incoming SMS from the SMS gateway App->>+GW: DELETE /api/v2/messages/{messageId} GW-->>-App: 204 No Content

Receive message (with callbacks)

To receive inbound SMS messages automatically in real time without polling, register an account webhook subscribed to the "message.received" event. Whenever an inbound SMS arrives in the inbox folder, the gateway pushes it to your webhook endpoint over HTTP POST.

Workflow steps:

  1. Register a webhook URL for incoming messages: Configure your callback endpoint via POST /api/v2/webhook (or PUT /api/v2/webhook) with events: ["message.received"]. The gateway returns 201 Created along with a signing secret (whsec_...) used to verify the X-Hub-Signature-256 header.
  2. Receive the incoming SMS callback: When an inbound SMS arrives, the gateway sends an HTTP POST request to your webhook URL containing a JSON array of message.received event envelopes. Your application verifies the signature, processes the message, and responds with a 2xx HTTP status code (e.g., 200 OK).
  3. Delete the incoming SMS from the SMS gateway: Remove the processed message from the inbox folder using DELETE /api/v2/messages/{messageId} (or POST /api/v2/messages:batchDelete).
sequenceDiagram autonumber participant App as HTTP API Application participant GW as Ozeki SMS Gateway participant MNO as Mobile Network Operator participant SH as Sending Handset Note over App,GW: 1. Register a webhook URL for incoming messages App->>+GW: POST /api/v2/webhook (url, events: ["message.received"]) GW-->>-App: 201 Created — webhookId, url, events, secret SH->>MNO: Send SMS to recipient number MNO->>GW: Deliver inbound SMS to gateway Note over App,GW: 2. Wait for the callback with the message.received event GW->>+App: POST <webhook.url> — [{ type: "message.received", payload: { messageId, from, to, content } }] App-->>-GW: 200 OK Note over App,GW: 3. Delete the SMS from the SMS gateway App->>+GW: DELETE /api/v2/messages/{messageId} GW-->>-App: 204 No Content

More information