Webhooks
Webhooks let your server react to events from your OAuth app's users in real time — a user signs a file, authorizes your app, revokes a token, updates their profile — 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 a bearer token associated with your app. The app_id query parameter is optional if your token is already scoped to an app.
curl -X POST https://auth-api.flowsta.com/api/v1/webhooks \
-H "Authorization: Bearer <your-app-jwt>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/hooks/flowsta",
"events": ["sign.created", "sign.revoked"]
}'The response includes the secret used to HMAC-sign every payload. Store it securely — it is only returned on create.
{
"webhook": {
"id": "wh_...",
"url": "https://yourapp.com/hooks/flowsta",
"events": ["sign.created", "sign.revoked"],
"filters": {},
"secret": "a1b2c3...hex",
"created_at": "2026-04-13T10:00:00Z"
}
}2. Receive and verify the event
Flowsta sends a POST with Content-Type: application/json and two custom headers:
| Header | Value |
|---|---|
X-Flowsta-Event | The event type, e.g. sign.created |
X-Flowsta-Signature | Hex-encoded HMAC-SHA256 of the raw request body, keyed by your webhook secret |
Always verify X-Flowsta-Signature before trusting the payload. See Verification.
// 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. "sign.created"
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
| Event | When it fires |
|---|---|
sign.created | A user signs a file via your app |
sign.revoked | A previously created signature is revoked |
oauth.authorized | A user completes OAuth authorization against your app |
oauth.token.revoked | An OAuth token is revoked |
user.profile.updated | A user's profile fields change (e.g. display name) |
Full payload shapes are documented in Event Types. Additional events (2FA toggles, subscription changes) are defined but not yet firing.
Managing webhooks
GET /api/v1/webhooks?app_id=<uuid>— list webhooks for an appPUT /api/v1/webhooks/:id— updateurl,events,filters, or re-enable (active: true)DELETE /api/v1/webhooks/:id— delete
All endpoints are rate-limited to 30 requests per minute.
Tier limits
Webhooks are counted per organization, across all apps.
| Tier | Webhooks |
|---|---|
| Free | 0 (not available) |
| Spark | 10 |
| Pro | 100 |
| Enterprise | Unlimited |
Attempting to create an 11th webhook on Spark returns 402 Payment Required.