Skip to main content
Route each event by event_type, and open that event’s page for the shape of data.

Read the envelope

Every webhook request body is this envelope, and every WebSocket event frame carries the same envelope in its event field. Only data changes between event types. Deduplicate on event_id, which stays the same across webhook retries and WebSocket replays, and keep trace_id for support. This one carried a message.failed event:
captured-output

Read a person’s time zone

Every person in an event carries timezone: the IANA time zone name their Relay app last reported, such as America/Detroit. It is null until their app reports one; when the person uses Relay on more than one device, the device they used last sets it. An agent has no timezone. Timestamps stay in UTC, so use it to read them in the person’s local time:

Read a person’s age range

Every person in an event also carries age_range: under_13, 13_15, 16_17 or 18_plus. Their Relay app reads it from the person’s Apple Account (Apple’s Declared Age Range), or, when Apple has none, from a birth year the person types once; Relay keeps only the range. It is null until their app reports one. An agent has no age_range. Your agent never has to ask anyone their age. If your agent is for adults, set its Age rating to 18+ in Relay Console: Relay then refuses a chat between it and anyone whose age_range is not 18_plus, with 403, code 2035, and leaves it out of their directory, search and suggestions.
Every person in an event also carries links: up to 5 profile links they added in Relay, in the order they chose. Each link is an absolute https URL, and the list is empty when they added none. Relay sends no site name, so read the site from the URL’s host. An agent has no links.
Relay stores each link as the WHATWG URL parser writes it, with the scheme and host in lowercase and a non-ASCII host in punycode. No two links in a list are the same after that step. Relay refuses a link with whitespace or control characters, a user name or password, a host that is not public (localhost, an IP address, a single-label name, .local and other private names), or a host label that mixes Latin with another script.

Read a person’s about

Every person in an event also carries about: a line of plain text, at most 160 characters, that they wrote about themselves in Relay. It is null when they wrote none. An agent has no about.

Choose an event type

Subscribe to the events your backend acts on and ignore the rest; a webhook subscription names them in subscribed_events, and a WebSocket consumer receives all of them. Most agents need message.received first and chat.created second.

List event types

Read the names the API accepts in subscribed_events. The list is the contract, so check a new name here before you add it to a subscription:

What you get back

Relay answers 200 with every event name and the URL of this catalog. The order matches the table above, and the list changes only with a new API contract version:
captured-output

When it fails

A 401 means the Agent Token is missing or revoked. An event name that is not in this list is rejected by the subscription route with code 1005, so read the list rather than typing names by hand. If an event you subscribed to never arrives, read delivery and retries before assuming it did not fire.

Next steps