Send an operator reply
Adds a reply written by a person to an existing conversation. This is the human takeover path. The AI agent is not invoked for this reply and does not answer on top of it. On WhatsApp, email and webchat the agent still answers the contact’s next inbound message as usual. On Instagram and Messenger the agent steps back after a human reply (see below).
Delivery depends on the thread’s channel.
- WhatsApp: delivered before anything is stored. If WhatsApp refuses
(24-hour window, opt-out, compliance, cap), nothing is written and the refusal is returned.
Pass
templateIdinstead ofmessagewhen the contact is outside the 24-hour window. - Email: sent from the workspace’s connected mailbox, then stored. The subject is taken
from the thread (latest recorded subject, prefixed
Re:once), falling back toRe: su conversación. - Webchat: stored and pushed to the visitor’s open widget in real time. A visitor without an open widget sees it the next time the history loads.
- Instagram / Messenger: delivered through the Facebook Page the person wrote to,
before anything is stored. Within 24 hours of the person’s last message it is sent as a
normal response. After 24 hours and within 7 days it is sent as a human-agent message, which
Meta only accepts once the Human Agent feature is approved for the app. After 7 days, or when
the person has never written, it is refused with 422. A long reply is split into several
messages (Instagram accepts 1,000 bytes per message, Messenger 2,000 characters). Every
refusal (window closed, person blocked the Page, Instagram message access switched off,
another app controls the thread, contact opted out, daily cap) returns 4xx with the reason
in
error.message, and nothing is written.
Human takeover on Instagram and Messenger. After a human reply on these two channels the
agent stops answering that thread for 24 hours from the last human message. The same happens
when someone answers from the Page inbox in Meta Business Suite. While it lasts, the contact’s
messages are still stored (with metadata.held_for_human = true), the conversation is flagged
as waiting for a person, and metadata.human_takeover on the conversation holds
{ until, source, at }. POST /api/conversations/{conversationId}/needs-human/resolve hands
the thread back to the agent.
The stored message has role: agent and metadata.manual = true (plus
provider_message_id and template_id when applicable). Template replies are recorded as
[template] <templateId>.
Side effects. Sends a real WhatsApp message or email to the customer. Provider-backed sends consume one unit of the channel’s daily cap. Replies written by people never draw on the AI-message allowance. Broadcasts realtime updates to the dashboard and the visitor’s widget, clears the conversation caches, and writes an audit entry.
Idempotency. Not idempotent. A retry after a timeout sends and stores the reply twice.
Re-read the thread with GET /api/conversations/{conversationId} before retrying.
Webhook events. audit.log_recorded for subscribers that selected it explicitly. See Webhooks.
Access
- Required scope:
write. - Rate limit: General API — 120 requests/min per workspace (Starter), 200 (Growth), 300 (Business), 600 (Enterprise). See Rate limits.
- Plan: Available on every plan.
Authentication
Workspace API key: jl_ followed by 64 lowercase hex characters, created by the workspace owner in the
dashboard (Settings → API Keys) and sent as Authorization: Bearer jl_.... The plaintext is shown once,
at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys.
Operations restricted to admins or owners reject keys without the full scope with 403, and say so in
their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret —
that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds.
See Authentication.
Path parameters
Request
At least one of message or templateId is required. When both are sent on WhatsApp, the template is sent.
Reply text, trimmed and sent as written. Required unless templateId is sent. Email threads always need message.
WhatsApp conversations only. Id of an approved template of the workspace, for
contacts outside the 24-hour window. On any other channel the call returns 400
templateId is only supported on WhatsApp conversations.
Values for the template placeholders, as an ordered list ({{1}} first) or an object keyed by placeholder number. Ignored without templateId.
Response
Reply delivered (for WhatsApp and email) and stored.

