Get message status

Retrieves the current status and details of a message by ID. Includes delivery status, timestamps, and error information if applicable. A message that is or was held for a later time (a send you scheduled with scheduled_at, a quiet-hours hold, or a message you cancelled while it was held) is returned as a ScheduledMessageResponse: the same fields plus scheduled_at, the instant it is held for in UTC — or, on a CANCELLED message, the instant that was called off. A message sent immediately has no scheduled_at key.

GET
/v3/messages/{id}

Response Body

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v3/messages/8ba7b830-9dad-11d1-80b4-00c04fd430c8"
{
  "success": true,
  "data": {
    "id": "8ba7b830-9dad-11d1-80b4-00c04fd430c8",
    "customer_id": "550e8400-e29b-41d4-a716-446655440000",
    "contact_id": "550e8400-e29b-41d4-a716-446655440002",
    "phone": "+14155551234",
    "phone_international": "+1 415-555-1234",
    "region_code": "US",
    "template_id": "7ba7b820-9dad-11d1-80b4-00c04fd430c8",
    "template_name": "Welcome Message",
    "template_category": "UTILITY",
    "channel": "sms",
    "message_body": {
      "header": null,
      "content": "Welcome to our service, John! We're excited to have you.",
      "footer": null,
      "buttons": null,
      "subject": null,
      "media": null,
      "headerMedia": null
    },
    "status": "DELIVERED",
    "direction": "OUTBOUND",
    "created_at": "2026-11-05T13:14:26.991975+00:00",
    "price": 0.0055,
    "active_contact_price": 0.015,
    "events": [
      {
        "status": "QUEUED",
        "timestamp": "2026-11-05T13:14:26.9920159+00:00",
        "description": "Message queued for sending",
        "reason_code": null,
        "reason": null
      },
      {
        "status": "SENT",
        "timestamp": "2026-11-05T13:14:31.9920301+00:00",
        "description": "Message sent via SMS",
        "reason_code": null,
        "reason": null
      },
      {
        "status": "DELIVERED",
        "timestamp": "2026-11-05T13:14:36.9920321+00:00",
        "description": "Message delivered to recipient",
        "reason_code": null,
        "reason": null
      }
    ],
    "reason_code": null,
    "reason": null
  },
  "error": null,
  "meta": {
    "request_id": "req_7X9zKp2jDw",
    "timestamp": "2026-11-05T15:14:26.99204+00:00",
    "version": "v3"
  }
}
{
  "success": false,
  "data": null,
  "error": {
    "code": "VALIDATION_001",
    "message": "Invalid message ID format.",
    "details": null,
    "doc_url": "https://docs.sent.dm/reference/api/error-catalog"
  },
  "meta": {
    "request_id": "req_7X9zKp2jDw",
    "timestamp": "2026-11-05T15:14:26.9920423+00:00",
    "version": "v3"
  }
}
Empty
Empty
{
  "success": false,
  "data": null,
  "error": {
    "code": "RESOURCE_003",
    "message": "Message not found",
    "details": null,
    "doc_url": "https://docs.sent.dm/reference/api/error-catalog"
  },
  "meta": {
    "request_id": "req_7X9zKp2jDw",
    "timestamp": "2026-11-05T15:14:26.9920428+00:00",
    "version": "v3"
  }
}
{
  "success": false,
  "data": null,
  "error": {
    "code": "INTERNAL_001",
    "message": "An unexpected error occurred while retrieving the message.",
    "details": null,
    "doc_url": "https://docs.sent.dm/reference/api/error-catalog"
  },
  "meta": {
    "request_id": "req_7X9zKp2jDw",
    "timestamp": "2026-11-05T15:14:26.9920431+00:00",
    "version": "v3"
  }
}

Send a message POST

Sends a message to one or more recipients using a template. Supports multi-channel broadcast — when multiple channels are specified (e.g. ["sms", "whatsapp"]), a separate message is created for each (recipient, channel) pair. To choose which of your own numbers a send goes out from, use 'channels': {"sms": [{"from": ["+12125550000", "+14155550000"]}]}. Each channel holds a list of entries, each with 'from' and optionally 'country' and 'strategy'; 'country' and 'strategy' are stored but not acted on yet, so every entry's numbers apply to every recipient on that channel. Every number listed must be an active sender on your account. Like the other account-level preconditions below, that is checked per message rather than when the request is received: the request is still accepted with 202, and each affected message is reported as BLOCKED with error code BUSINESS_029 on GET /messages/{id} and the message.blocked webhook. Each channel's numbers restrict which numbers that channel may use; it does not choose channels — 'channel' does, and the two can be combined. With 'channel' left at auto-detect, a recipient best served by a channel you listed no numbers for still goes out on it. Where several of the listed numbers could serve a recipient, routing prefers the one whose area code matches theirs. Keys: sms, whatsapp, rcs, mms. Returns immediately with per-recipient message IDs for async tracking via webhooks or the GET /messages/{id} endpoint. Sends gated before any delivery attempt do not reject the request — an account-level precondition such as insufficient balance, a template not approved for sending, or free-form content with no open conversation with the contact. The send is accepted with 202 and the affected messages are reported as BLOCKED on GET /messages/{id} and the message.blocked webhook. To send later, set scheduled_at (ISO-8601 with an explicit UTC offset; a value without one is rejected) between 1 minute and 30 days ahead: the response is a ScheduledSendMessageResponse (the same fields plus scheduled_at; status is still QUEUED), each message then moves to SCHEDULED, is held and released at that time (within a few minutes), and a message.scheduled webhook fires once it is held. Balance and template approval are evaluated at release, not at acceptance. Quiet hours are not checked when the request is accepted: if the time falls inside a legally protected quiet-hours window for a recipient, that message is moved to the next allowed time at release and a second message.scheduled webhook reports the new scheduled_at. An account may hold at most 1,000,000 scheduled messages at once (429 LIMIT_001).

Get message activities GET

Retrieves the activity log for a specific message. Activities track the message lifecycle including acceptance, processing, sending, delivery, and any errors. A SCHEDULED entry carries scheduled_at, the release instant in UTC as it stood at that moment. Other entries have no scheduled_at key.