# Zapier integration with FreeAgentMaker

Use Zapier to trigger agent runs or send results to other apps.

**Builder:** **Open Zapier** / **Automate with Zapier** sends you to [Webhooks by Zapier on Zapier.com](https://zapier.com/apps/webhook/integrations) (not a separate “FreeAgentMaker” app page, which would 404 until a partner listing exists). Use **Copy run URL** in the same section and follow the steps below.

For prioritized founder workflows and rollout order, see **[ZAPIER-PRIORITY-FLOWS.md](./ZAPIER-PRIORITY-FLOWS.md)**.

## Social publishing (MCP → Zapier)

If your FreeAgentMaker server is configured with `ZAPIER_WEBHOOK_URL`, you can use the built-in **Zapier (recommended)** MCP server to publish social posts through Zapier with an approval-first workflow.

See **[ZAPIER-SOCIAL-PUBLISHER.md](./ZAPIER-SOCIAL-PUBLISHER.md)** for:

- The exact webhook **payload contract**
- A copy/paste Zapier **template description** (Paths by `toolName`)

## Run agent (action)

**Endpoint:** `POST https://your-freeagentmaker-domain.com/api/agents/:agentId/run`

**Auth:** Send one of:

- **Session:** Cookie from the browser after sign-in (not ideal for server Zaps).
- **API key:** Create an API key in the app (Model & settings → API keys). Send header: `X-API-Key: your_key`.

**Body (JSON):**

```json
{
  "input": "User message or task for the agent",
  "context": { "source": "zapier", "trigger": "optional" }
}
```

**Response:** `{ "reply": "…", "runId": "…" }`

## Founder starters (phase 1 + 2 + 3)

Use `GET /api/agents/:agentId/zapier/phase1-starters` to pull copy-ready templates for:

- **Inbound lead triage:** `POST /api/agents/:agentId/leads/triage`
- **Meeting follow-through autopilot:** `POST /api/agents/:agentId/meetings` then `POST /api/agents/:agentId/meetings/:meetingId/followthrough-draft`
- **Support ticket intelligence:** `POST /api/agents/:agentId/support/tickets/intelligence`
- **Content repurposing pipeline:** `POST /api/agents/:agentId/content/repurpose`
- **Daily founder briefing:** `POST /api/agents/:agentId/founder/daily-briefing`

All responses are draft-first payloads for approval-oriented workflows.

### Example Zap (webhook → FreeAgentMaker → Gmail)

1. **Trigger:** Webhooks by Zapier – Catch Hook. Copy the webhook URL.
2. **Action:** Webhooks by Zapier – POST.  
   URL: `https://your-app.com/api/agents/YOUR_AGENT_ID/run`  
   Payload type: JSON  
   Data: `{ "input": "{{trigger_body_message}}" }`  
   Add header: `X-API-Key: {{your_api_key}}`
3. **Action 2:** Gmail – Send Email, using `reply` from step 2.

### Example Zap (Google Form → Agent → Slack)

1. **Trigger:** Google Forms – New Response.
2. **Action:** Webhooks – POST to `https://your-app.com/api/agents/YOUR_AGENT_ID/run` with body `{ "input": "Form response: {{form_response}}" }`, header `X-API-Key: …`.
3. **Action:** Slack – Send Channel Message with `{{reply}}` from step 2.

## Run with workflow key (no user session)

For server-to-server Zaps you can use the **workflow trigger** instead of an API key:

1. In the app, enable webhook for the agent and copy the **Run URL** and **Key** (from Quick action “Enable webhook”).
2. **POST** to the Run URL with header `X-Workflow-Key: <key>` and body `{ "input": "…" }`.

Same response: `{ "reply", "runId" }`. Use this when you don’t want to manage API keys and the Zap runs in the background.

## Triggers (future)

A Zapier **trigger** could poll `GET /api/agents/:id/run-history` or use a “new run completed” webhook. Today you can:

- Use **Webhooks by Zapier** to receive the run-completion webhook (if you set “Notify URL when a run finishes” on the agent) and use that as a trigger in another Zap.

## Run-completion webhook payload (v2)

The server POSTs JSON to your Catch Hook (or any HTTPS URL configured on the agent). **`webhookProtocolVersion: 2`** is always present. Core fields: `runId`, `agentId`, `status` (`success` | `error`), `replySnippet`, `durationMs`, **`runReceipt`**. On **success** with tools, you may also see **`recoveryHints`** (array of short strings) and **`pendingActionsCount`**. On **`error`**, you get **`failureCategory`**, raw **`error`**, and a humanized **`recoveryHint`**.

Example (success, tools):

```json
{
  "webhookProtocolVersion": 2,
  "runId": "…",
  "agentId": "…",
  "status": "success",
  "replySnippet": "…",
  "durationMs": 4200,
  "runReceipt": "text=1; images=0; …",
  "recoveryHints": ["Check Google Calendar scope if free/busy failed."],
  "pendingActionsCount": 1
}
```

**Zapier Code (optional)** — normalize trigger output:

```javascript
const input = inputData.body || inputData;
return {
  runId: input.runId,
  agentId: input.agentId,
  status: input.status,
  receipt: input.runReceipt || "",
  hints: (input.recoveryHints || []).join(" | "),
  pending: input.pendingActionsCount || 0,
  operatorHint: input.recoveryHint || ""
};
```

When `WEBHOOK_SIGNATURE_SECRET` is set, verify header **`X-Webhook-Signature-256`** (HMAC-SHA256 of the raw body) as described in the root **README**.
