Webhooks overview
Lisoloo delivers status updates asynchronously to a URL you configure on your API key. Each event is a single HTTP POST with a JSON body and the optional HTTP Basic credentials you set.
Why webhooks
Section titled “Why webhooks”For any send of more than a handful of recipients, polling
GET /status/{message_id} is the wrong tool — it burns your
120 reads/minute rate-limit and adds latency. Webhooks push the
final state directly to your server, in real time, for free (no extra
rate-limit cost on your end).
┌──────────────┐ webhook POST ┌────────────────┐ POST /send ─▶ │ Lisoloo API │ ──────────────▶ │ Your endpoint │ └──────────────┘ on each event └────────────────┘ │ └─ status transitions internally: pending → processing → sent → deliveredDelivery semantics
Section titled “Delivery semantics”- HTTP method:
POST. - Content-Type:
application/json. - Body: a single event object (see Event types).
- Authentication: HTTP Basic with the credentials configured on your API key, if set. No HMAC signature today.
- Retries: up to 4 attempts on
5xxresponses or connection failures, with exponential backoff30s → 2m → 10m → 1h. After 4 failures the event is dropped. - Order: not guaranteed. A
sms.deliveredevent for one recipient may arrive before thesms.sentevent for another in the same batch. Userecipient_phoneto correlate; rely on the authoritative state inGET /statusif order matters. - Idempotency: every event has an
event_id(UUID v4). Your endpoint must be idempotent — replay with the sameevent_idmust be a no-op.
Configuring a webhook
Section titled “Configuring a webhook”Webhook configuration lives on the API key, not the merchant account. You configure it in the dev portal:
- Open Bloonio → Lisoloo → Developer → API keys.
- Scroll to Webhook configuration.
- Set
webhook_urlto an HTTPS endpoint on your server. - (Optional but recommended) set
webhook_basic_auth_usernameandwebhook_basic_auth_password. The gateway will use these for HTTP Basic auth on every POST. - Save.
The full walkthrough — including the write-only password field and the “Basic auth configured” indicator — is at Webhooks → Configuration.
What you’ll receive
Section titled “What you’ll receive”Every event has the same outer envelope:
{ "event_id": "f8a3b7c1-2e4d-4a9b-9d8f-7c6e5b4a3d2c", "event_type": "sms.delivered", "timestamp": "2026-05-27T10:15:08Z", "message_id": "507f1f77bcf86cd799439011", "data": { ...event-specific payload... }}The event_type values and per-event data shapes are documented at
Webhook event types.
What you should send back
Section titled “What you should send back”A 2xx status (200, 201, or 204) acknowledges the event. The
body is ignored. Any 4xx is treated as a permanent failure (the
event will not retry — typically used to refuse misrouted events).
Any 5xx or connection error triggers the retry sequence.
HTTP/1.1 204 No ContentAim to respond in under 5 seconds. Acks beyond 5 seconds are
treated as timeout and trigger a retry. If your handling is slow,
accept first and process async — push the event into a queue and
return 204 immediately.
Testing webhooks locally
Section titled “Testing webhooks locally”webhook.site and smee.io both expose a public URL that forwards to your laptop. Useful for early integration; for production routing use your own domain with TLS.
For unit tests, the sandbox webhook_url accepts any HTTPS URL — fire
a sandbox POST /send against a webhook.site URL and watch the events
arrive within a few seconds.