https://voice-api.relationsai.com/v1 with a rai_test_ key, which never places a real call. It works once the API is enabled for your workspace (private preview: support@relationsai.com). Your key stays in this tab's memory; live keys are refused.Webhook endpoints
Receive signed event notifications on your server.
List webhook endpoints
Lists the webhook endpoints of the key's mode, newest first. Secrets are never listed, only their last four characters.
GET /v1/webhook-endpoints · Operation ID: listWebhookEndpoints
query Parameters
limitMaximum number of objects to return, from 1 to 100. Defaults to 25.
cursorThe next_cursor of the previous page. Send it with exactly the same filters as the request that returned it; a changed filter set is 400 invalid_cursor.
List webhook endpoints › Responses
A page of endpoints.
objectAlways list.
has_moreTrue when more objects exist after this page.
next_cursorPass as cursor (with the same filters) to fetch the next page. Null on the last page.
Endpoints on this page.
Create a webhook endpoint
Registers an HTTPS URL to receive events of the key's mode. The response contains the signing
secret (whsec_...) once; store it to verify signatures. A replay with the same Idempotency-Key
returns the same endpoint with secret: null (the secret is never stored in readable form; if it was lost,
rotate it). Every delivery is a POST with the
event as JSON and these headers: RelationsAI-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>" with the secret>, RelationsAI-Event-Id, RelationsAI-Event-Type,
RelationsAI-Delivery-Id and User-Agent: RelationsAI-Webhooks/1.0. Reject a signature older
than 5 minutes.
Answer with any 2xx within 10 seconds. Anything else is retried after about 10 seconds, 1 minute,
5 minutes, 30 minutes, 2 hours, 6 hours and 12 hours, then marked failed. Delivery is
at-least-once and unordered. Redirects are not followed. The URL must be public HTTPS on port 443.
Back-pressure: at most 2 attempts are in flight to one endpoint at a time; after 5 failed attempts in a
row an endpoint is paused (1 minute, doubling up to 1 hour) and its waiting deliveries are attempted
after the pause, without using up their attempts; one success resumes it. The endpoint is never
disabled automatically. Live-mode deliveries are attempted before test-mode ones, and a workspace's
test-mode deliveries are limited to 60 attempts a minute.
POST /v1/webhook-endpoints · Operation ID: createWebhookEndpoint
Headers
Idempotency-Key^[\x21-\x7E]+$Optional. A unique key for this operation, 1 to 255 printable ASCII characters with no spaces (a UUID v4 is ideal). With it, a retry of the same request (same key, same body) returns the stored answer and never runs the action twice; reuse the same key for every retry, it is kept for 24 hours. Without it, every request runs: a retry after a timeout can repeat the action, so check the state with a GET before retrying.
Create a webhook endpoint › Request Body
url^https:// · requiredMust start with https://; any other scheme is refused with 400 validation_error (issue invalid_format) before the URL is checked. Then: port 443 only, no user name or password, not a RelationsAI host, and the host must resolve only to public internet addresses, otherwise 422 webhook_url_not_allowed. Checked when created, when changed, and again on every delivery.
eventsEvent types to deliver. webhook_endpoint.test cannot be subscribed to (the test operation always delivers it).
descriptionYour note about the endpoint.
Create a webhook endpoint › Responses
The endpoint was created. Store secret now; it is not shown again.
id^we_[A-Za-z0-9_-]{1,… · requiredEndpoint id (we_...).
objectAlways webhook_endpoint.
livemodeThe endpoint receives events of this mode only.
urlWhere events are delivered.
descriptionYour note about the endpoint.
eventsEvent types delivered to this endpoint. The test event is delivered on request regardless of this list.
statusenabled endpoints receive deliveries; disabled ones do not. Open enum.
secret_last4Last four characters of the current signing secret, to tell secrets apart.
created_atWhen the endpoint was created.
updated_atWhen the endpoint was last changed.
The most recent delivery attempt, or null if none yet.
secret^whsec_[A-Za-z0-9_-]… · requiredThe signing secret (whsec_...), shown only in the first response to the create or rotate request. null on an idempotent replay of that request (same Idempotency-Key): the secret is stored only encrypted and is never returned again. If it was lost, rotate the secret.
Retrieve a webhook endpoint
Returns one webhook endpoint with a summary of its most recent delivery.
GET /v1/webhook-endpoints/{webhook_endpoint_id} · Operation ID: getWebhookEndpoint
path Parameters
webhook_endpoint_id^we_[A-Za-z0-9_-]{1,… · requiredThe webhook endpoint id (we_...).
Retrieve a webhook endpoint › Responses
The endpoint.
id^we_[A-Za-z0-9_-]{1,… · requiredEndpoint id (we_...).
objectAlways webhook_endpoint.
livemodeThe endpoint receives events of this mode only.
urlWhere events are delivered.
descriptionYour note about the endpoint.
eventsEvent types delivered to this endpoint. The test event is delivered on request regardless of this list.
statusenabled endpoints receive deliveries; disabled ones do not. Open enum.
secret_last4Last four characters of the current signing secret, to tell secrets apart.
created_atWhen the endpoint was created.
updated_atWhen the endpoint was last changed.
The most recent delivery attempt, or null if none yet.
Delete a webhook endpoint
Deletes the endpoint. Pending deliveries to it are cancelled. This cannot be undone.
DELETE /v1/webhook-endpoints/{webhook_endpoint_id} · Operation ID: deleteWebhookEndpoint
path Parameters
webhook_endpoint_id^we_[A-Za-z0-9_-]{1,… · requiredThe webhook endpoint id (we_...).
Headers
Idempotency-Key^[\x21-\x7E]+$Optional. A unique key for this operation, 1 to 255 printable ASCII characters with no spaces (a UUID v4 is ideal). With it, a retry of the same request (same key, same body) returns the stored answer and never runs the action twice; reuse the same key for every retry, it is kept for 24 hours. Without it, every request runs: a retry after a timeout can repeat the action, so check the state with a GET before retrying.
Delete a webhook endpoint › Responses
The endpoint was deleted.
idId of the deleted object.
objectType of the deleted object, for example contact.
livemodetrue for live mode, false for test mode.
deletedAlways true.
Update a webhook endpoint
Changes the URL, description, subscribed events or status. Disabling an endpoint stops new deliveries to it; events that occur while it is disabled are not delivered later.
PATCH /v1/webhook-endpoints/{webhook_endpoint_id} · Operation ID: updateWebhookEndpoint
path Parameters
webhook_endpoint_id^we_[A-Za-z0-9_-]{1,… · requiredThe webhook endpoint id (we_...).
Update a webhook endpoint › Request Body
url^https://Must start with https://; any other scheme is refused with 400 validation_error (issue invalid_format) before the URL is checked. Then: port 443 only, no user name or password, not a RelationsAI host, and the host must resolve only to public internet addresses, otherwise 422 webhook_url_not_allowed. Checked when created, when changed, and again on every delivery.
descriptionYour note about the endpoint. Null clears it.
eventsEvent types to deliver. Replaces the current list. webhook_endpoint.test cannot be subscribed to (the test operation always delivers it).
statusenabled or disabled.
Update a webhook endpoint › Responses
The updated endpoint.
id^we_[A-Za-z0-9_-]{1,… · requiredEndpoint id (we_...).
objectAlways webhook_endpoint.
livemodeThe endpoint receives events of this mode only.
urlWhere events are delivered.
descriptionYour note about the endpoint.
eventsEvent types delivered to this endpoint. The test event is delivered on request regardless of this list.
statusenabled endpoints receive deliveries; disabled ones do not. Open enum.
secret_last4Last four characters of the current signing secret, to tell secrets apart.
created_atWhen the endpoint was created.
updated_atWhen the endpoint was last changed.
The most recent delivery attempt, or null if none yet.
Rotate a webhook signing secret
Issues a new signing secret, returned once. During the grace period every delivery carries two
v1= signatures, one per secret, so you can deploy the new secret without missing events; after
it, only the new secret signs. At most two secrets ever sign a delivery.
Rotating again while a grace period runs:
grace_period_hours: 0is always allowed and retires EVERY previous secret immediately: use it when a secret may have leaked, and deploy the new one at once.- a grace period above 0 keeps the OLDEST secret still signing (the one your receiver most likely uses) until its original grace end, discards the secret issued by the rotation in between, and issues a new one. Use it when the response to a rotation was lost.
A replay of this request with the same Idempotency-Key returns the endpoint with secret: null: the
secret is shown only in the first response and is never stored in readable form. To recover a secret
you did not receive, rotate again (with a grace period, as above).
POST /v1/webhook-endpoints/{webhook_endpoint_id}/rotate-secret · Operation ID: rotateWebhookEndpointSecret
path Parameters
webhook_endpoint_id^we_[A-Za-z0-9_-]{1,… · requiredThe webhook endpoint id (we_...).
Headers
Idempotency-Key^[\x21-\x7E]+$Optional. A unique key for this operation, 1 to 255 printable ASCII characters with no spaces (a UUID v4 is ideal). With it, a retry of the same request (same key, same body) returns the stored answer and never runs the action twice; reuse the same key for every retry, it is kept for 24 hours. Without it, every request runs: a retry after a timeout can repeat the action, so check the state with a GET before retrying.
Rotate a webhook signing secret › Request Body
grace_period_hoursHours during which every delivery carries two signatures, one per secret, so you can deploy the new secret without dropping events. 0 retires every previous secret immediately (always allowed, also during a grace period). A value above 0 during a running grace period keeps the oldest secret still signing until its original grace end and discards the one in between.
Rotate a webhook signing secret › Responses
The endpoint with its new secret. Store it now.
id^we_[A-Za-z0-9_-]{1,… · requiredEndpoint id (we_...).
objectAlways webhook_endpoint.
livemodeThe endpoint receives events of this mode only.
urlWhere events are delivered.
descriptionYour note about the endpoint.
eventsEvent types delivered to this endpoint. The test event is delivered on request regardless of this list.
statusenabled endpoints receive deliveries; disabled ones do not. Open enum.
secret_last4Last four characters of the current signing secret, to tell secrets apart.
created_atWhen the endpoint was created.
updated_atWhen the endpoint was last changed.
The most recent delivery attempt, or null if none yet.
secret^whsec_[A-Za-z0-9_-]… · requiredThe signing secret (whsec_...), shown only in the first response to the create or rotate request. null on an idempotent replay of that request (same Idempotency-Key): the secret is stored only encrypted and is never returned again. If it was lost, rotate the secret.
Send a test event
Creates a webhook_endpoint.test event and delivers it to this endpoint only, signed like any other event. The response is the delivery, usually pending; read the deliveries list to see the result.
POST /v1/webhook-endpoints/{webhook_endpoint_id}/test · Operation ID: sendWebhookEndpointTestEvent
path Parameters
webhook_endpoint_id^we_[A-Za-z0-9_-]{1,… · requiredThe webhook endpoint id (we_...).
Headers
Idempotency-Key^[\x21-\x7E]+$Optional. A unique key for this operation, 1 to 255 printable ASCII characters with no spaces (a UUID v4 is ideal). With it, a retry of the same request (same key, same body) returns the stored answer and never runs the action twice; reuse the same key for every retry, it is kept for 24 hours. Without it, every request runs: a retry after a timeout can repeat the action, so check the state with a GET before retrying.
Send a test event › Responses
The test event was created and its delivery scheduled.
id^wd_[A-Za-z0-9_-]{1,… · requiredDelivery id (wd_...).
objectAlways webhook_delivery.
livemodeMode of the event.
webhook_endpoint_idThe endpoint.
event_idThe event delivered (evt_...). Also sent as the RelationsAI-Event-Id header.
event_typeAn event type. Open enum; new types can be added.
statuspending (first attempt not made yet), retrying (failed, another attempt is scheduled), succeeded (your server answered 2xx), failed (every attempt failed). Open enum.
attemptsAttempts made so far.
last_attempt_atWhen the last attempt was made.
next_attempt_atWhen the next attempt is scheduled, if any.
response_statusHTTP status of your server's last answer, if it answered.
duration_msHow long the last attempt took.
errorWhy the last attempt failed: timeout (no answer in 10 seconds), connection_failed (including a host name that did not resolve in time), tls_error, blocked_destination (the URL resolved to a non-public address), http_error (a non-2xx answer), signing_failed (RelationsAI could not sign the delivery; nothing was sent, the attempt still counts, and the delivery fails after its last attempt like any other; contact support if it persists). Null if it succeeded. Open enum.
created_atWhen the delivery was created.
List deliveries
Lists deliveries to this endpoint, newest first, for troubleshooting. Deliveries are kept for 30 days.
GET /v1/webhook-endpoints/{webhook_endpoint_id}/deliveries · Operation ID: listWebhookDeliveries
path Parameters
webhook_endpoint_id^we_[A-Za-z0-9_-]{1,… · requiredThe webhook endpoint id (we_...).
query Parameters
limitMaximum number of objects to return, from 1 to 100. Defaults to 25.
cursorThe next_cursor of the previous page. Send it with exactly the same filters as the request that returned it; a changed filter set is 400 invalid_cursor.
statusOnly deliveries in this status.
List deliveries › Responses
A page of deliveries.
objectAlways list.
has_moreTrue when more objects exist after this page.
next_cursorPass as cursor (with the same filters) to fetch the next page. Null on the last page.
Deliveries on this page.
Retry a delivery
Schedules an immediate new attempt of a failed or retrying delivery. The event and its id are unchanged, so your duplicate check still works.
POST /v1/webhook-deliveries/{webhook_delivery_id}/retry · Operation ID: retryWebhookDelivery
path Parameters
webhook_delivery_id^wd_[A-Za-z0-9_-]{1,… · requiredThe webhook delivery id (wd_...).
Headers
Idempotency-Key^[\x21-\x7E]+$Optional. A unique key for this operation, 1 to 255 printable ASCII characters with no spaces (a UUID v4 is ideal). With it, a retry of the same request (same key, same body) returns the stored answer and never runs the action twice; reuse the same key for every retry, it is kept for 24 hours. Without it, every request runs: a retry after a timeout can repeat the action, so check the state with a GET before retrying.
Retry a delivery › Responses
A new attempt was scheduled.
id^wd_[A-Za-z0-9_-]{1,… · requiredDelivery id (wd_...).
objectAlways webhook_delivery.
livemodeMode of the event.
webhook_endpoint_idThe endpoint.
event_idThe event delivered (evt_...). Also sent as the RelationsAI-Event-Id header.
event_typeAn event type. Open enum; new types can be added.
statuspending (first attempt not made yet), retrying (failed, another attempt is scheduled), succeeded (your server answered 2xx), failed (every attempt failed). Open enum.
attemptsAttempts made so far.
last_attempt_atWhen the last attempt was made.
next_attempt_atWhen the next attempt is scheduled, if any.
response_statusHTTP status of your server's last answer, if it answered.
duration_msHow long the last attempt took.
errorWhy the last attempt failed: timeout (no answer in 10 seconds), connection_failed (including a host name that did not resolve in time), tls_error, blocked_destination (the URL resolved to a non-public address), http_error (a non-2xx answer), signing_failed (RelationsAI could not sign the delivery; nothing was sent, the attempt still counts, and the delivery fails after its last attempt like any other; contact support if it persists). Null if it succeeded. Open enum.
created_atWhen the delivery was created.