Receive events
1. Register an endpoint
enabledEvents takes types from the event catalog, or "*" for all. The response includes secret, shown only once. scope is self for the events of this organization or customers for the events of its subaccounts. An organization can have up to 16 endpoints, enabled or not, because every event goes to each one that listens to it. The next one answers 422 webhook_endpoint_limit: delete one you no longer use, or add event types to one that already exists.
2. Test it
POST /v2/webhook-endpoints/{id}/test sends a signed webhook_endpoint.test event to that endpoint only.
3. Answer fast
Respond 2xx as soon as you have stored the event, and do the work afterwards. Any other answer, or no answer, is retried.
Each event is an envelope:
customerId is present when the event belongs to a subaccount. The data shape depends on type.
Eventobject, 7 fields
objectenumrequiredeventidstringrequiredtypestringrequiredThe event type, such as case.escalated. See GET /v2/event-types.
createdAtstring (date-time)requiredorganizationIdstringrequiredcustomerIdstringoptionalThe subaccount the event belongs to, when there is one.
dataobjectrequiredThe shape depends on `type`. See GET /v2/event-types.
Retries
- Lelemon sends the event with Lelemon-Signature and a Lelemon-Delivery-Id. The v1 value is an HMAC-SHA256 of t, a dot and the raw body.
- Your endpoint checks the signature against the raw body and rejects a t more than 5 minutes from its clock.
- Any answer that is not 2xx, or no answer, counts as a failure.
- Lelemon waits and tries again, up to 12 attempts in all.
- The event id stays the same on every attempt and the Lelemon-Delivery-Id changes. Deduplicate by the evt_ id.
- Your endpoint stores the event, answers 2xx and does the work afterwards. The delivery is done.
- After the last attempt the delivery is exhausted. An endpoint with no successful delivery for 72 hours becomes disabled and Lelemon sends an email.
| Attempt | Wait before it |
|---|---|
| 2 | 5 seconds |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
| 6 | 5 hours |
| 7 to 12 | 10 hours each |
After the last attempt the delivery is exhausted. If an endpoint has no successful delivery for 72 hours, it becomes disabled and Lelemon sends an email.
Events can arrive twice and out of order. Deduplicate by the evt_ id and compare createdAt. Each attempt carries a Lelemon-Delivery-Id header, a whd_ id that changes per attempt while the event id stays the same. It is the id of that attempt in GET /v2/webhook-endpoints/{id}/deliveries, so you can match what you received with what Lelemon recorded.
Inspect and replay
GET /v2/webhook-endpoints/{id}/deliverieslists the attempts of an endpoint.POST /v2/events/{id}/resendsends an event again, to one endpoint withendpointIdor to every subscribed endpoint.
Events and their delivery attempts are kept for 30 days. After that, an event can no longer be resent (404) and its attempts leave the list. An event that is still being retried or was resent within the last 30 days stays until that window passes.
Local development
Local URLs are rejected unless the API runs with NODE_ENV=development or test and LELEMON_ALLOW_LOCAL_WEBHOOKS=true. Then localhost, 127.0.0.1 and ::1 are accepted. No other private range is. Elsewhere, expose your machine with a tunnel.