> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pyai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Zapier integration

> Trigger Zaps from completed calls with a signed, deduplicated envelope. Connect with a Catch Hook URL or the REST-hooks API; full event catalog with samples.

The Zapier integration turns every completed call into a trigger for your
whole Zapier account: a signed envelope with the event type, timestamp, and
the full call payload. Sheets rows, CRM updates, emails, queue messages — if
Zapier can do it, a completed call can start it.

## What you need

* A **Catch Hook URL** from Zapier: create a Zap, choose **Webhooks by
  Zapier → Catch Hook** as the trigger, and copy the
  `https://hooks.zapier.com/hooks/catch/...` URL.
* Or, for programmatic setup, a PyAI API key for the REST-hooks API (below).

## Connect (console)

1. In PyAI Console, open **Integrations** and find **Zapier** under
   Automation.
2. Click **Connect**, paste the Catch Hook URL, and pick your events.
3. Press **Test**. The sample envelope appears in Zapier's trigger step for
   field mapping.
4. Turn the Zap on. Every completed call fires it from then on.

## Connect (REST-hooks API)

Zapier (or your own tooling) can subscribe directly with any active PyAI key:

```bash theme={null}
curl -X POST https://api.pyai.com/v1/integrations/zapier/hooks \
  -H "Authorization: Bearer $PYAI_KEY" \
  -H "content-type: application/json" \
  -d '{"event": "recap.call.completed", "target_url": "https://hooks.zapier.com/hooks/catch/..."}'
```

* Subscribing is **idempotent** on `(org, event, target_url)`: re-subscribing
  refreshes in place and returns the same hook id.
* Unsubscribe: `DELETE /v1/integrations/zapier/hooks/{id}`.
* The event catalog with representative samples: `GET /v1/integrations/events`.

## The envelope

```json theme={null}
{
  "id": "webhook:integration:call_8fK2:idst_9fK2:integration.deliver:v1",
  "type": "recap.call.completed",
  "occurred_at": "2026-08-01T09:13:20.000Z",
  "data": { "call_id": "call_8fK2mQ9xR4", "status": "completed", "record": { } }
}
```

The `id` is deterministic per (call, hook) and matches the
`Idempotency-Key` header, so a retried delivery can never fire a Zap twice.
Every POST also carries `X-PyAI-Signature` (HMAC-SHA256 of `timestamp.body`
with your org webhook signing secret, minted in Console → Developers).

## Troubleshooting

* **Zap shows stale or no sample.** Press **Test** on the connection again;
  the sample envelope re-fires into the trigger step.
* **Duplicate rows downstream.** Check you did not connect the same Zap both
  via the console and the REST-hooks API as separate hooks; each is its own
  delivery. Delete one.
* **Zapier was down during calls.** Deliveries retry eight times over about
  twenty minutes, then surface as a visible error on the card with the
  payload preserved for replay.
