Reading data

Everything here is a read, and needs the key's read permission.

GET
List accounts

/accounts  ·  needs read

Every account you've connected, on every channel. status is connected, needs_attention or disconnected whatever the channel calls it. GET /accounts/{id} returns one.

{
  "accounts": [
    {
      "id": "01a115a8-…",
      "channel": "whatsapp",
      "name": "Test WhatsApp",
      "identifier": "+15559990000",
      "status": "connected",
      "canSend": true,
      "capabilities": {
        "contacts": true,
        "startConversation": true,
        "requiresSubject": false,
        "asyncSend": false,
        "maxMessagesPerRead": 100,
        "maxTextLength": 10000,
        "createAndAuthenticate": false,
        "embed": false,
        "attachments": false,
        "maxAttachmentBytes": 0,
        "adoptExisting": false,
        "searchMessages": false,
        "updateCredentials": false,
        "topics": false,
        "resolveConversation": false,
        "webhooks": true
      },
      "createdAt": "2026-10-07T09:19:08+00:00"
    }
  ]
}

GET
List conversations

/accounts/{id}/conversations?limit=50  ·  needs read

Most recent activity first, up to limit (1–100). There's no paging for conversations. On WhatsApp one person is always one conversation, even if they have two identities.

{
  "conversations": [
    {
      "id": "15551230001@c.us",
      "name": "Ada Lovelace",
      "isGroup": false,
      "lastMessage": { "text": "message number 30", "at": "2026-10-07T09:18:53+00:00", "fromMe": false },
      "unreadCount": 2
    }
  ]
}

GET
Resolve a recipient

/accounts/{id}/resolve?to=  ·  needs read

Telegram only. Turns what a person would type to address someone — @ada, ada, https://t.me/ada, or a phone number with a leading + — into the conversation id the conversation and message routes use for them, so you can open a chat knowing only a username. It sends nothing, spends no credit and creates no chat. A bare numeric chat id is returned as it is. to can be up to 64 characters.

curl "https://messengeragent.dev/api/v1/accounts/ACCOUNT_ID/resolve?to=@ada" -H "Authorization: Bearer $API_KEY"
#   → { "conversationId": "777000123", "name": "Ada Lovelace", "username": "ada" }

# Then read the chat with the id you were given.
curl "https://messengeragent.dev/api/v1/accounts/ACCOUNT_ID/conversations/777000123/messages" -H "Authorization: Bearer $API_KEY"
  • 404 not_found — "No such Telegram user." Nothing is remembered about a miss, so asking again later works.
  • 400 invalid_request — to is missing, blank or too long. 422 unsupported_operation — the account's channel cannot do this; check capabilities.resolveConversation.
  • 429 rate_limited — Telegram asked for a pause; wait Retry-After seconds. Lookups have a lower limit than other reads (20 a minute per key) because each one reaches Telegram; a person found is remembered for about ten minutes.

GET
List a forum's topics

/accounts/{id}/conversations/{conversationId}/topics  ·  needs read

Telegram only. A forum is a supergroup split into topics: the conversation has isForum: true and no messages of its own, and each topic does. A topic's id is a conversation id like any other, so read it and send into it with the ordinary conversation routes. Pinned topics first, then newest activity first. A conversation that isn't a forum is a 422 unsupported_operation; an account's capabilities.topics says whether its channel has topics at all.

curl "https://messengeragent.dev/api/v1/accounts/ACCOUNT_ID/conversations?limit=50" -H "Authorization: Bearer $API_KEY"
#   → { "conversations": [ { "id": "-1001919633522", "name": "Flow Dev", "isGroup": true, "isForum": true, … } ] }

curl "https://messengeragent.dev/api/v1/accounts/ACCOUNT_ID/conversations/-1001919633522/topics" -H "Authorization: Bearer $API_KEY"
#   → { "topics": [ { "id": "-1001919633522_1", "name": "General", "isGeneral": true, "isPinned": false, "isClosed": false, "unreadCount": 3, "lastMessage": { … } },
#                   { "id": "-1001919633522_5968", "name": "News", … } ] }

# A topic's id is a conversation id: read it, and send into it, like any other.
curl "https://messengeragent.dev/api/v1/accounts/ACCOUNT_ID/conversations/-1001919633522_5968/messages" -H "Authorization: Bearer $API_KEY"

GET
List messages

/accounts/{id}/conversations/{conversationId}/messages?limit=30&before=  ·  needs read

Newest first. type is one of text, image, video, audio, document, sticker, contact, poll, location, other. status is the channel's own delivery state in lower case (sent, delivered, read, failed; on LinkedIn also queued, sending). Attachments are listed, not downloaded, in v1.

{
  "messages": [
    {
      "id": "M30",
      "conversationId": "15551230001@c.us",
      "direction": "inbound",
      "fromMe": false,
      "type": "text",
      "text": "message number 30",
      "subject": null,
      "sender": { "name": "Ada Lovelace" },
      "status": "delivered",
      "at": "2026-10-07T09:18:53+00:00",
      "attachments": []
    }
  ],
  "hasMore": true,
  "nextBefore": "M21"
}

GET
List contacts

/accounts/{id}/contacts?search=&limit=50&offset=0  ·  needs read

WhatsApp and LinkedIn. conversationId opens the conversation with that person.

{
  "total": 124,
  "offset": 0,
  "limit": 50,
  "contacts": [
    { "id": "01a1…", "name": "Ada Lovelace", "identifier": "+15551230001", "conversationId": "15551230001@c.us", "updatedAt": "2026-10-01T10:00:00+00:00" }
  ]
}

Pagination

Messages page backwards by message, not by time: pass nextBefore from one page as before on the next. Because a cursor is a message id, messages sent in the same second are never skipped at a page boundary. When hasMore is false you've reached the oldest message that's reachable. A before that's no longer reachable is a 422, not a silent restart. Contacts page with limit and offset.

# First page, newest first
curl "https://messengeragent.dev/api/v1/accounts/ACCOUNT_ID/conversations/CONVERSATION_ID/messages?limit=10" ...
#   → "hasMore": true, "nextBefore": "M21"

# Older: pass nextBefore as "before"
curl "https://messengeragent.dev/api/v1/accounts/ACCOUNT_ID/conversations/CONVERSATION_ID/messages?limit=10&before=M21" ...