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

# Webhooks

> Receive FloKit events in your backend, data warehouse, or Slack workflows.

<Note>
  The FloKit v1 REST API is in design-partner preview — endpoints and schemas may change before general availability. Contact your FloKit team for access.
</Note>

FloKit sends webhook payloads to your configured endpoint when key events occur — actions created, approved, or rolled back; guardrails triggered; payback reports updated; or integrations failing to sync.

## Setup

Go to **FloKit → Settings → Webhooks → Add endpoint**. Enter your HTTPS URL and select the event types you want to subscribe to.

***

## Webhook events

| Event                       | When it fires                                                           |
| --------------------------- | ----------------------------------------------------------------------- |
| `action.created`            | A new action enters the queue                                           |
| `action.ready_for_approval` | An action has passed all guardrail checks and is ready for human review |
| `action.approved`           | An action has been approved for execution                               |
| `action.executed`           | An action has been executed                                             |
| `action.rolled_back`        | An action has been rolled back                                          |
| `guardrail.triggered`       | A guardrail has blocked or flagged a proposed action                    |
| `report.payback_updated`    | Payback report data has been refreshed                                  |
| `integration.error`         | An integration failed to sync                                           |

***

## Payload format

All payloads follow the same envelope structure.

```json theme={null}
{
  "event": "action.ready_for_approval",
  "workspace_id": "ws_01hx4j7k9m2n3p5q",
  "occurred_at": "2024-03-15T14:22:00Z",
  "data": {
    "id": "act_01hx4j7k9m2n3p5q6r8s",
    "type": "budget_shift",
    "status": "ready",
    "title": "Shift 20% budget from TikTok Broad to Meta Search",
    "rationale": "Meta Search cohort reached payback in 16 days vs. TikTok Broad at 34 days.",
    "expected_impact": {
      "metric": "blended_roas_30d",
      "direction": "increase",
      "magnitude": 0.3
    },
    "created_at": "2024-03-15T06:00:00Z"
  }
}
```

| Field          | Type   | Description                                                     |
| -------------- | ------ | --------------------------------------------------------------- |
| `event`        | string | The webhook event name                                          |
| `workspace_id` | string | Your FloKit workspace identifier                                |
| `occurred_at`  | string | ISO 8601 timestamp of when the event occurred                   |
| `data`         | object | The relevant object — action, guardrail, integration, or report |

***

## Signature verification

FloKit signs every webhook request with HMAC-SHA256. Verify the signature before processing the payload.

**Header:** `FloKit-Signature: sha256=<hex_digest>`

The signing secret is available in **FloKit → Settings → Webhooks → your endpoint → Signing secret**.

```typescript theme={null}
import crypto from 'crypto';

function verifyWebhook(payload: string, signature: string, secret: string): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return `sha256=${expected}` === signature;
}

// In your request handler (Express example):
app.post('/flokit/webhook', (req, res) => {
  const signature = req.headers['flokit-signature'] as string;
  const rawBody = req.rawBody; // requires raw body middleware

  if (!verifyWebhook(rawBody, signature, process.env.FLOKIT_WEBHOOK_SECRET!)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const payload = JSON.parse(rawBody);
  // handle payload.event ...

  res.status(200).json({ received: true });
});
```

Use the raw request body (before JSON parsing) when computing the HMAC. JSON serialization differences will cause signature mismatches.

***

## Retries

```mermaid theme={null}
sequenceDiagram
    participant FloKit
    participant Endpoint as Your endpoint
    FloKit->>Endpoint: POST payload + FloKit-Signature header
    alt 2xx response
        Endpoint-->>FloKit: 200 OK
        Note over FloKit: Delivery recorded
    else Non-2xx response or timeout
        Endpoint-->>FloKit: Error
        Note over FloKit: Retry with backoff:<br/>30s, 5m, 30m, 2h (5 attempts total)
        FloKit->>Endpoint: Retry delivery
        Note over FloKit: After 5 consecutive failures:<br/>endpoint disabled, integration.error fired
    end
```

FloKit retries failed webhook deliveries — any response that is not a `2xx` status — up to 5 times with exponential backoff:

| Attempt | Delay      |
| ------- | ---------- |
| 1       | Immediate  |
| 2       | 30 seconds |
| 3       | 5 minutes  |
| 4       | 30 minutes |
| 5       | 2 hours    |

After 5 consecutive failures, the endpoint is temporarily disabled and an `integration.error` event fires to your other active endpoints. Re-enable the endpoint in **FloKit → Settings → Webhooks**.

To avoid retries, return `200 OK` immediately and process the payload asynchronously.

***

## POST /v1/webhooks/test

Send a sample payload to your configured endpoint to verify your integration.

```bash theme={null}
curl -X POST https://YOUR-FLOKIT-API-HOST/v1/webhooks/test \
  -H "Authorization: Bearer $FLOKIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event": "action.ready_for_approval"}'
```

### Request body

<ParamField body="event" type="string" required>
  The webhook event type to simulate. FloKit sends a realistic sample payload for the specified event to your configured endpoint.
</ParamField>

### Response

```json theme={null}
{
  "status": "ok",
  "delivery_id": "del_01hx4j7k9m2n3p5q6r8s"
}
```

Use the `delivery_id` to look up delivery logs in **FloKit → Settings → Webhooks → your endpoint → Delivery history**.
