Developers
Events API overview
Tell Custoz when something happens in your product. Each event updates the customer's contact and runs the automation rules your team has built for it.
How an event travels
- 1
Your system posts it
Send POST /events with your source key, or let a tool post to your webhook address.
- 2
Custoz checks and stores it
The body is validated, duplicates are recognised, and you get a response straight away.
- 3
The contact is updated
A new phone number becomes a contact. Existing contacts keep the details they already have.
- 4
Your rules run
Every enabled “An event is received” rule for that event name runs, and can send templates.
Sending an event
Authentication
Create an event source in Settings → Events → Sources & keys. Each source gets its own key, starting with cev_, shown once when it's created. Send it as a bearer token: Authorization: Bearer cev_… Requests without a valid key get 401.
You can rotate a source's key at any time from the same page.
The request body
Send a JSON object to POST /events with these fields:
- event (required) — the event name: lower-case letters, digits, underscores and dots, starting with a letter, up to 64 characters. For example trial_started or invoice.payment_failed.
- phone (required) — the customer's WhatsApp number with its country code.
- id (recommended) — your own id for this event, up to 100 characters. Sending the same id again from the same source is treated as a duplicate.
- name, email, company (optional) — text up to 200 characters each, used when Custoz creates a new contact.
- properties (optional) — up to 50 values: text up to 1,000 characters, numbers, true/false or null. Property names use lower-case letters, digits and underscores, up to 40 characters.
Responses
- 202 Accepted — the event is stored. The body includes its id and duplicate: true or false. Rules run after the response.
- 400 — something in the body isn't valid; each problem is named by its field.
- 401 — missing or unknown source key.
- 413 — the body is larger than 64 KB.
- 429 — more than 600 events a minute from one source.
Retries and duplicates
If a request times out, send it again with the same id. A repeat is answered as a duplicate and starts no rules, so your customers never get the same message twice.
Declaring your events
Publish the list of events a source sends with PUT /events/catalogue, using the same source key. Send the whole list each time. Declared events and their fields show up in Custoz straight away, so your team can build rules and fill template variables before the first real event arrives.
Adding a new event is your change to make — it never needs a Custoz release.
Receiving webhooks from other tools
Tools that send their own webhook format post to a unique address, POST /hooks/<token>, which Custoz creates for you. The signature is checked against the raw body before anything else; invalid signatures get 401 and are logged.
- Shopify, WooCommerce, Razorpay and Stripe have ready-made adapters with their own signature checks.
- Any other service can use a custom webhook: capture a sample request, then map the phone number, event name, dedup id and properties from the payload. JSON and form-encoded bodies are both supported.
- Custom webhooks can be signed with HMAC-SHA256 (your header name, encoding and prefix), protected with a shared secret header, or left unsigned.
- Every delivery is logged with its outcome — accepted, duplicate, ignored, rejected or failed — and can be replayed after you fix a mapping.
Good to know
- Events without a valid phone number are logged as failed and don't run any rules.
- Event properties are available in templates and messages as variables, for example {{event.order_id}}.
- Processed events are kept for 90 days, and webhook delivery logs for 30 days.
Related
Your customers are already messaging you. Answer them well.
Bring your WhatsApp number, your team and your FAQs. Custoz does the rest.
No credit card needed.