postmatic

Direct Messages

List conversations for an account, read a conversation, and reply within Meta's 24-hour window.

Reading and replying to Instagram direct messages, live from Meta. Nothing is stored by Postmatic.

Permission

The account must have been connected with instagram_business_manage_messages. Without it, routes respond with 403 PERMISSION_REQUIRED: reconnect the account via Accounts.

Conversations

GET /v1/messages?accountId=…
curl "https://api.uat.postmatic.dev/v1/messages?accountId=int_…&limit=20" -H "x-access-key: pm_live_…"
json
{
  "success": true, "accountId": "int_…", "selfId": "1784…", "selfUsername": "acme.brand",
  "conversations": [{
    "id": "aWdfZ…", "updatedTime": "2026-09-09T12:00:00+0000",
    "participants": [{ "id": "1784…", "username": "acme.brand", "name": "Acme", "profilePictureUrl": null }, { "id": "1234…", "username": "ana", "name": "Ana", "profilePictureUrl": "https://…" }],
    "lastMessage": { "id": "aWdf…", "text": "hi, do you have it in blue?", "from": { "id": "1234…", "username": "ana" }, "timestamp": "2026-09-09T12:00:00+0000" }
  }],
  "nextCursor": "QVFIU…"
}

The recipientId to reply to is the participant whose id differs from selfId.

Reading a conversation

GET /v1/messages/:conversationId?accountId=…&limit=25&cursor=… returns messages (most recent first) and nextCursor.

Replying

POST /v1/messages
curl -X POST https://api.uat.postmatic.dev/v1/messages \
  -H "x-access-key: pm_live_…" -H "content-type: application/json" \
  -d '{ "accountId": "int_…", "recipientId": "1234…", "text": "Yes! Should I set one aside for you?" }'

Responds with 201 and messageId. Text must be 1 to 1000 characters.

The 24-hour window

Meta only allows replies up to 24 hours after the recipient's last message. Postmatic checks this before sending: outside the window, or with no prior message from that recipient, the response is 409 MESSAGE_WINDOW_CLOSED with details.recipientId and details.lastInboundAt (or null). There is no way to initiate a conversation via the API.