Skip to content

Pagination and filters ​

GET /v1/messages returns 100 messages a page, newest first, and a next_cursor. Pass it as cursor to get the next page; it is null on the last page.

json
{
  "data": [{ "id": "msg_CgdWeHQN4sPaZnXfh7kP5", "status": "delivered", "…": "…" }],
  "next_cursor": "msg_CgdWeHQNnp4VN7KkfNqju"
}

The cursor marks a position, not a page number: messages accepted while you page do not shift or repeat the following pages. Treat it as an opaque string.

Filters ​

Parameter
statusOne status, e.g. failed.
channelwhatsapp or sms.
toA number in E.164; the + may be left out.
referenceYour reference, exactly.
templateA template name (of the channel, if given).
from, untilMoments of acceptance, ISO 8601; until is exclusive. Without an offset the time is UTC.

Filters combine with cursor: keep them the same on every page.

Example: reconcile a day ​

js
let cursor = null
do {
  const params = new URLSearchParams({
    from: '2026-11-01T00:00:00Z',
    until: '2026-11-02T00:00:00Z',
  })
  if (cursor) params.set('cursor', cursor)
  const response = await fetch(`https://api.ace-send.com/v1/messages?${params}`, {
    headers: { Authorization: `Bearer ${process.env.ACE_SEND_API_KEY}` },
  })
  const page = await response.json()
  for (const message of page.data) await save(message)
  cursor = page.next_cursor
} while (cursor)

Keep under the read limit of 20 requests a second per key.

ACE SEND API v1