Send messages: Agent Inbox
Use the Aircall Public API to send WhatsApp text and template messages from a WhatsApp-capable line into an agent conversation in Aircall Workspace
Overview
This mode sends a WhatsApp message — text or an approved template — from a WhatsApp-capable line and adds it to the agent's conversation in Aircall Workspace. If no conversation with the recipient exists yet, one is created. Any agent on the line can then see the message and continue the thread, and the customer's replies flow back into the same conversation.
Use agent conversation mode when a human agent needs visibility into the WhatsApp conversation. For automated, high-volume, or non-conversational sending — use skipping-inbox mode instead.
Prerequisites
- A registered WhatsApp-capable line — See the WhatsApp overview for registration.
- A valid OAuth access token — See OAuth page to learn how to get one.
Send a template message
Templates are pre-approved message formats. Use one to start a conversation or to reach a customer outside the 24-hour window. First list the line's approved templates, then send by id.
Get the templates
List the line's approved templates to find the one you need.
const LINE_ID = 123; //Your Aircall number with active Whatsapp Addon
const listApprovedTemplates = async () => {
const res = await fetch(
`https://api.aircall.io/v1/numbers/${LINE_ID}/templates?status=APPROVED`,
{ headers: { 'Authorization': `Bearer ${process.env.AIRCALL_ACCESS_TOKEN}` } }
);
if (!res.ok) throw new Error(`Failed to list templates: ${res.status}`);
const { templates } = await res.json();
// Each template: { id, name, category, status, language, ... }
return templates;
};Send the template message
Send the template by passing templateParams instead of text. The body array fills the template's variables, matching each placeholder key to a value.
const sendTemplate = async () => {
const res = await fetch('https://api.aircall.io/v1/messages/send/whatsapp/native', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.AIRCALL_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
lineId: 123,
externalNumber: '+14155552671',
templateParams: {
id: '1234',
body: [
{ key: '{{1}}', value: 'Jordan' },
{ key: '{{2}}', value: '2026-06-18' }
]
}
})
});
if (!res.ok) throw new Error(`Send failed: ${res.status}`);
return res.json();
};Each key in body must match a variable configured for that template in Aircall. You define those variables under the number's Integration page, in the WhatsApp in Aircall section; they correspond to the template's placeholders (
{{1}},{{2}}, ...). Set each key to the same variable so its value lands in the right placeholder.
Send a text message
Free-form text is allowed while the 24-hour customer service window is open — that is, within 24 hours of the customer's last inbound message. The two modes use different endpoints and name the recipient differently: agent conversation uses externalNumber, skipping inbox uses to. Both carry lineId in the request body.
const sendDirectMessage = async () => {
const res = await fetch('https://api.aircall.io/v1/messages/send/whatsapp/native', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.AIRCALL_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
lineId: 123,
externalNumber: '+14155552671',
text: 'Your order #4821 has shipped.'
})
});
if (!res.ok) throw new Error(`Send failed: ${res.status}`);
return res.json();
};Outside the window, free-form is rejected. When more than 24 hours have passed since the customer's last reply, a text or media send fails. Send an approved template instead, or queue the message until the customer messages again.
Response codes
These codes apply to all messaging endpoints.
| Status code | Meaning |
|---|---|
| 200 | Request accepted. |
| 429 | Rate limit exceeded — The line hit its WhatsApp throughput limit. |
| 403 | Add-on not active — The line isn't registered or verified for WhatsApp, doesn't belong to your account, or is configured for skipping-inbox mode. |
| 404 | Template not found — The templateParams.id doesn't match a template on the line. Re-fetch the line's templates and confirm the id is still APPROVED. |
See the full list of response codes here.
Updated 3 days ago