Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.powabase.ai/llms.txt

Use this file to discover all available pages before exploring further.

Webhooks let external systems (Stripe, GitHub, form submissions, internal services) trigger a deployed workflow over HTTP. The webhook ID and secret are minted when you arm a workflow for webhook execution — see the workflow guide for the full deploy + arm flow. The trigger endpoint is unauthenticated by design (no apikey / Authorization: Bearer {API_KEY} headers needed). Authentication is per-webhook: the secret token returned by the arm step must be presented either in an Authorization: Bearer <secret> header or as a ?token=<secret> query parameter.

Common Patterns

A workflow’s webhook lives in one of two states:
  • Deployed — the webhook is permanently active and accepts unlimited calls.
  • Armed for single use — the webhook accepts exactly one call within the arm window; after firing, you must re-arm. This is useful for one-shot integrations (testing, manual triggers) where you don’t want a long-lived endpoint.
The trigger endpoint behaves identically in both modes. The difference is only in how the workflow was prepared.

POST /api/webhooks/

Trigger a workflow. The request body becomes the workflow’s input variables. Returns the execution outcome synchronously (the workflow runs inline with a 5-minute timeout).
webhook_id
string
required
The webhook ID returned when the workflow was armed/deployed. Must be a valid UUID.
Authorization
string
Bearer <webhook_secret> — preferred over the query-param form.
token
string
Webhook secret. Use this when you can’t set headers (e.g., a webhook source that only supports a URL).
{
  "customer_email": "user@example.com",
  "amount_cents": 4900
}
{
  "execution_id": "exec-uuid",
  "status": "completed",
  "output": { "summary": "..." }
}
# Header auth (recommended)
response = requests.post(
    f"{BASE_URL}/api/webhooks/{webhook_id}",
    headers={"Authorization": f"Bearer {webhook_secret}", "Content-Type": "application/json"},
    json={"customer_email": "user@example.com"},
)

# Or query-param auth (when headers aren't an option)
response = requests.post(
    f"{BASE_URL}/api/webhooks/{webhook_id}?token={webhook_secret}",
    json={"customer_email": "user@example.com"},
)
The trigger endpoint executes the workflow inline and returns the final output. For long-running workflows that exceed the 5-minute synchronous limit, design the workflow to acknowledge the request quickly and continue work asynchronously (e.g. dispatch via a general_api block to a background processor).

Error Responses

Errors return {"error": "<message>", "error_code": "<UPPER_SNAKE_CODE>"}. The 401 responses additionally omit error_code (they’re a plain {"error": "Unauthorized"}).
Statuserror_codeDescription
400VALIDATION_ERRORwebhook_id is not a valid UUID
401Missing or incorrect webhook secret
403Webhook is not active (workflow not deployed and no live arm token)
404WORKFLOW_NOT_FOUNDNo workflow has a webhook block with this ID
500EXECUTION_FAILEDThe workflow ran but raised an error. The execution_id is included for debugging
504EXECUTION_TIMEOUTThe workflow exceeded the 5-minute synchronous limit