Developer Guide · Guides
Event messaging
Design WhatsApp messages once in the dashboard, then send them from your backend with one API call per event. Inboxi fills the variables, picks a session message or an approved template, and tracks delivery.
Event messaging separates what is said from when it is said. Your team writes the message for an event such as order.shipped in Settings › Automated Messages. Your developers only send the event name, the phone number and the data. Wording can change without a deploy, and WhatsApp's 24-hour rule is handled for you.
How it works
- Your platform calls the trigger endpoint. Inboxi checks the event is active and required variables are present, then returns
202with alogId. - A background worker renders the message and finds or creates the chat for that number.
- If the customer messaged you in the last 24 hours, the session message is sent as normal text (with an optional URL button).
- Otherwise Inboxi sends the Meta-approved template mapped to the event. The send method is recorded on the log.
- The message appears in the inbox conversation like any other, so agents see exactly what the customer received.
Set up events in the dashboard
Open Settings › Automated Messages. If the list is empty, click Create System Events to add the built-in events. System events start switched off; you activate each one after configuring its message.
- 1Filter events by category: Education, Orders, Appointments, Payments, Custom, General.
- 2The toggle activates the event. Inactive events reject triggers with EVENT_NOT_ACTIVE.
- 3Configure opens the message editor for the event.
- 4New Custom Event creates your own event; its name is prefixed with custom.
- 5Logs shows every trigger with its status and send method.
The editor has four tabs:
- 1Message: the session message sent inside the 24-hour window, with {{variable}} placeholders.
- 2Template (Outside 24h): pick or create the Meta template and map its {{1}}, {{2}} to your data fields.
- 3Variables: the data fields your platform sends, with type and required flag. Auto-discover reads them from the last trigger.
- 4Test: send the event to a phone number with sample data.
- 5Generate report page: long content is published as a web page and linked from the template.
Built-in events
| Event | Category | Required data |
|---|---|---|
enrollment.created | Education | student_name, course_name |
enrollment.activated | Education | student_name, course_name |
enrollment.expired | Education | student_name, course_name |
student.performance_report | Education | student_name, course_name |
order.created | Orders | customer_name, order_number |
order.confirmed | Orders | customer_name, order_number |
order.shipped | Orders | customer_name, order_number |
order.delivered | Orders | customer_name, order_number |
appointment.created | Appointments | customer_name, date, time |
appointment.reminder | Appointments | customer_name, date, time |
payment.received | Payments | customer_name, amount |
payment.failed | Payments | customer_name |
custom.notification | General | free text |
Optional fields (such as tracking_number, access_link, report_link) can also be sent and used in the message. Custom events must use lowercase letters, numbers, underscores and dots, are always prefixedcustom., and a workspace can have up to 50.
Trigger an event
/api/v1/events/triggerQueue an event message (permission: write)| Parameter | Type | Required | Description |
|---|---|---|---|
event | string | required | Event name, e.g. enrollment.created or custom.homework_submitted. |
phone | string | required | Recipient in international format. Non-digits are stripped, so +20 101 234 5678 and 201012345678 are equal. Do not send local numbers like 0101…. |
data | object | optional | Values for the event variables. variables is accepted as an alias. |
sendAt | ISO 8601 | optional | Schedule the send for later instead of sending now. |
curl -X POST https://inboxi.app/api/v1/events/trigger \
-H "X-API-Key: $INBOXI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event": "enrollment.created",
"phone": "201012345678",
"data": {
"student_name": "Ahmed Ali",
"course_name": "Mathematics 101",
"access_link": "https://academy.example.com/courses/101"
}
}'{
"success": true,
"data": { "logId": 1042, "status": "queued" }
}To know which events and fields are available without opening the dashboard, callGET /api/v1/events/messaging. It returns every active event with its requiredFields,optionalFields and full schema.
Scheduling
Add sendAt to send later, for example an appointment reminder the evening before:
{
"event": "appointment.reminder",
"phone": "201012345678",
"data": { "customer_name": "Sara", "date": "2026-11-02", "time": "10:30" },
"sendAt": "2026-11-01T17:00:00Z"
}
// Response
{ "success": true, "data": { "logId": 1043, "status": "scheduled", "scheduledAt": "2026-11-01T17:00:00Z" } }- Scheduled sends are picked up by a periodic job once
sendAthas passed, so expect delivery shortly after the exact time, not to the second. - The 24-hour window is evaluated at send time, not when you scheduled it.
- Events marked sensitive (one-time codes) cannot be scheduled and return
SCHEDULING_NOT_ALLOWED.
Check delivery status
/api/v1/events/messaging/:logId/statusStatus of one trigger (permission: read){
"success": true,
"data": {
"logId": 1042,
"event": "enrollment.created",
"phone": "201012345678",
"status": "sent",
"sendMethod": "template",
"error": null,
"processedAt": "2026-10-10T09:30:02.000Z",
"createdAt": "2026-10-10T09:30:00.000Z"
}
}| status | Meaning |
|---|---|
scheduled | Waiting for sendAt. |
pending / queued | Accepted and waiting for the worker. |
processing | Being rendered and sent. |
sent | Accepted by WhatsApp. Delivery and read receipts arrive as webhooks. |
failed | Not sent; error explains why (for example no approved template outside the window). |
sendMethod tells you which path was used: session or session_interactive (inside the window, plain or with a URL button), template (approved template), or report_template (template linking to a generated report page). For real delivery confirmation subscribe to the message.delivered, message.read andmessage.failed webhooks.
The 24-hour window and template fallback
WhatsApp allows free-form messages only within 24 hours of the customer's last message. Outside that window, only templates pre-approved by Meta can be sent. Inboxi decides for you on every send:
| Situation | What Inboxi sends |
|---|---|
| Customer wrote in the last 24h | The session message from the Message tab, with your variables filled in. |
| Window closed, template mapped | The template from the Template (Outside 24h) tab, with mapped variables and URL-button suffixes. |
| Window closed, long report enabled | A template that links to a hosted report page (pages expire after 30 days). |
| Window closed, no approved template | Nothing. The log is marked failed with a clear error. |
| Event marked sensitive | Always the template path, and the message text is hidden in the inbox. |