Skip to content

Replying

Replies go out through the same account the conversation came in on. You never pick a sender; the conversation decides.

POST /v1/conversations/:id/messages on a dm conversation sends a message to the contact.

Terminal window
curl -X POST https://social.missless.tel/v1/conversations/cnv2b4d6f8h1j3l/messages \
-H "Authorization: Bearer $MISSLESS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "Yes, Friday 15:00 or 16:30 is free. Which one?" }'

Response 201:

{
"id": "msg8r0t2v4x6z3b",
"conversation": "cnv2b4d6f8h1j3l",
"direction": "out",
"kind": "text",
"text": "Yes, Friday 15:00 or 16:30 is free. Which one?",
"media_url": null,
"platform_message_id": "m_XyZ0123456789abc",
"sent_by": "api",
"status": "sent",
"created": "2026-08-25T10:05:40Z"
}

The message is sent to Meta before the response returns. If Meta refuses, the call fails with network_error and details carries the reason; nothing is stored as sent. A message.sent event fires on success.

Add up to 13 tappable choices under a DM. Each has a title the contact sees (20 characters or fewer, Meta truncates longer ones) and a payload that comes back to you.

Terminal window
curl -X POST https://social.missless.tel/v1/conversations/cnv2b4d6f8h1j3l/messages \
-H "Authorization: Bearer $MISSLESS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Which slot works?",
"quick_replies": [
{ "title": "Friday 15:00", "payload": "slot:2026-08-28T15:00" },
{ "title": "Friday 16:30", "payload": "slot:2026-08-28T16:30" }
]
}'

When the contact taps one, an inbound message with kind: "postback" arrives whose text is the payload. Quick replies disappear as soon as the contact sends anything else, so treat them as a suggestion, not a form.

POST /v1/conversations/:id/messages on a comment conversation posts a public reply under the comment. quick_replies is ignored there.

Terminal window
curl -X POST https://social.missless.tel/v1/conversations/cnv3c5e7g9i2k4m/messages \
-H "Authorization: Bearer $MISSLESS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "Thank you! Walk-ins are welcome all Friday." }'

The stored message has kind: "reply". Public replies are visible to everyone who can see the post.

POST /v1/conversations/:id/private-reply on a comment conversation sends one direct message to the person who commented. This is how a comment such as “how much is a cut?” becomes a DM thread.

Terminal window
curl -X POST https://social.missless.tel/v1/conversations/cnv3c5e7g9i2k4m/private-reply \
-H "Authorization: Bearer $MISSLESS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "Hi! A cut is 35 euro. Want me to book you in?" }'

Meta allows exactly one private reply per comment, and only within 7 days of the comment. A second call on the same comment returns network_error. The contact’s answer arrives as a new dm conversation on the same account; it is not threaded under the comment.

Meta’s messaging policy applies to DMs: you can send a message within 24 hours of the contact’s last message. Outside that window Meta refuses and the call returns network_error.

  • The window resets every time the contact writes. Check last_message_at on the conversation, and the direction of the newest message, before offering a reply box.
  • Comment replies have no window. You can answer a comment weeks later.
  • A private reply to a comment opens a DM thread; the 24-hour clock for that thread starts when the contact answers.

Every outbound message records sent_by. Replies sent through this API are api, replies typed in the widget are embed, and an AI assistant over MCP produces mcp. Use it to show “sent by the assistant” badges or to audit who answered.

Replies that staff send from Meta’s own apps do not appear as messages here; MissLess only stores what it sent or received. If a customer answers in both places, the API copy is the one you sent.