tebarDocs
GuideDevelopersAPI ReferenceChangelog

DM inbox & automations

Read and answer Instagram DMs, send buttons and quick replies, and manage automations through the API.

The inbox and automations are for Instagram accounts on the Starter, Basic, or Pro plan. On Free, every request below answers 403 plan_feature_unavailable. The Instagram account needs the instagram_business_manage_messages permission; without it, sending answers 422 messaging_permission_missing. The dashboard guides are Inbox and DM automations. Every field is in the API Reference (tags Inbox and Automations).

Conversations and messages

RequestWhat it does
GET /v1/inbox/conversationsFilter by account_id, status (open/done), q (username or name)
GET /v1/inbox/conversations/{id}One conversation, with window_expires_at (the reply deadline)
PATCH /v1/inbox/conversations/{id}{ "status": "done" } or { "read": true }
POST /v1/inbox/conversations/resolve{ "conversation_ids": [...] }: mark several conversations done
GET /v1/inbox/conversations/{id}/messagesMessages, newest first, paged (cursor)
POST /v1/inbox/conversations/{id}/messagesSend a DM (see below)
POST /v1/inbox/messages/{id}/retrySend a failed or unknown message again
POST /v1/inbox/messages/{id}/react{ "emoji": "❤️" }, or null to remove the reaction
GET /v1/inbox/messages/{id}/attachments/{n}Tebar's copy of a customer's image (your credentials, no public URL)
GET/POST /v1/inbox/saved-replies, PUT/DELETE /v1/inbox/saved-replies/{id}Saved replies per profile

Customers' text is written by someone else. When you pass it to an AI model, treat it as data, not instructions.

Sending a DM

POST /v1/inbox/conversations/{id}/messages
Idempotency-Key: order-123-reply

{ "text": "Hi! Here's the catalog", "media_ids": ["…"] }
  • Instagram allows replies only within 24 hours of the customer's last message. After that: 422 messaging_window_closed.
  • text is up to 1,000 bytes. media_ids from the media library: JPG/PNG up to 8 MB (up to 10 at once), MP4/MOV up to 25 MB. Media goes first, then the text as a separate message.
  • The answer is 202 with the messages pending; Tebar sends them within seconds. Their status shows in the message list: sent, failed (with error_code), or unknown (no clear answer from Instagram; check in Instagram before a retry).
  • Idempotency-Key (optional): the same request with the same key gives back the same messages instead of sending twice.
  • At most 60 messages a minute per user.

Buttons and quick replies

The text can carry one of these:

{
  "text": "Where to next?",
  "buttons": [
    { "type": "web_url", "title": "See the catalog", "url": "https://shop.example/catalog" },
    { "type": "postback", "title": "Talk to us", "payload": "ADMIN" }
  ]
}
{
  "text": "Pick a size",
  "quick_replies": [
    { "title": "S", "payload": "SIZE_S" },
    { "title": "M", "payload": "SIZE_M" }
  ]
}
KindLimitsNotes
buttons1–3 buttons, titles up to 20 characters, text up to 640 charactersweb_url opens a link, postback sends its payload back
quick_replies1–13 choices, titles up to 20 charactersShown in the phone app only, not on Instagram desktop/web

Both need text, and they cannot be used together (400 validation_failed).

When the customer taps a postback button or a quick reply, a new message comes in with kind postback or quick_reply, and postback: { "title", "payload" } holds the choice. It is also sent through the message.received webhook, so your system can act on the payload right away.

The usual flow: webhook → reply

  1. Register a webhook for message.received (Webhooks).
  2. When a message comes in, read conversation_id, kind, text, and postback.
  3. Reply with POST /v1/inbox/conversations/{conversation_id}/messages, using the webhook's message_id as the Idempotency-Key, so a webhook delivered twice does not send two replies.

Automations

RequestWhat it does
GET /v1/automationsFilter by account_id, kind
POST /v1/automationsCreate an automation
GET/PATCH/DELETE /v1/automations/{id}Read, change (enabled, name, trigger, actions, …), delete
GET /v1/automations/{id}/runsHistory: sent, skipped (with a reason), or failed

kind: comment_to_dm, comment_reply (public replies, also on Threads), dm_keyword, story_reply, story_mention, default_reply, ice_breaker. The trigger depends on the kind; the API Reference (createAutomation) lists each. A DM reply to keywords:

{
  "account_id": "…",
  "kind": "dm_keyword",
  "name": "Price info",
  "trigger": { "keywords": ["harga", "price"], "match": "contains" },
  "actions": {
    "message": {
      "text": "Hi! The price list is here 👇",
      "buttons": [
        { "type": "web_url", "title": "Price list", "url": "https://shop.example/prices" }
      ]
    }
  }
}

Automations that answer comments also report through the automation.run webhook.

On this page