# Webhook API (/docs/reference/webhook-api)

Technical reference for the webhook trigger endpoint.



The webhook endpoint triggers a workflow execution from an external HTTP request.

Endpoint [#endpoint]

The full webhook URL is displayed in the Webhook Trigger node settings, in the **Parameters** pane. Copy it from there. The URL includes the workflow ID and a token generated for that trigger node.

Authentication [#authentication]

Authentication is via the `token` query parameter. This is a random secret generated per webhook trigger node. Treat it like a password - anyone with the URL can trigger your workflow.

Request [#request]

**Method**: POST only

**Headers**:

| Header                | Required    | Description                                 |
| --------------------- | ----------- | ------------------------------------------- |
| Content-Type          | Recommended | `application/json` for parsed body          |
| X-Webhook-Delivery-Id | No          | Unique delivery ID for replay protection    |
| X-GitHub-Delivery     | No          | GitHub-specific delivery ID (auto-detected) |

**Body**: Up to 100 KB. JSON is recommended. If `Content-Type: application/json` is set, the body is parsed as JSON. Other content types are accepted and stored as raw text in a `body` field.

```bash
curl -X POST "<your-webhook-url>" \
  -H "Content-Type: application/json" \
  -d '{"token": "SOL", "price": 150.23}'
```

Replace `<your-webhook-url>` with the URL from your Webhook Trigger node settings.

Response [#response]

**Success (200)**:

```json
{
  "success": true,
  "executionId": "k57abc123def..."
}
```

**Deduplicated (200)**:

```json
{
  "success": true,
  "executionId": "k57abc123def...",
  "deduplicated": true
}
```

**Errors**:

| Status | Cause                                                                                                                                               |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | Missing workflowId or token, invalid JSON, failed to read request body                                                                              |
| 403    | Invalid token, workflow not active (returns executionId), plan limit exceeded, webhook triggers not available on current plan                       |
| 404    | Workflow not found                                                                                                                                  |
| 413    | Request body too large (>100 KB)                                                                                                                    |
| 429    | Per-workflow rate limit exceeded. Response includes a `Retry-After` header (seconds) and a `retryAfter` field in the JSON body. Back off and retry. |

Replay protection [#replay-protection]

If the sender includes `X-Webhook-Delivery-Id` or `X-GitHub-Delivery`, Solaris AI Flow deduplicates requests scoped to the workflow + trigger node + delivery ID. Duplicate deliveries return 200 with `deduplicated: true`.

Generic senders without a delivery ID are not replay-protected. Every request creates a new execution.

Editor reruns [#editor-reruns]

The editor executions panel can run a webhook trigger again with the trigger's configured sample payload. It does not replay the original request body.

Activation required [#activation-required]

The webhook only fires after the workflow is activated from the editor toolbar. Inactive workflows return 403.

Plan limits [#plan-limits]

Webhook triggers are subject to plan-based quotas. <PlanName plan="free" /> plan: <PlanLimit plan="free" field="maxWebhookWorkflows" noun="active webhook workflow" />. <PlanName plan="pro" />/<PlanName plan="ultra" />: unlimited.

Next steps [#next-steps]

* [Webhook Trigger](/docs/triggers/webhook) - setup guide
* [Troubleshooting](/docs/reference/troubleshooting) - common webhook issues
