Messages

Instagram direct messages and Facebook Page messages, normalized into one shape. Adeli refreshes history from the provider before returning it, so a read is live rather than a cache.

Meta providers only

TikTok messaging is not supported, and YouTube has no messaging API at all — its direct messages were retired in 2019. WhatsApp sends approved templates rather than free text through the API — see WhatsApp below.

Both providers reply inside a 24-hour window

Meta only permits a reply within 24 hours of the person's last message, on Instagram and on Facebook alike. When Meta refuses a send because the window has closed, Adeli returns 409 window_closed; you cannot open one by sending first.

GET/api/v1/messagesList messages

Returns a flat array across the profile's Instagram, Facebook, and WhatsApp conversations, oldest first by occurredAt. Uses the aggregate response contract.

Query parameters

platform"instagram" | "facebook" | "whatsapp"
Return one provider's messages only. facebook covers every connected Facebook Page's Messenger conversations. Anything else, including tiktok and youtube, returns 422 unsupported_platform.
accountIduuid
Narrow to one connected account.
profileIduuid
Defaults to your key's profile.
json
{
  "status": "complete",
  "messages": [
    {
      "id": "instagram_message_aWdfbWlk",
      "providerId": "aWdfbWlk",
      "platform": "instagram",
      "accountId": "00000000-0000-0000-0000-000000000000",
      "profileId": "00000000-0000-4000-8000-000000000001",
      "direction": "inbound",
      "type": "text",
      "recipient": null,
      "sender": "17841400000000001",
      "body": "Do you ship to Canada?",
      "status": "received",
      "occurredAt": "2026-04-01T12:00:00.000Z",
      "createdAt": "2026-04-01T12:00:01.000Z"
    }
  ],
  "errors": []
}

Message fields

idstring
Adeli's identifier for this message.
providerIdstring | null
The provider's message id.
direction"inbound" | "outbound"
Relative to the connected account.
type"text" | "template" | "unsupported"
unsupported covers media and other payloads Adeli does not normalize.
senderstring | null
Set on inbound messages — the provider-scoped participant id (an IGSID on Instagram, a PSID on Facebook).
recipientstring | null
Set on outbound messages.
statusstring
Provider delivery state, such as received or sent.
occurredAtISO 8601
When the provider recorded the message. Sort on this.

If a provider sync fails, Adeli still returns the messages it has already persisted and reports the failure in errors, which makes the response 207.

Errors — 401 unauthorized, 400 invalid_request, 422 unsupported_platform, 404 profile_not_found, 404 account_not_found, 502 provider_error.

POST/api/v1/messagesSend a message

Body

platform"instagram" | "facebook"Required
accountIduuidRequired
A connected Instagram account or Facebook Page in your key's profile.
profileIduuid
Defaults to your key's profile.
recipientstringRequired
The provider-scoped participant id, 1–200 characters. Take it from the sender field of an inbound message, not from a username.
textstringRequired
1–1,000 characters.
curl --fail-with-body -X POST "$ADELI_URL/api/v1/messages" \
-H "Authorization: Bearer $ADELI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "platform": "instagram",
  "accountId": "'"$ACCOUNT_ID"'",
  "recipient": "'"$RECIPIENT_ID"'",
  "text": "Yes, we ship to Canada."
}'

A Facebook reply has the same shape. accountId is the connected Page, and recipient is the person's PSID, from the sender field of their inbound message:

bash
curl --fail-with-body -X POST "$ADELI_URL/api/v1/messages" \
  -H "Authorization: Bearer $ADELI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "facebook",
    "accountId": "'"$PAGE_ACCOUNT_ID"'",
    "recipient": "'"$PSID"'",
    "text": "Yes, we deliver on Saturdays."
  }'

Success returns 201 and a bare message object with direction: "outbound", type: "text", and status: "sent".

Meta's messaging rules still apply

A business can message a person only inside the window Meta's policy opens, which begins when that person messages the business. When Meta refuses a send because that window has closed, the response is 409 window_closed. Wait for the person to message again before retrying.

Errors — 401 unauthorized, 400 invalid_request, 404 profile_not_found, 404 account_not_found, 409 window_closed, 409 page_not_selected (Facebook), 403 missing_permission (Facebook), 422 connection_expired, 422 provider_not_configured, 422 provider_not_supported, 502 provider_error.

WhatsApp

Each profile can hold one WhatsApp number that the business connected itself, through Embedded Signup on the dashboard's Accounts page. It appears in GET /api/v1/accounts with platform: "whatsapp", the phone number ID as providerId, and the display number as displayIdentifier, and its history is included in GET /api/v1/messages. WhatsApp history is what Adeli has received by webhook and sent, so a read makes no provider call.

Through the API, WhatsApp sends one of the business's approved templates — the only message WhatsApp allows when starting a conversation or more than 24 hours after the customer last wrote.

WhatsApp body

platform"whatsapp"Required
accountIduuidRequired
The WhatsApp account in your key's profile.
profileIduuid
Defaults to your key's profile.
recipientstringRequired
An E.164 phone number, such as +15551234567.
template.namestringRequired
An approved template on the business's WhatsApp Business Account: lowercase letters, digits, and underscores.
template.languagestringRequired
The template's language, such as en_US.
template.bodyParametersstring[]
Values for the body's {{1}}, {{2}}, … placeholders, in order. Up to 20; omit for a template without placeholders.
json
{
  "platform": "whatsapp",
  "accountId": "00000000-0000-0000-0000-000000000000",
  "recipient": "+15551234567",
  "template": { "name": "order_update", "language": "en_US", "bodyParameters": ["Jane", "A-42"] }
}

Success returns 201 with type: "template". A number whose setup has not finished returns 422 setup_incomplete; one whose access the business revoked returns 422 reconnect_required. An unknown or unapproved template fails at Meta and surfaces as 502 provider_error.

WhatsApp numbers cannot be connected through POST /api/v1/profiles/{profileId}/connect yet — that returns 422 provider_not_supported.