Frontro Live Zapier API and event reference
This reference documents the production OAuth and REST Hook contract used by the official Frontro Live Zapier integration. Zapier configures these requests for users; ordinary users should follow the connection guide instead of calling the endpoints directly.
Base URLs and authentication
| Purpose | URL |
|---|---|
| Frontro OAuth consent | https://creator.frontro.com/integrations/zapier/oauth/authorize |
| Frontro API | https://api.frontrow.cc |
The integration uses OAuth 2.0 authorization code flow with PKCE and rotating refresh tokens. Access tokens are bearer credentials and must never be placed in a URL, browser bundle, log, screenshot, support ticket, or source repository.
Only a channel owner or administrator can authorize a channel. A Frontro account's owner/admin role is checked by the API; a client-side role or feature-flag value is not authorization.
Authorization scopes
| Scope | Allows |
|---|---|
hooks:read | Read event samples for trigger setup. |
hooks:write | Create and remove Zapier REST Hook subscriptions. |
recordings:write | Complete a delivery-specific recording transcription. |
The token endpoint is POST /v1/integrations/zapier/oauth/token. It accepts authorization_code and refresh_token grants. Zapier authenticates the confidential client; Frontro does not publish the client secret.
Frontro returns OAuth errors as { "error": "<code>" } with codes such as invalid_client, invalid_grant, invalid_request, access_denied, temporarily_unavailable, or server_error.
Connection and hooks
All endpoints below use the production API base URL.
Test the connection
GET /v1/integrations/zapier/me
Requires a bearer token. The response identifies the connected channel and supplies Zapier's connection label.
{
"id": "12884901905",
"channelId": 12884901905,
"connectionLabel": "Frontro Live channel 12884901905"
}
Subscribe
POST /v1/integrations/zapier/hooks
Requires hooks:write.
{
"eventType": "user.signup",
"targetUrl": "https://hooks.zapier.com/hooks/standard/..."
}
Frontro validates the target as a Zapier REST Hook destination and returns 201 Created with a subscription ID and event type. The subscription is scoped to the OAuth grant's channel.
Unsubscribe
DELETE /v1/integrations/zapier/hooks/{subscriptionId}
Requires hooks:write. A successful removal returns 204 No Content.
Revoke an OAuth grant
POST /v1/integrations/zapier/oauth/revoke
Requires the grant's bearer token. A successful revocation returns 204 No Content and removes the grant's active REST Hook subscriptions.
Zapier removing an App Connection does not call this endpoint automatically. A channel owner or administrator must also disconnect the grant under Settings → Integrations → Zapier in Frontro Creator. The Frontro UI performs the managed revocation with the signed-in user's channel authorization; it never exposes the OAuth token.
Read a sample
GET /v1/integrations/zapier/events/{eventType}/samples
Requires hooks:read. Samples use synthetic or channel-scoped test data and the same versioned envelope as live deliveries.
Event envelope
Every webhook delivery contains:
{
"schemaVersion": 1,
"eventId": "00000000-0000-4000-8000-000000000102",
"eventType": "user.signup",
"occurredAt": "2026-09-01T19:05:00Z",
"channelId": 12884901905,
"data": {}
}
| Field | Type | Meaning |
|---|---|---|
schemaVersion | integer | Contract version; currently 1. |
eventId | UUID string | Stable event identifier and idempotency key. |
eventType | string | One of the supported event names below. |
occurredAt | RFC 3339 datetime | When the business event occurred. |
channelId | integer | Channel that owns the event. |
data | object | Event-specific fields. |
Use eventId to deduplicate retries. Delivery attempt IDs and Zap run IDs are operational identifiers, not business-event idempotency keys.
Event types
| Event type | Important event-specific fields |
|---|---|
recording.completed | frontroLiveId, externalId, title, durationMs, recordingUrl, recordingFormat, correlationMarker, otterImportName |
user.signup | userId, externalId, username, displayName, givenName, familyName, email, phone, role, acceptsMarketing, smsMarketingConsent, smsMarketingConsentVersion |
user.deleted | userId, externalId, username, email, phone, deletedAt |
user.marketing.email.subscribed | userId, externalId, email, names, subscribed |
user.marketing.email.unsubscribed | userId, externalId, email, names, subscribed |
user.marketing.sms.subscribed | userId, externalId, phone, names, subscribed, consentVersion |
user.marketing.sms.unsubscribed | userId, externalId, phone, names, subscribed, consentVersion |
purchase.one_time.completed | userId, oneTimePurchaseId, title, amountMinor, currency, provider IDs, livestreamId |
purchase.subscription.started | purchase, user, membership, plan, price, billing, provider, status, and renewal fields |
purchase.subscription.cancelled | purchase, user, membership, plan, price, billing, provider, status, and renewal fields |
frontro.purchase.gift_tip.completed | kind, userId, oneTimePurchaseId, title, amountMinor, currency, provider IDs, livestreamId |
registration.completed | registrationId, frontroLiveId, event metadata, scheduled start, userId |
Fields can be nullable when the source record has no value. Events queued before an additive contract release can omit the newly added optional field while the old queue drains.
recording.completed also contains otterCompletion.callbackUrl. The recording URL is short-lived and should be imported immediately. The callback URL is unique to one delivery and must not be reconstructed.
Transcription completion
POST /v1/integrations/zapier/recordings/{eventId}/deliveries/{deliveryId}/transcription-completions
Requires recordings:write. Use the exact URL delivered in otterCompletion.callbackUrl.
{
"status": "COMPLETED",
"otterRecordingId": "otter-recording-123",
"transcriptUrl": "https://otter.ai/u/example",
"errorCode": ""
}
status is COMPLETED or FAILED. A successful response identifies the event and delivery, reports the durable delivery status, and says whether the request changed state.
{
"eventId": "00000000-0000-4000-8000-000000000101",
"deliveryId": "00000000-0000-4000-8000-000000000201",
"status": "DELIVERED",
"changed": true
}
Errors and retries
| Status | Meaning |
|---|---|
400 | Invalid request, event type, identifier, callback shape, or OAuth grant input. |
401 | Missing, invalid, expired, or insufficient bearer token. Reconnect when refresh returns invalid_grant. |
403 | The signed-in Frontro user cannot authorize or manage the selected channel. |
404 | Resource not found or the integration is unavailable for the channel. |
409 | The callback conflicts with the durable delivery state. Do not guess another delivery ID. |
429 | Temporary rate limit; retry with backoff. |
500 | Server error; retry with backoff and preserve eventId. |
Frontro retries non-terminal webhook deliveries with bounded backoff. A destination should return a 2xx response only after it has durably accepted the event, and it should make processing idempotent on eventId.
For help with a production request, contact Frontro Support with the timestamp, event type, and eventId. Never send an access token, refresh token, client secret, or unrelated customer data.