Skip to content

Webhooks ​

Webhooks let your server react to events from your OAuth app's users in real time - a user authorizes your app, disconnects it, updates their display name, or your app signs a file through the REST signing endpoints - your endpoint gets an HTTP POST from Flowsta within seconds.

Webhooks are available on paid developer tiers only (Spark, Pro, Enterprise). Free-tier apps cannot register webhooks.

Quickstart ​

1. Register a webhook endpoint ​

Send a POST to /api/v1/webhooks with your developer session token (the bearer token dev.flowsta.com holds after you sign in) and the app_id of an app you own. A token that already carries an app (an app-scoped token) may omit app_id; any other token without it gets 403 app_required, and an app_id for an app you do not own gets 403 forbidden.

bash
curl -X POST "https://auth-api.flowsta.com/api/v1/webhooks?app_id=<app-uuid>" \
  -H "Authorization: Bearer <your-developer-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/hooks/flowsta",
    "events": ["oauth.authorized", "oauth.token.revoked"]
  }'

URL requirements: https:// only, on a public hostname. localhost, *.local, *.internal, private and link-local IP ranges, and IPv6 local addresses are rejected with 400 invalid_url. To test from a development machine, put a public tunnel in front of it.

The response is HTTP 201 with the webhook, a human-readable message, and the secret used to HMAC-sign every payload. Store the secret securely - it is only returned on create.

json
{
  "webhook": {
    "id": "3f9c2a4e-7b1d-4e8a-9c0f-5d6e7a8b9c0d",
    "url": "https://yourapp.com/hooks/flowsta",
    "events": ["oauth.authorized", "oauth.token.revoked"],
    "filters": {},
    "secret": "a1b2c3...64 hex characters",
    "created_at": "2026-04-13T10:00:00Z"
  },
  "message": "Webhook registered. Use the secret to verify payloads (HMAC-SHA256 of the body in X-Flowsta-Signature header)."
}

You can also add and delete webhooks on the app's page at dev.flowsta.com (OAuth apps only). Editing and re-enabling are API-only.

2. Receive and verify the event ​

Flowsta sends a POST with Content-Type: application/json and two custom headers:

HeaderValue
X-Flowsta-EventThe event type, e.g. oauth.authorized
X-Flowsta-SignatureHex-encoded HMAC-SHA256 of the raw request body, keyed by your webhook secret

Always verify X-Flowsta-Signature before trusting the payload. See Verification.

js
// Express example - see /webhooks/verification for full code
app.post('/hooks/flowsta', express.raw({ type: 'application/json' }), (req, res) => {
  const valid = verifyFlowstaSignature(req.body, req.header('X-Flowsta-Signature'), secret);
  if (!valid) return res.status(401).end();

  const event = JSON.parse(req.body.toString());
  console.log(event.event, event); // e.g. "oauth.authorized"
  res.status(200).end();
});

3. Respond quickly ​

Return a 2xx status within the 10-second delivery timeout. Non-2xx responses count as a delivery failure. See Delivery & Failures for the exact policy.

What you can subscribe to ​

Every event is delivered only to the webhooks of the app it belongs to.

EventWhen it fires
oauth.authorizedA user grants consent to your app on the consent screen (first authorization, or new scopes). Repeat sign-ins that skip the consent screen do not fire it
oauth.token.revokedA refresh token for your app is revoked through POST /oauth/revoke (a user disconnecting your app). Access tokens cannot be revoked, so nothing fires for them
user.profile.updatedA user changes their display name. Delivered to the apps that hold an unrevoked refresh token for that user
sign.createdYour app signs a file through POST /api/v1/sign-it/sign or /sign-batch with an OAuth token for your app. Signatures made in the user's Vault (the SDK's Vault path) raise no webhook
sign.revokedYour app revokes a signature through POST /api/v1/sign-it/revoke. Revocations made in the Vault raise no webhook

Full payload shapes are documented in Event Types. subscription.* and user.2fa.* event names are accepted by the API but nothing fires them today.

Managing webhooks ​

  • GET /api/v1/webhooks/events - the event catalog (public, no token)
  • GET /api/v1/webhooks?app_id=<uuid> - list webhooks for an app
  • PUT /api/v1/webhooks/:id - update url, events, filters, or re-enable (active: true)
  • DELETE /api/v1/webhooks/:id - delete

Creating a webhook (POST) is rate-limited to 30 requests per minute. The other management endpoints carry no rate limit.

Tier limits ​

Webhooks are counted per organization, across all apps.

TierWebhooks
Free0 (not available)
Spark10
Pro100
EnterpriseUnlimited

Creating a webhook on the Free tier returns 402 Payment Required with error: "tier_required"; an 11th webhook on Spark returns 402 with error: "limit_reached".

Documentation licensed under CC BY-SA 4.0.