What this integration exposes
Version 1.0.1 is the private Zapier Platform integration for First AI Employee. It exposes five REST hook triggers, three create actions, and two searches. Every request is tenant-scoped by the OAuth grant. Callers never supply a business or customer ID.
Official paths
OAuth and the Zapier API are served from https://api.firstaiemployee.com. The authenticated base path is https://api.firstaiemployee.com/api/zapier.
- Every event payload is flat and has a stable top-level id so Zapier can deduplicate it.
- Event timestamps use ISO 8601 UTC strings. Appointments preserve their local date and time together with the account IANA time zone.
- Contacts and Requests endpoints honor whether those Front Desk modules are available on the authorized account.
Authentication and scopes
Zapier uses the OAuth 2.0 authorization-code grant as a registered confidential client. The account owner reviews the requested scopes on the First AI Employee consent page. The Zapier client authenticates at the token endpoint with its registered client credentials. PKCE is accepted when supplied, but it is not mandatory for this confidential Zapier client.
Eight requested scopes
| Scope | Access |
|---|---|
leads:read | Read new lead events and trigger samples. |
calls:read | Read completed calls, including transcript text. |
bookings:read | Read booking events and find exact bookings. |
bookings:write | Create a booking or captured appointment request. |
contacts:read | Read contact events and find a contact by phone. |
contacts:write | Create or reuse a contact by normalized phone. |
requests:read | Read customer Request events and trigger samples. |
requests:write | Create an idempotent Request for an existing contact. |
Scopes are enforced both when a subscription is created and when each event is delivered. Reauthorization never silently widens an existing grant.
OAuth endpoints and token lifecycle
Access tokens last one hour. Refresh tokens rotate on every successful use and expire after 90 days of inactivity. Reusing an authorization code or an already-used refresh token revokes the grant because replay cannot be distinguished from credential theft.
Protocol endpoints
| Method | Path | Authentication | Purpose |
|---|---|---|---|
GET | /oauth/authorize | Browser session | Start the authorization-code flow and render owner consent. |
POST | /oauth/authorize | Browser session + CSRF | Submit the owner consent form. Browser-only, not a partner API call. |
GET | /oauth/resume | Signed resume token | Resume the same authorization request after sign-in. Browser-only. |
POST | /oauth/token | Confidential client | Exchange a code or rotate a refresh token. |
- redirect_uri must exactly match one of the client registered redirect URIs.
- Authorization codes are single-use. Do not resubmit a code exchange after an ambiguous result.
- Persist the new refresh_token from every successful response before refreshing again.
- A 401 can mean the access token expired. A successful refresh and retry leave the connection active. If /oauth/token returns invalid_grant because authorization was revoked, reconnect that saved account.
- Each saved connection has its own grant. Reconnecting one does not repair other revoked connections. Check the authorized business before publishing the Zap.
- A 403 can mean insufficient scopes or an unavailable module. Check error and error_description before reauthorizing.
Trigger and webhook lifecycle
All five triggers use the same subscription lifecycle. Zapier creates the subscription when a Zap is turned on, receives flat JSON events, and deletes the subscription when the Zap is turned off.
- When a Zap is turned on, Zapier sends
POST /api/zapier/hookswithtargetUrland one of the five supported events. - First AI Employee requires HTTPS on the exact
hooks.zapier.comhost, checks the event scope, and returns201with the subscription ID. - When the event occurs, First AI Employee posts one flat JSON payload to the Zapier URL. A write originating from that same grant is not echoed back to the same connection.
- When the Zap is turned off, Zapier sends
DELETE /api/zapier/hooks/{id}and receives204.
Current delivery is a single best-effort POST with an eight-second timeout. A non-2xx response or network failure is logged and never blocks the customer record being saved. This route does not currently provide a server-side redelivery queue.
Operation coverage for v1.0.1
These are the ten visible Zapier operations and the exact API contracts behind them. Trigger test endpoints return up to three recent records or one clearly marked synthetic sample when the account has no matching records.
| Type | Operation | Method and path | Scope | Input | Result and behavior |
|---|---|---|---|---|---|
| Trigger | New Leadnew_leadlead.created | GET/api/zapier/leads | leads:read | None | Lead or clearly marked sample array with id, contact, call, outcome, and occurredAt fields. Subscribes through the shared REST hook lifecycle and emits after a completed lead call. |
| Trigger | New Bookingnew_bookingbooking.created | GET/api/zapier/bookings | bookings:read | None | Booking or clearly marked sample array with date, time, timeZone, status, and calendarWritten. Emits when an appointment is recorded, whether it was written to a calendar or only captured. |
| Trigger | Completed Callcall_completedcall.completed | GET/api/zapier/calls | calls:read | None | Call or clearly marked sample array with summary, transcript, intent, outcome, duration, and occurredAt. Uses a separate permission because the payload can contain sensitive transcript text. |
| Trigger | New Contactcontact_createdcontact.created | GET/api/zapier/contacts | contacts:read | None | Contact or clearly marked sample array with contactId, identity, source, stage, and occurredAt. Available when the Front Desk Contacts module is enabled for the account. |
| Trigger | New Requestcase_createdcase.created | GET/api/zapier/requests | requests:read | None | Request or clearly marked sample array with requestId, contactId, summary, priority, status, and occurredAt. The customer-facing name is Request. The stable wire event remains case.created. |
| Action | Create Bookingcreate_booking | POST/api/zapier/bookings | bookings:write | name, date (YYYY-MM-DD), time (HH:MM), optional reason | status, detail, name, date, time, reason A captured status means the appointment was recorded but no calendar write occurred. |
| Action | Create or Update Contactcreate_contact | POST/api/zapier/contacts | contacts:write | phone, optional name, optional email | Contact fields plus created, reused, and filledBlankFields Normalizes the phone, reuses an exact existing contact, and only fills blank name or email fields. |
| Action | Create Requestcreate_request | POST/api/zapier/requests | requests:write | deduplicationKey (sent as sourceRecordId), contactId, summary, optional jobId, description, category, priority | Request fields plus created and replayed Deduplication uses the source record ID within the same OAuth grant. Reuse it only for identical details; reconnecting does not preserve this deduplication boundary. |
| Search | Find Contactfind_contact | GET/api/zapier/contacts/find?phone={phone} | contacts:read | phone | One-item contact array or an empty array Matches the normalized phone exactly and supports Zapier find-or-create flows. |
| Search | Find Bookingfind_booking | GET/api/zapier/bookings/find?name={name}&date={date}&time={time} | bookings:read | name, date (YYYY-MM-DD), time (HH:MM) | One-item booking array or an empty array Matches exact structured name, date, and time fields. Legacy prose summaries are not guessed. |
Authenticated endpoint inventory
| Method | Path | Authentication | Purpose |
|---|---|---|---|
GET | /api/zapier/me | Bearer | Test the connection and return the authorized business and scopes. |
POST | /api/zapier/hooks | Bearer + event scope | Subscribe the Zapier target URL to one supported event. |
DELETE | /api/zapier/hooks/{id} | Bearer | Remove the exact subscription for this connection. |
GET | /api/zapier/leads | leads:read | New Lead trigger sample or recent records. |
GET | /api/zapier/calls | calls:read | Completed Call trigger sample or recent records. |
GET | /api/zapier/bookings | bookings:read | New Booking trigger sample or recent records. |
POST | /api/zapier/bookings | bookings:write | Create Booking action. |
GET | /api/zapier/bookings/find | bookings:read | Find Booking search. |
GET | /api/zapier/contacts | contacts:read | New Contact trigger sample or recent records. |
POST | /api/zapier/contacts | contacts:write | Create or Update Contact action. |
GET | /api/zapier/contacts/find | contacts:read | Find Contact search. |
GET | /api/zapier/requests | requests:read | New Request trigger sample or recent records. |
POST | /api/zapier/requests | requests:write | Create Request action. |
Request and response examples
The examples use placeholders and example data. They do not contain production credentials or customer records. All API calls use JSON except the OAuth token endpoint, which uses form encoding.
Verify a live Zap
- Test the connection and confirm the correct business. Review every action and its destination before turning the Zap on.
- An editor test retrieves a sample for field mapping. To verify delivery, publish and enable the Zap, then generate a controlled event in that same account.
- In Zap History, confirm the trigger and actions succeeded. Keep the Zap enabled and its successful run history available during review.
- To test New Contact or New Request, create the record from the dashboard or through another connection authorized to the same account. Writes are not echoed to their own grant.
- Find Booking searches the 200 most recent booking events using structured name, date, and time. A synthetic trigger test does not save an appointment that the search can find.
Create or reuse a contact
Create a booking
Create an idempotent Request
Find exact records
- Request categories are
general,appointment,service,quote,billing,complaint, andother. - Request priorities are
low,normal, andhigh. Omitted values default togeneralandnormal. - Searches return a one-item array for an exact match and an empty array when no record matches.
Errors, retries, and idempotency
Errors use a stable error code and a human-readable error_description. Field validation errors may also include field. Retry safety differs by action, so do not treat every write as generically retryable.
Statuses and recovery
| Status | Common codes | Response |
|---|---|---|
400 | invalid_request, invalid_event, invalid_target | Correct the fields, event, or target URL. Do not retry the same request. |
401 | invalid_token | Refresh once. If refresh fails, reconnect the account. |
403 | insufficient_scope, front_desk_module_disabled, front_desk_dependency_disabled, front_desk_basic_not_included | For missing scopes, reauthorize. For module errors, check Front Desk availability and settings. |
404 | not_found, account_not_found | Stop the task and confirm the record and account still exist. |
409 | slot_taken, idempotency_key_reused, write_blocked | Change the input or resolve the conflict. Do not repeat the same write. |
503 | unavailable, front_desk_module_state_unavailable | Booking service or module state is unavailable. Retry with bounded backoff; contact support if it persists. |
Action-specific retry safety
- Create or Update Contact is safe to repeat with the same normalized phone. It reuses the contact and only fills blank fields.
- Create Request is safe to repeat within the same OAuth grant with the same Deduplication Key, sent as sourceRecordId, and identical details. It returns 200 with replayed: true and Idempotency-Replayed: true. Different details with the same key return 409. After reconnecting, check whether the Request already exists before retrying: a new grant can create a duplicate.
- Create Booking has no general idempotency key. After an ambiguous timeout, use Find Booking with the exact name, date, and time before creating again.
- GET requests may be retried with bounded backoff after transient failures. Do not retry 400, 403, 404, or 409 without changing the state or input.
Version, revocation, and support
This reference covers Zapier integration version 1.0.1. Customers can revoke a connection from Connected Apps in the First AI Employee dashboard. Revocation stops authenticated requests and webhook fan-out for that grant.
Access boundaries
This surface does not expose a public /oauth/revoke endpoint. The customer revokes from the dashboard. When a grant is revoked, its tokens stop working and its subscriptions stop receiving events.
Test data
Trigger test endpoints return clearly labeled synthetic data only when no real records exist. The examples on this page are synthetic too.
Integration support: [email protected]