Appearance
Send product events
Send Zay the events your backend sees — signups, purchases, campaign touches — so they join the user's Zay journey in analytics.
This is optional. You don't need it to onboard or pay users.
Requirements
| Requirement | Description |
|---|---|
| Signed requests | Working signing code — see Authentication |
| Your own user ids | The id you set as external_id with Create user |
How it works
1. Use the same user id everywhere
Events are tied to users by your id, user_external_id. Set the same value as external_id when you create the user, and events from before and after signup join into one journey:
json
{ "phone_number": "+15555550100", "external_id": "acme-user-42" }Because the id is yours, you can send events for a user before they exist in Zay.
2. Batch your events
Collect events and send them together — up to 1,000 per request, under 1 MB. Each event needs:
| Field | What to put in it |
|---|---|
event_name | What happened, e.g. signup_completed. Case-insensitive |
payload | Any JSON object of properties |
event_datetime | When it happened on your side, ISO 8601, UTC |
event_id | A new UUIDv4 for this event — generate it once, when the event happens |
user_external_id | Your id for the user |
device_id | Optional — your client or device id, if you have one |
The full schema is in Submit events.
3. Send the batch
bash
curl -X POST "https://api-connect.zay.me/merchants/v1/events" \
-H "Content-Type: application/json" \
-H "zay-api-key: $ZAY_API_KEY" \
-H "zay-timestamp: $TS" \
-H "zay-signature: $SIG" \
-d '{
"events": [
{
"event_name": "signup_completed",
"payload": {"plan": "pro", "referrer": "campaign-42"},
"event_datetime": "2025-12-05T12:05:49Z",
"event_id": "0192f5b0-1234-7e8d-89ab-cdef01234567",
"user_external_id": "acme-user-42"
}
]
}'You get 202 Accepted with no body: the batch is queued. If any event is invalid, the whole batch is rejected with 400 and nothing is queued — fix it and send it again.
4. Retry without double-counting
If a batch fails with a timeout or a 5xx, send the same events again with the same event_ids. Zay ignores any event_id it has seen in the last 24 hours, so a retried batch never counts an event twice. Don't regenerate event_id on retry.
Related
- Submit events — the endpoint and its limits
- Handle errors and retries