Event Types
Every webhook payload has this envelope:
{
"event": "<event-type>",
"timestamp": 1739462400000,
"...": "event-specific fields"
}event- the event type string (e.g.oauth.authorized). Also sent in theX-Flowsta-EventHTTP header.timestamp- milliseconds since Unix epoch, generated at delivery time.
The event-specific fields are spread into the top level of the JSON body. Every event is delivered only to the webhooks of the app it belongs to.
sign.created
Fires when your app signs a file through POST /api/v1/sign-it/sign or POST /api/v1/sign-it/sign-batch with an OAuth access token for your app (sign scope). Delivered to your app's webhooks only.
It does not fire for signatures the user makes in their Vault - including the @flowsta/auth and @flowsta/holochain SDK paths that hand the signature to a running Vault. Those signatures are committed on the user's device and never pass through the signing endpoints.
{
"event": "sign.created",
"timestamp": 1739462400000,
"file_hash": "a1b2c3...64-char-hex",
"action_hash": "uhCkk...",
"signer": "uhCAk...",
"signed_at": 1739462399500,
"intent": "authorship"
}| Field | Type | Notes |
|---|---|---|
file_hash | string | SHA-256 of the signed file, lowercase hex |
action_hash | string | The Holochain action hash of this signature entry |
signer | string | Holochain agent public key of the user who signed |
signed_at | number | Milliseconds since epoch, when the sign action happened |
intent | string | undefined | Intent string when the request carried one (e.g. authorship). Absent for sign-batch signatures |
Optional filter: filters.file_hash on the webhook restricts delivery to one file hash (compared case-insensitively). It is the only filter that exists.
sign.revoked
Fires when your app revokes a signature through POST /api/v1/sign-it/revoke. Delivered to your app's webhooks only. Revocations made in the Vault raise no webhook.
{
"event": "sign.revoked",
"timestamp": 1739470000000,
"action_hash": "uhCkk...",
"revoker": "uhCAk...",
"reason": "uploaded by mistake"
}| Field | Type | Notes |
|---|---|---|
action_hash | string | Action hash of the signature being revoked |
revoker | string | Agent public key of the user revoking |
reason | string | null | Optional reason string supplied by the user |
oauth.authorized
Fires when a user grants consent to your app on the consent screen - the first authorization, or a later one that asks for new scopes. Repeat sign-ins that skip the consent screen (the user already authorized these scopes) issue a code without firing it.
{
"event": "oauth.authorized",
"timestamp": 1739462000000,
"user_id": "user-uuid-123",
"scopes": ["openid", "display_name", "sign"]
}| Field | Type | Notes |
|---|---|---|
user_id | string | Internal user identifier |
scopes | string[] | Granted OAuth scopes |
Scoped to the app the user authorized (delivered only to webhooks on that app).
oauth.token.revoked
Fires when a refresh token for your app is revoked through POST /oauth/revoke. Only refresh tokens can be revoked; a revoke call that names an access token, or a token that was already invalid, still answers 200 but fires nothing.
{
"event": "oauth.token.revoked",
"timestamp": 1739465000000,
"token_type": "refresh_token"
}| Field | Type | Notes |
|---|---|---|
token_type | string | The token_type_hint the revoking client sent, echoed back; refresh_token when it sent none. In practice only refresh tokens are revocable |
user.profile.updated
Fires when a user changes their display name (through the Vault or the flowsta.com dashboard). Delivered to every app that holds an unrevoked refresh token for that user.
{
"event": "user.profile.updated",
"timestamp": 1739468000000,
"user_id": "user-uuid-123",
"fields_changed": ["display_name"]
}| Field | Type | Notes |
|---|---|---|
user_id | string | Internal user identifier |
fields_changed | string[] | Names of the fields that changed - currently always ["display_name"] |
Reserved (not yet firing)
These event types are accepted by POST /api/v1/webhooks (and appear in GET /api/v1/webhooks/events), but no code fires them. Payload shapes will be documented when they do:
subscription.upgradedsubscription.downgradedsubscription.cancelleduser.2fa.enableduser.2fa.disabled
Subscribing today is safe - you simply won't receive deliveries until they ship.