REST APIGET

Inbox messages

Read direct message conversations on Facebook, Instagram, Bluesky and Mastodon, send replies within each platform's rules and mark conversations done.

GEThttps://post.adaptlypost.com/post/api/v1/inbox/conversations

Returns direct message conversations, the one with the latest message first. Answers { conversations, total, hasMore, nextCursor }.

API Key (Bearer token)
Permission:inbox.readRoles and permissions

Every role holds inbox.read, so any valid key can read the inbox.

Query parameters

ParameterTypeDescription
accountIdsstring[]Only these accounts, by the id from GET /social-accounts. Repeat the key or separate values with commas. Up to 50
platformsPlatformType[]Only these platforms. Repeat the key or separate values with commas
statusesInboxStatus[]Only items in these states: UNREAD, READ or DONE. Repeat the key or separate values with commas
sincestring (ISO 8601)Only items created on the platform at or after this date-time
searchstringText to search for
limitnumberItems per page, 1 to 100. Default 25
cursorstringThe nextCursor of the previous page. nextCursor is null on the last page

About 10 minutes, not real time

AdaptlyPost reads each connected account every 10 minutes and keeps what it finds. The lists answer from that copy, so a new comment, mention, message or review shows up within about 10 minutes. POST /api/v1/inbox/refresh asks for a read now. Webhook events come from the same reads.

Channels that need a reconnect

Every channel is open to the API. When a connection lacks the platform permission for a channel or action, including permissions the platform is still reviewing for AdaptlyPost, GET /api/v1/inbox/summary shows the channel as RECONNECT_REQUIRED and every write on it answers 403 inbox_reconnect_required. An expired token answers the same. Ask the user to reconnect the account in AdaptlyPost; retrying does not help.

Conversation fields

FieldDescription
idConversation id. Use it with the endpoints below
accountIdThe account the item belongs to: its id from GET /social-accounts
platformThe platform, as a PlatformType
accountNameDisplay name of that account
participantThe other person: id, name, username and avatarUrl
lastMessageTextText of the latest message
lastMessageAtWhen the latest message was sent
lastMessageIsOwnTrue when your account sent the latest message
statusUNREAD, READ or DONE. A conversation turns UNREAD when the other person writes and nobody has answered since, so a reply sent from the platform's own app keeps it read
repliedAtWhen your account last replied, or null
replyWindowEndsAtFacebook and Instagram: when the 24-hour reply window closes, counted from the last message AdaptlyPost read. null on other platforms
maxMessageLengthThe longest message the platform accepts in this conversation
capabilitiescanReply: false once the reply window has closed or the platform does not let the account send

Read a conversation

GEThttps://post.adaptlypost.com/post/api/v1/inbox/conversations/:id

Returns { conversation, messages }: the conversation and the messages AdaptlyPost has read from it. An unknown id answers 404 inbox_item_not_found. Each message has these fields:

API Key (Bearer token)
Permission:inbox.readRoles and permissions
FieldDescription
idMessage id
isOwnTrue when your account sent it
textThe message text
hasAttachmentsTrue when the message carries images or files. The API returns the text only
createdAtWhen it was sent

Send a message

POSThttps://post.adaptlypost.com/post/api/v1/inbox/conversations/:id/messages

Sends a message from the account in the conversation and answers 201 { conversation, message }.

API Key (Bearer token)
Permission:inbox.replyRoles and permissions

Writes need inbox.reply (Admin and Editor) and an active AdaptlyPost plan. Without the plan they answer 403 subscription_required.

Body parameters

ParameterTypeDescription
textREQUIREDstringThe message, up to maxMessageLength of the conversation

The 24-hour window on Facebook and Instagram

Facebook and Instagram let a business answer only within 24 hours of the person's last message. The send still goes to the platform after replyWindowEndsAt, because the person may have written since the last read; when the platform refuses it, the call answers 400 inbox_messaging_window_closed. Bluesky messages need an app password with direct message access.

Mark as read or done

POSThttps://post.adaptlypost.com/post/api/v1/inbox/conversations/status

Sets the status of up to 100 conversations and answers { conversations, unreadCount }.

API Key (Bearer token)
Permission:inbox.replyRoles and permissions

Body parameters

ParameterTypeDescription
idsREQUIREDstring[]1 to 100 ids from the list
statusREQUIREDInboxStatusUNREAD, READ or DONE

Refusals

A refused call answers { statusCode, error, code, message }. Branch on code. message explains the refusal in words.

CodeStatusWhen, and what to do
inbox_item_not_found404The id does not exist or belongs to another workspace. Stop
inbox_action_unsupported400The platform, or this item, does not allow this hide, delete or like. capabilities says what applies. Stop
inbox_reconnect_required403The connection lacks the permission for this channel or action, including one still in platform review, or its token expired. Ask the user to reconnect the account in AdaptlyPost. Do not retry
inbox_reply_invalid400The text is empty or over the limit. The message names the limit. Fix the text
inbox_messaging_window_closed400Facebook or Instagram: the 24-hour reply window has passed. Stop
inbox_rate_limited429The platform rate limited AdaptlyPost. Retry after a while
inbox_platform_error503The platform failed. Retry later
permission_denied403The key's role lacks inbox.read or inbox.reply. Do not retry
subscription_required403A write without an active AdaptlyPost plan. Do not retry
List unread conversations
curl --request GET \
  --url 'https://post.adaptlypost.com/post/api/v1/inbox/conversations?statuses=UNREAD' \
  --header 'Authorization: Bearer <api-key>'
Read a conversation
curl --request GET \
  --url https://post.adaptlypost.com/post/api/v1/inbox/conversations/cnv_5d0e7a19 \
  --header 'Authorization: Bearer <api-key>'

200
{
  "conversation": { "id": "cnv_5d0e7a19", "...": "..." },
  "messages": [
    {
      "id": "msg_a1f20c33",
      "isOwn": false,
      "text": "Hi, do you ship to Portugal?",
      "hasAttachments": false,
      "createdAt": "2026-11-08T08:55:02.000Z"
    }
  ]
}
Send a message
curl --request POST \
  --url https://post.adaptlypost.com/post/api/v1/inbox/conversations/cnv_5d0e7a19/messages \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Content-Type: application/json' \
  --data '{ "text": "Yes, delivery to Portugal takes 3 to 5 days." }'
Mark a conversation as done
curl --request POST \
  --url https://post.adaptlypost.com/post/api/v1/inbox/conversations/status \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Content-Type: application/json' \
  --data '{ "ids": ["cnv_5d0e7a19"], "status": "DONE" }'
200
{
  "conversations": [
    {
      "id": "cnv_5d0e7a19",
      "accountId": "conn_fb_page_001",
      "platform": "FACEBOOK",
      "accountName": "AdaptlyPost",
      "participant": {
        "id": "7230011122233344",
        "name": "João Silva",
        "username": null,
        "avatarUrl": null
      },
      "lastMessageText": "Hi, do you ship to Portugal?",
      "lastMessageAt": "2026-11-08T08:55:02.000Z",
      "lastMessageIsOwn": false,
      "status": "UNREAD",
      "repliedAt": null,
      "replyWindowEndsAt": "2026-11-09T08:55:02.000Z",
      "maxMessageLength": 2000,
      "capabilities": { "canReply": true }
    }
  ],
  "total": 2,
  "hasMore": false,
  "nextCursor": null
}