GET /v1/conversations/{conversationId}/messages

Read a conversation's history, newest first, both ways — what the contact sent and what you sent.

GET /v1/conversations/{conversationId}/messages

A conversation's history, newest first, both ways: what the contact sent you and what you sent them. This is how to read what was said before you were streaming — the stream starts from now, or from an event id you already hold. Catching up after a dropped connection is still Last-Event-ID on the stream, which replays every event, not only messages.

curl "https://api.mapier.ai/v1/conversations/a0000000-0000-4000-8000-000000000001/messages?limit=2" \
  -H "Authorization: Bearer $MAPIER_API_KEY" \
  -H "x-mapier-version: 2026-10-15"
200 OK
{
  "messages": [
    {
      "conversationId": "a0000000-0000-4000-8000-000000000001",
      "from": "+14155550100",
      "text": "is it here yet?",
      "externalId": "guid-1",
      "replyToExternalId": null,
      "occurredAt": "2026-08-24T18:03:11.000Z",
      "attachmentIds": [],
      "attachments": [],
      "messageId": "0192a7c4-6a02-7e11-8c4d-2b9f7e3a5d22",
      "direction": "inbound",
      "status": null,
      "commandId": null
    },
    {
      "conversationId": "a0000000-0000-4000-8000-000000000001",
      "from": "+14155550142",
      "text": "Your order is on its way.",
      "externalId": "guid-0",
      "replyToExternalId": null,
      "occurredAt": "2026-08-24T18:01:02.000Z",
      "attachmentIds": [],
      "attachments": [],
      "messageId": "0192a7c4-5b1e-7c3d-9f2a-6e8d4b1c0a99",
      "direction": "outbound",
      "status": "delivered",
      "commandId": "3f1a0c2e-8b47-4d19-9a5e-2c6f0b8d4e71"
    }
  ],
  "nextCursor": "…"
}

Request

Prop

Type

No endpoint lists conversations; a conversationId comes from message frames, command settlements and the conversation.created webhook.

Page with cursor: pass each answer's nextCursor back until it is null. A cursor past the last page answers an empty page. A cursor is opaque: never build or parse one.

The response

messages is one page, newest first, and nextCursor is the cursor for the next, older page, or null on the last. Each row is the stream's message frame, with the same ids — messageId is the one to reply to, and lineId the line the message is on: the line an inbound one arrived on, or the one an outbound one went out from — plus three fields. Rows do not carry isVoiceMemo, effect, service, contactId, optedOut or an attachment's isSticker; the stream frame and message.received do.

Prop

Type

On a row, from is the contact's address for an inbound message and your line's address for an outbound one, and empty when no sender address was recorded.

How long history is kept

A live key's history is complete: live messages are kept for ever, where the stream replays 90 days of events. A test key's messages last 30 days, except the newest message in each direction of each conversation, which lasts longer. A test key reads the sandbox's conversations.

Errors

StatusCodeCause
401invalid_credentialsNo key, or one that is unknown, revoked or expired
404not_foundA conversation this key cannot read — another project's, or the other environment's — the same answer a made-up id gets
409project_archivedThe project is archived
422validation_failedA parameter outside the bounds above, or an x-mapier-version this build does not answer to
429rate_limitedOver 120 requests a minute for this key — see Rate limits
500internal_errorAn unhandled failure, reported
503service_busyThe platform had no database connection free in time and did nothing; wait details.retryAfter seconds and ask again
503upstream_unavailableThe service could not answer

On this page