Events API
Send a custom event from your server with the required fields and handle responses.
POST https://graytower.app/api/collect/server accepts a custom event for the Website linked to your Custom events server key. Send JSON with a Bearer token. Keep the key on the server.
Send an event
const response = await fetch("https://graytower.app/api/collect/server", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GRAYTOWER_SERVER_EVENT_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "account_created",
eventId: crypto.randomUUID(),
anonymousId: visitorId, // the browser's _gt_id UUID
params: { plan: "pro" },
}),
});
if (!response.ok) {
throw new Error(`Graytower rejected the event: ${response.status}`);
}The example assumes visitorId is the browser's _gt_id UUID and is available to your backend. If you do not have that value, do not send an invented ID.
Request fields
| Field | Required | Meaning |
|---|---|---|
type | Yes | Custom event name, such as account_created. |
eventId | Yes | UUID for this action; reuse it when retrying the same action. |
anonymousId | Yes | Visitor's _gt_id UUID. |
occurredAt | No | ISO timestamp; Graytower uses receipt time if omitted. |
params | No | Up to 10 string properties for the event. |
Event names use lowercase letters, digits, _, -, or : (up to 64 characters) and cannot be reserved names. Parameter values are at most 255 characters. The request body limit is 16 KB.
Responses and retries
| Status | Meaning |
|---|---|
204 | Accepted; reports may update afterward. No response body. |
400 | Invalid payload. |
401 | Invalid or revoked server key. |
413 | Request body too large. |
429 | Rate or usage limit; check Retry-After when present. |
500 | Server error; retry later with the same eventId. |
Error responses contain an error code.
Reuse the same eventId when retrying one logical action. A newly generated ID can create another event and consume additional allowance.