Read message history

​

Returns message history for a channel. One endpoint serves two paging styles:

  • Scroll-up paging — ?before={seq}&limit={n}. Returns messages older than before, ascending (oldest first), up to limit (default 50, max 100). Omit before to start from the newest.
  • Gap-fill range — ?from={seq}&to={seq}. Returns messages in the inclusive [from, to] sequence range, ascending.

The same endpoint serves both callers: use the control plane with a secret key for server-side history reads, or the realtime edge with a user JWT for client reads. The response is { msgs, hasMore }. Retracted messages come back as tombstoned envelopes (retracted: true, content: null). Browser CORS is enabled on the realtime edge, scoped to the environment's allowed origins.

Path Parameters

  • The channel id. Channels are not created explicitly — they exist by being used.

Query Parameters

  • Return messages with seq less than this value (scroll-up paging).

  • Inclusive lower bound of a gap-fill range (use with to).

  • Inclusive upper bound of a gap-fill range (use with from).

  • Scope the read to ONE thread: the id of the message that started it. Returns only that thread's replies, paged by threadSeq — inside a thread, before is a thread position, not a channel seq.

    Unscoped history still contains thread replies (every message is stored in the channel); this narrows the read for clients that want a thread on its own.

    Honored by both servers: the realtime edge pages the coordinator's hot tier and falls through to the Postgres archive; the control plane reads the archive directly. Messages archived before the thread columns existed are untagged and not returned by a thread-scoped read. See amendments A17 and A19.

  • Page size for scroll-up paging (default 50, max 100).

Responses

  • application/json
  • application/json
  • application/json
Request Example for get/v1/channels/{channelId}/history
curl 'https://api.useportal.co/v1/channels/chat-general/history?before=100&from=80&to=120&threadParentId=m_1752912000_42&limit=50' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
One message, more available
{
  "msgs": [
    {
      "id": "m_1752912000_41",
      "seq": 41,
      "type": "message",
      "kind": "text",
      "content": {
        "text": "hi"
      },
      "sender": {
        "id": "u_123",
        "anon": false
      },
      "timestamp": 1752911999000,
      "retracted": false,
      "ephemeral": false
    }
  ],
  "hasMore": true
}