Skip to main content

Messaging

Read Messenger and Instagram DM threads and reply as the Page or account.

Read your Facebook Messenger and Instagram Direct inbox threads and reply into them. Reading needs whatsapp:read; sending needs whatsapp:send. Messaging on both channels is not metered.

No account id goes in the path anywhere on this page. Reading is scoped to your whole workspace, and a send names its account in the body — with a value you already hold, because it comes off the thread you are replying to.

One rule shapes this whole surface: a conversation must be started by the customer. You can never message someone who has not messaged your Page or account first — there is no thread to reply into, and the send is refused with a 409.

The messaging window

Meta only lets a business reply for a limited time after the customer's last message. CallMissed enforces this before any upstream call, measured from the thread's last inbound message:

Time since last inboundWhat happens
Within 24 hoursThe reply sends normally.
24 hours – 7 daysThe reply sends as a human-agent tagged message. This uses Meta's Human Agent feature, which needs its own App Review approval — until that's granted, Meta may still reject the tagged send (surfaced as 503).
Over 7 daysThe reply is refused locally with 400. The customer must message again to reopen the window.

List inbox threads

Facebook — GET /api/v1/facebook/conversations Instagram — GET /api/v1/instagram/conversations

The most recent 200 threads, newest first. There is no pagination and no cursor — this is a live inbox view, not an archive export. Message bodies are not included; fetch them per thread from the messages endpoint.

Threads are returned for every connected account on the channel, so a workspace with two Pages sees both inboxes in one call. account_ref tells you which account each thread belongs to, and it is the value you send back when you reply.

[
  {
    "id": "7f3c1e64-2b8a-4d19-9c02-5a1b6e4f8d20",
    "channel": "facebook",
    "account_ref": "102938475610293",
    "contact_id": "6284719203847561",
    "contact_name": "Priya Sharma",
    "last_inbound_at": "2026-08-24T09:14:02.481930+00:00",
    "last_message_at": "2026-08-24T09:15:37.902144+00:00"
  }
]

contact_id is the recipient id you send to (a Page-scoped id on Facebook, an Instagram-scoped id on Instagram). contact_name can be null.

List messages in a thread

Facebook — GET /api/v1/facebook/conversations/{conversation_id}/messages Instagram — GET /api/v1/instagram/conversations/{conversation_id}/messages

The messages in one thread, oldest first (up to 500). conversation_id is the id from the thread list.

[
  {
    "id": "3a5e77c1-9b40-4f8e-a2d6-11c8ee4b7f39",
    "channel": "facebook",
    "direction": "inbound",
    "external_id": "m_AbCdEf1234567890",
    "message_type": "text",
    "text": "Hi, is the store open tomorrow?",
    "status": null,
    "created_at": "2026-08-24T09:14:02.481930+00:00"
  },
  {
    "id": "9c02b418-77de-4a55-b6f1-2d9e0a3c8b7e",
    "channel": "facebook",
    "direction": "outbound",
    "external_id": "m_ZyXwVu0987654321",
    "message_type": "text",
    "text": "Yes, we are open 10am to 8pm tomorrow.",
    "status": "sent",
    "created_at": "2026-08-24T09:15:37.902144+00:00"
  }
]

An unknown conversation_id, or one from another workspace, returns an empty array ([]), not a 404 — so [] can mean "no such thread" as well as "no messages yet". status is null on inbound messages. message_type is text, an attachment type, reaction (Instagram), or postback (a button tap).

Send a message

Facebook — POST /api/v1/facebook/messages Instagram — POST /api/v1/instagram/messages

A text reply into an existing thread. All three fields are required, and all three come straight off the thread you are replying to — there is no ?account= hint here because the body already carries the account.

Facebook

FieldTypeDescription
page_idstringThe connected Page's Meta id — the thread's account_ref.
recipient_idstringThe recipient's id — the thread's contact_id.
textstringThe message text.

Instagram

FieldTypeDescription
ig_user_idstringThe connected Instagram account's Meta id — the thread's account_ref.
recipient_idstringThe recipient's id — the thread's contact_id.
textstringThe message text.

An account_ref that is not connected to your workspace returns 404, so a send is authorized against your own accounts rather than trusted from the request.

curl -X POST https://api.callmissed.com/api/v1/instagram/messages \
  -H "Authorization: Bearer cm_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "ig_user_id": "17841400000000000", "recipient_id": "1234567890123456", "text": "Yes, we deliver across Pune in 2 days." }'

On Instagram a long message is split on word boundaries into multiple sends (the per-message limit is 1,000 bytes of UTF-8), and the response reports how many went out. Only the parts Meta actually accepted are recorded, so a partial send is visible rather than reported as whole:

{ "status": "sent", "sent": 2, "message_ids": ["aWdfZG1fMTo...QUFB", "aWdfZG1fMTo...QkJC"] }

Facebook returns a single message_id (which can be null if Meta omitted it):

{ "status": "sent", "message_id": "m_ZyXwVu0987654321" }

Text only — there is no attachment, template or quick-reply parameter on these endpoints. A send fails with 409 when no thread exists for the recipient (the window was never opened), 400 when the window has closed, 404 when the account is not one of yours, and 503 when the upstream send fails.

Messaging analytics

Facebook — GET /api/v1/facebook/analytics/funnel · GET /api/v1/facebook/analytics/timeseries Instagram — GET /api/v1/instagram/analytics/funnel · GET /api/v1/instagram/analytics/timeseries

Message volume and delivery for one channel across your whole workspace. Needs whatsapp:read.

QueryTypeDescription
daysintegerLook-back window, 1–90. Default 7 for the funnel, 14 for the time series.

Funnel — counts are cumulative: a read message also counts as delivered and sent.

{
  "channel": "instagram",
  "days": 7,
  "inbound": 412,
  "outbound": 398,
  "sent": 391,
  "delivered": 380,
  "read": 301,
  "failed": 7,
  "delivery_rate": 0.955,
  "read_rate": 0.792
}
FieldDescription
inboundMessages customers sent you
outboundMessages you sent (agent replies and API sends)
sent / delivered / readOutbound messages that reached at least that stage
failedOutbound messages Meta rejected
delivery_ratedelivered / outbound, 0–1
read_rateread / delivered, 0–1 (both rates rounded to 3 decimals)

Time series — one point per UTC day and direction; days with no messages are omitted.

{
  "channel": "facebook",
  "days": 14,
  "points": [
    { "date": "2026-08-23", "direction": "inbound", "count": 58 },
    { "date": "2026-08-23", "direction": "outbound", "count": 61 }
  ]
}