Get message activities

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.

GET
/v3/messages/{id}/activities

Response Body

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v3/messages/8ba7b830-9dad-11d1-80b4-00c04fd430c8/activities"
{
  "success": true,
  "data": {
    "message_id": "8ba7b830-9dad-11d1-80b4-00c04fd430c8",
    "activities": [
      {
        "status": "DELIVERED",
        "description": "Message delivered to recipient",
        "from": "+15551234567",
        "timestamp": "2026-10-20T13:17:48.7470157+00:00",
        "scheduled_at": null,
        "reason_code": null,
        "reason": null,
        "price": "0.0450",
        "active_contact_price": "0.0050"
      },
      {
        "status": "SENT",
        "description": "Message sent via SMS",
        "from": "+15551234567",
        "timestamp": "2026-10-20T13:12:48.7470417+00:00",
        "scheduled_at": null,
        "reason_code": null,
        "reason": null,
        "price": "0.0450",
        "active_contact_price": "0.0050"
      },
      {
        "status": "PROCESSED",
        "description": "Message processed and queued for sending",
        "from": null,
        "timestamp": "2026-10-20T13:11:48.7470419+00:00",
        "scheduled_at": null,
        "reason_code": null,
        "reason": null,
        "price": "0.0450",
        "active_contact_price": "0.0050"
      },
      {
        "status": "QUEUED",
        "description": "Message accepted and queued for processing",
        "from": null,
        "timestamp": "2026-10-20T13:10:48.747042+00:00",
        "scheduled_at": null,
        "reason_code": null,
        "reason": null,
        "price": null,
        "active_contact_price": null
      }
    ],
    "pagination": null
  },
  "error": null,
  "meta": {
    "request_id": "req_7X9zKp2jDw",
    "timestamp": "2026-10-20T13:42:48.7470497+00:00",
    "version": "v3"
  }
}
{
  "success": true,
  "error": {
    "code": "string",
    "message": "string",
    "details": {
      "property1": [
        "string"
      ],
      "property2": [
        "string"
      ]
    },
    "doc_url": "string"
  },
  "meta": {
    "request_id": "string",
    "timestamp": "2019-08-24T14:15:22Z",
    "version": "string"
  }
}
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-10-20T13:42:48.7470521+00:00",
    "version": "v3"
  }
}
{
  "success": false,
  "data": null,
  "error": {
    "code": "INTERNAL_001",
    "message": "An unexpected error occurred while retrieving message activities.",
    "details": null,
    "doc_url": "https://docs.sent.dm/reference/api/error-catalog"
  },
  "meta": {
    "request_id": "req_7X9zKp2jDw",
    "timestamp": "2026-10-20T13:42:48.7470525+00:00",
    "version": "v3"
  }
}

Get message status GET

Retrieves the current status and details of a message by ID. Includes delivery status, timestamps, and error information if applicable.

Cancel a scheduled message POST

Calls off a message you scheduled with `scheduled_at`, before it is released for sending. The message moves to `CANCELLED`, which is terminal, and it is never sent. **Only a SCHEDULED message can be cancelled.** A message that has already been released — queued, in flight, or finished — returns 409. The release sweeper runs continuously, so a cancellation sent within about a minute of the scheduled instant can lose that race and be refused; cancel with time to spare. **One message per call.** A send to many recipients, or on several channels, becomes one message per recipient × channel, each with its own id; cancel the ones you want stopped. There is no bulk cancellation. **Cancelling is free**, and nothing was charged for the hold in the first place — a scheduled message is only priced and billed at release. **A cancellation fires `message.cancelled`** on your webhook, exactly once, carrying the `scheduled_at` that was called off so a consumer can un-record the send it was expecting. Cancelling the same message again returns this same response and fires no second event. `Idempotency-Key` is honoured. A cancelled message cannot be resent — send a new one. The response is the message itself, in the same shape `GET /v3/messages/{id}` returns, so the `status` you read back is the one now stored on the row, and `scheduled_at` is the time it would have gone out. `GET /v3/messages/{id}` keeps reporting both afterwards. `events` is the message lifecycle as it stood immediately before the cancellation: the CANCELLED entry is written asynchronously and lands a moment later, so read `status` for the outcome. If you need the entry itself, re-fetch the message after a few seconds — `GET /v3/messages/{id}` is cached briefly, so an immediate re-fetch can still show the pre-cancellation state.