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

# Zapier

# Zapier

Connect **Zapier** to **FinalSay** using the **FinalSay Zapier integration** (in-repo: [`finalsay-zapier/`](../../finalsay-zapier)), or using **custom HTTP** steps with the [Agent API](../api-reference/agent) directly.

## Official Zapier integration

The open-source app wraps the same **Agent API** as n8n: **Create Approval** and **Find Approval Result** (poll by `request_id`). Install it from the Zapier Platform after your team [publishes](https://docs.zapier.com/platform/publish/integration-publishing) the app, or use a **private invite** link from your integration owner.

* **Repository:** [`finalsay-zapier/README.md`](../../finalsay-zapier/README.md) — `npm run validate`, `zapier push`, and developer notes.
* **Authentication:** the published Zapier app targets the hosted API **`https://api.finalsay-hitl.com`** (no base URL field). You only save the **workspace API key** on the connection. **Choose an Agent on each action** (Create Approval, Find Approval Result); that lets one Zap use different agents. Agent options load via **`GET /v1/agents`**. The connection test calls the same endpoint to verify the key.

When an approval completes, FinalSay can **POST** the outcome to a URL you provide. In Zapier, that is usually a **Webhooks by Zapier** **Catch Hook** URL in the **Callback URL** field on **Create Approval** (or `callback.url` in raw JSON). Use a **second Zap** (trigger: Catch Hook) to process the body, or poll with **Find Approval Result**.

## Prerequisites

* [Credentials](../guide/credentials): **Agent ID**, **workspace API key**. The official Zapier app does not ask for a base URL (SaaS host is fixed). For **custom HTTP**, you still need your deployment **base URL**.
* A Zapier plan that supports the building blocks you need (e.g. **Webhooks by Zapier** for catch hooks, multi-step Zaps, and possibly **Code by Zapier** if you bypass the official app and craft raw HTTP).

## Custom HTTP (no Zapier app)

Every Agent API call must include:

| Header       | Value                  |
| ------------ | ---------------------- |
| `X-Agent-Id` | Your Agent ID          |
| `X-Api-Key`  | Your workspace API key |

Use an action that allows **custom headers** (often **Webhooks by Zapier** → **Custom Request**, or **Code by Zapier**).

### Create an approval

1. Trigger your Zap (schedule, form, another app, etc.).
2. Add **Webhooks by Zapier** → **POST** (or **Custom Request**) to `{BASE_URL}/v1/approvals`.
3. Set method **POST**, body type **JSON**, and paste a body that matches [POST /v1/approvals](../api-reference/agent#post-v1-approvals).
4. Add the headers above in the custom headers section.

Capture **`request_id`** from the create response for polling (present whether you set `request_id` in the body or not), or configure a callback (below).

### Get the result

#### Option A — Callback

1. Create a **Catch Hook** in **Webhooks by Zapier** and copy the hook URL.
2. In your **create approval** JSON, set `callback.url` to that hook URL.
3. Use a second Zap (trigger: **Catch Hook**) to process the POST body when the approval completes.

Zapier’s exact steps vary by interface version; look for “Custom Request” or raw JSON body support.

#### Option B — Polling

Zapier does not offer a built-in “wait until HTTP changes” loop. Practical patterns:

* Use **Delay** between repeated **GET** calls to `{BASE_URL}/v1/approvals/{requestId}/result` (use the **`request_id` from the create response** as `{requestId}`), **or**
* Use **Code by Zapier** to loop with delays (subject to Zapier execution time limits), **or**
* Use the official integration’s **Find Approval Result** action, **or**
* Prefer **callback** (Option A) for long human wait times.

Treat `status: "pending"` as “not done yet”; see [GET result](../api-reference/agent#get-v1-approvals-requestid-result).

## Limitations

* Zapier task limits and step timeouts apply—**callbacks** are usually more reliable than long polling for human-in-the-loop delays.
* Store API keys in Zapier **Secrets** or connection fields, not in plain text in shared Zaps.

## Related

* [Custom HTTP & scripts](./custom-http)
* [Automation limits & billing](../guide/automation-limits)
* [n8n](./n8n)
* [MCP](./mcp)
* [Agent API](../api-reference/agent)
