How to Set Up Headless Human Handoff (API-Only Agent Inbox)
Headless human handoff lets your own application act as the WhatsApp gateway. You implement the Meta webhook handler and chatbot orchestration (e.g. Voiceflow or Botpress), while using HitlChat purely as the live-agent inbox. You push inbound messages to the HitlChat API; your agents reply in HitlChat; we send those replies (and a “resolved” event) back to your webhook endpoint, and your gateway handles the actual message sending via Meta.
What is headless human handoff?
In a normal HitlChat setup, HitlChat connects to WhatsApp for you and receives the messages. In headless mode, your own system stays in charge of WhatsApp — HitlChat never becomes the webhook receiver for your number and never sends messages on its own. Instead:
- Inbound: your gateway forwards the WhatsApp message to our API, and it appears in the agent inbox.
- Outbound: when an agent replies, HitlChat sends the message to your webhook as a ready-to-send Meta payload — your gateway forwards it to WhatsApp.
- Resolved: when an agent closes the chat, HitlChat fires a
conversation_resolvedevent to your webhook so you can clean up state.
Who it’s for
Use this mode when you already run your own WhatsApp gateway and just want a human agent inbox — for example:
- You receive WhatsApp via the Meta Cloud API into your own webhook (a custom backend, automation tool, etc.).
- Your bot logic (Voiceflow, Botpress, or a custom flow) lives outside HitlChat and you only want HitlChat for the live-agent step.
- You need your gateway to remain the single point that talks to Meta for sending and receiving.
If you’d rather HitlChat manage the WhatsApp connection for you, use one of the standard methods instead — see Connect to WhatsApp.
What you need
- A HitlChat account.
- Your own WhatsApp gateway already receiving Meta webhooks for your number.
- From Meta: your WhatsApp Business Account ID, Phone Number ID, and a permanent (system-user) access token.
- A webhook URL on your gateway that can receive HitlChat’s outbound events.
- Your HitlChat API key for the inbound endpoint — it’s your User ID, shown under My Account → API.
Choose “No chatbot” in the setup wizard
In the left menu, open Configuration. On the Integration Setup step, under Select Integration Type, choose No chatbot — your bot runs in your own gateway, so HitlChat doesn’t need one. Click Next.
Pick “External / API — Headless Human Handoff”
On the WhatsApp Connection Options step, choose External / API — Headless Human Handoff. This is the “bring your own transport” option: HitlChat acts as the agent inbox only, while your gateway stays the WhatsApp webhook receiver and sender. Click Next.
Enter your details & save
Fill in the four fields and click Save:
- WhatsApp Business Account ID — from Meta; we use it to match the inbound payloads you forward.
- Phone Number ID — from Meta; included in the outbound payloads we send you.
- Meta Access Token — a permanent / system-user token. HitlChat uses it only to download inbound media (images, video, audio, documents) so you can forward Meta payloads verbatim. It is never used to send messages.
- Webhook URL — your gateway endpoint. We send agent replies and resolved events here.
On save, HitlChat validates your Meta credentials (token, Phone Number ID and WABA) and checks that your webhook URL is reachable — if anything is wrong, the save is rejected with a clear message.
The External / API configuration step.
How the two-way flow works
- A customer messages your number → Meta → your gateway (unchanged).
- Your gateway POSTs the message to HitlChat’s inbound API → it appears in the agent inbox.
- An agent replies → HitlChat sends the reply to your webhook as a ready-to-send Meta payload.
- Your gateway forwards it to Meta → the customer receives it.
- The agent resolves the chat → HitlChat fires
conversation_resolvedto your webhook.
The next section shows the exact API calls and payloads for each step.
Authentication & base URL
The inbound API is authenticated with your API key as a Bearer token. Your key is your User ID, shown inside HitlChat under My Account → API.
Step 4 · Forward inbound messages
From your gateway, POST the verbatim Meta webhook payload to the inbound endpoint — no reshaping. The first message for a contact opens a conversation (and creates the contact); later messages append to it.
# Forward a text message exactly as Meta sent it
curl -X POST https://api-portal.hitlchat.io/api/v1/public/inbound \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"object": "whatsapp_business_account",
"entry": [{
"id": "YOUR_WHATSAPP_BUSINESS_ID",
"changes": [{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": { "phone_number_id": "YOUR_PHONE_NUMBER_ID" },
"contacts": [{ "profile": { "name": "John" }, "wa_id": "447700900123" }],
"messages": [{
"from": "447700900123", "id": "wamid.ABC", "timestamp": "1733670000",
"type": "text", "text": { "body": "I need to speak to a human" }
}]
}
}]
}]
}'
entry[0].id (WhatsApp Business ID) and phone_number_id must match what you configured — that’s how we route the message to your account.Inbound media (images, video, files)
Forward media verbatim too — including the Meta media id, exactly as Meta sends it. HitlChat downloads the file from Meta using the access token you saved and renders it in the inbox. No transformation needed on your side.
# The messages[] entry for an inbound image (rest of the envelope is identical)
"messages": [{
"from": "447700900123", "id": "wamid.IMG", "timestamp": "1733670200",
"type": "image",
"image": { "mime_type": "image/jpeg", "id": "META_MEDIA_ID", "caption": "Receipt" }
}]
video, audio and document — use the matching type and object.Optional: prior chat history (handoff context)
On the message that opens a conversation, you can attach a top-level prior_history array so the agent sees the earlier bot conversation. It’s text-only — for a past media turn, describe it in text.
# Add this sibling key alongside "object" / "entry"
"prior_history": [
{ "direction": "inbound", "text": "What are your hours?", "timestamp": "2026-06-08T09:14:00Z" },
{ "direction": "outbound", "text": "9am-5pm, Mon-Fri.", "timestamp": "2026-06-08T09:14:05Z" }
]
Step 5 · Receive agent replies on your webhook
When an agent replies in the inbox, HitlChat POSTs an outbound_message event to your Webhook URL. It carries meta_payload — the exact body to POST to Meta. Your gateway just forwards it with your own token.
# What HitlChat sends to your webhook
{
"event": "outbound_message",
"contact_number": "447700900123",
"phone_number_id": "YOUR_PHONE_NUMBER_ID",
"meta_payload": {
"messaging_product": "whatsapp", "to": "447700900123",
"type": "text", "text": { "body": "Hi John, happy to help!" }
}
}
"image": { "link": "…" } — a public link Meta fetches, so your gateway needs no extra upload call.Step 6 · Handle the resolved event
When an agent marks the chat Resolved by Human, HitlChat fires a conversation_resolved event to the same webhook so you can clear your session state.
{
"event": "conversation_resolved",
"contact_number": "447700900123",
"resolved_status": "Resolved by Human",
"resolved_datetime": "2026-06-09T10:05:00Z"
}
Every endpoint, field and response
The full interactive reference — auto-generated from the live API — documents every parameter and lets you try calls in the browser.
Headless Human Handoff FAQs
What is headless human handoff?
It’s a HitlChat connection mode where your own gateway stays the WhatsApp webhook receiver and sender, and HitlChat is used purely as the live-agent inbox. You push inbound messages to our API, and we emit agent replies and a resolved event back to your webhook.
When should I use External / API mode instead of connecting WhatsApp directly?
Use it when you already run your own WhatsApp pipeline (for example a flow that receives the Meta webhook and runs your bot) and only want HitlChat for the human-agent step. If you’d rather HitlChat manage the WhatsApp connection, pick Facebook Login, Manual Configuration, or QR Code instead.
Do I forward Meta payloads verbatim?
Yes. Forward the exact Meta webhook payload to POST /v1/public/inbound — text and media alike, with no reshaping. The only optional addition is a top-level prior_history array on the message that opens a conversation.
Why does HitlChat need my Meta access token if my gateway sends the messages?
Only to download inbound media. A Meta inbound media message references the file by a media id that can only be fetched with the access token. Storing it lets you forward media payloads verbatim — HitlChat downloads the file and shows it in the inbox. The token is never used to send messages; your gateway still sends.
How do agent replies get back to WhatsApp?
When an agent replies, HitlChat POSTs an outbound_message event to your webhook URL containing meta_payload — the exact body to send to Meta. Your gateway forwards that to the Meta API with your own credentials.
What is the conversation_resolved webhook?
When an agent marks a chat “Resolved by Human”, HitlChat fires a conversation_resolved event to your webhook so you can clean up your own session state.
How do images and other media work?
Inbound: forward the verbatim payload (media id) — we download it from Meta with your token and render it. Outbound: we send the image as a public link in meta_payload, so Meta fetches it and your gateway needs no extra upload step.
What’s my API key for the inbound endpoint?
It’s your User ID, shown inside HitlChat under My Account → API. Send it as Authorization: Bearer YOUR_API_KEY. Keep it secret — it grants access to your account’s data.
Can I test it without my own gateway?
Yes. Use POST /v1/public/inbound/test-resolved-webhook to fire a sample resolved event to your webhook, and point your Webhook URL at a tool like webhook.site to inspect the outbound payloads. You can also POST sample inbound payloads with cURL or Postman.
Related guides
How to Use the HitlChat API
Authenticate with your API key, then manage contacts, list conversations, and send messages and broadcasts — with code examples.
Read guide →How to Use the HitlChat Inbox
Work the shared agent inbox — reply to customers, transfer chats, and resolve conversations.
Read guide →Stories from real businesses
Daniel Ortega
eCommerce Ops Manager
"WhatsApp is where most of our online customer conversations happen. Our Voiceflow assistant handles the basic questions really well, but when questions get more complicated hitlchat allows our team to jump in instantly without having to move the customer to another channel. It feels like true live chat inside WhatsApp and we’ve seen higher conversions because of it"
Sanjay Mehta
Conversational AI Agency
"The hitlchat setup is super simple, and its easy to use! Most of our clients run small teams handling WhatsApp conversations powered by a Voiceflow bot. hitlchat gives them one shared workspace to manage all their conversations. Being able to step into bot conversations directly inside WhatsApp has transformed their support workflows."
Lucas Bennett
Voiceflow Developer
"We've been building Voiceflow WhatsApp assistants for our clients across various industries (healthcare, ecommerce, restaurants etc) for a few years now. We had been looking for a way to route conversations from the Voiceflow assistant to live human agent for some time. Eventually we found out about hitlchat and honestly its been a gamechanger for us ever since. Our clients love it, and as a result we love it!"
Ready to try hitlchat ?
Create Your Free Account Now
No credit card required