Skip to content

API: Sending messages

Business-initiated WhatsApp messages must use an approved template — that rule applies to the API exactly as it does in the app. The API lets your systems send those templates: order confirmations, booking reminders, shipping updates.

See the API overview for authentication and errors.

List approved templates — GET /v1/templates

Terminal window
curl -s https://app.nybero.com/api/v1/templates \
-H "Authorization: Bearer $NYBERO_KEY"
[
{
"id": "7b1f…",
"name": "order_confirmation",
"language": "de",
"category": "utility",
"status": "approved",
"variables": ["contact.name", "order_number"],
"has_media_header": false
}
]

Only approved templates are returned — those are the only ones that can be sent. variables lists the template’s placeholders in order; has_media_header tells you the template carries an image/video/document header (the saved header media is attached automatically at send time).

Delivery stats per template — GET /v1/templates/stats

The numbers behind Templates → View: how many sends of each template Meta accepted, delivered, reported as read, and rejected, plus how many were answered and how many contacts clicked a link button. Pass days to limit the window (default: all time).

Terminal window
curl -s "https://app.nybero.com/api/v1/templates/stats?days=30" \
-H "Authorization: Bearer $NYBERO_KEY"
[
{
"template_id": "7b1f…",
"name": "order_confirmation",
"language": "de",
"sent": 1240,
"delivered": 1198,
"read": 874,
"failed": 12,
"replied": 203,
"clicked": 96,
"last_sent_at": "2026-10-11T18:02:41Z"
}
]

A read message also counts as delivered and sent. read only covers recipients who have read receipts switched on, so treat it as a lower bound. replied counts sends the contact answered within 24 hours and before the next template reached them. clicked counts distinct contacts who opened a link button with click counting enabled. Only templates with at least one send in the window are listed.

Send a template — POST /v1/messages/template

Identify the template by template_id or by template_name (optionally with language), and the recipient by contact_id or phone (the contact must already exist — create it first via POST /v1/contacts):

Terminal window
curl -s https://app.nybero.com/api/v1/messages/template \
-H "Authorization: Bearer $NYBERO_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+4915112345678",
"template_name": "order_confirmation",
"language": "de",
"params": ["", "A-1042"]
}'
{
"message_id": "3f7a…",
"contact_id": "0d9f…",
"template": "order_confirmation",
"status": "sent"
}

params supplies the values for the template’s variables, in order. Contact-field variables (contact.name, contact.phone) fill themselves per recipient — pass an empty string in that position (or any value; it is ignored). Custom variables use exactly what you send.

The send appears in the contact’s conversation in the Inbox like any other outbound message, and delivery/read receipts update its status there.

What the API enforces

The same guardrails as the app — expect these errors:

StatusReason
409The contact opted out — the API never messages opted-out contacts
409The number is known not to be on WhatsApp
400Template not approved, or its channel is not usable
402Subscription inactive or the workspace’s monthly send limit is reached
502Meta rejected the send — detail carries Meta’s error message

Worked example: booking reminder from your calendar system

Your booking tool knows the appointment; Nybero sends the reminder:

  1. Create/refresh the contact at booking time: POST /v1/contacts with opt_in: true (consent collected in the booking form).
  2. 24 hours before the slot, your scheduler calls POST /v1/messages/template with template_name: "appointment_reminder" and params carrying date and time.
  3. Replies land in the shared Inbox, inside the 24-hour window — your team (or the AI agent) takes it from there.