Webhook event catalog
tryMellon delivers events to the webhook_url configured per application. All events share an envelope; only data varies.
Envelope
{
"id": "evt_…",
"type": "session.revoked",
"created_at": "2026-04-15T15:00:00.000Z",
"application_id": "uuid",
"tenant_id": "uuid",
"data": { "…event-specific…": "…" }
}
The full payload is signed — see Signature verification.
Event types
| Event | When emitted |
|---|---|
application.secret_rotated | Successful rotation of the application’s client_secret (manual or scheduled). |
session.revoked | A session was administratively revoked (admin action, security trigger, or DELETE /v1/sessions/:id). |
session.logout | The user logged out from their session (SDK logout() or POST /v1/sessions/:id/logout). |
user.locked | A user was hard-locked (10 failed auth attempts in 24h). |
credential.revoked | A passkey credential was revoked by the user or admin. |
identifier.linked | An email or wallet identifier is verified and linked to a user (F1). |
identifier.unlinked | An identifier is removed from a user (F1). |
recovery.enrollment.issued | A B2B recovery enrollment ticket was issued (your backend called POST /v1/users/:external_user_id/recovery/enroll). |
recovery.enrollment.completed | The user completed the recovery enrollment URL; all prior credentials were revoked atomically and a new passkey was registered. |
Subscription: today every application receives the full catalog. Per-event opt-in toggles are on the F0 follow-up roadmap.
Payloads
application.secret_rotated
{
"type": "application.secret_rotated",
"data": {
"rotated_by": "user_…",
"previous_secret_expires_at": "2026-04-15T15:14:00.000Z"
}
}
session.revoked
{
"type": "session.revoked",
"data": {
"session_id": "sess_…",
"user_id": "user_…",
"external_user_id": "your-user-123",
"revoked_by": "user_…",
"reason": "admin"
}
}
session.logout
{
"type": "session.logout",
"data": {
"session_id": "sess_…",
"user_id": "user_…",
"external_user_id": "your-user-123"
}
}
user.locked
{
"type": "user.locked",
"data": {
"user_id": "user_…",
"external_user_id": "your-user-123",
"locked_until": "2026-04-16T15:00:00.000Z",
"reason": "too_many_failed_attempts"
}
}
credential.revoked
{
"type": "credential.revoked",
"data": {
"credential_id": "cred_…",
"user_id": "user_…",
"external_user_id": "your-user-123",
"revoked_by": "user"
}
}
Identity linking events (F1)
identifier.linked
Emitted when a user successfully links and verifies an email or wallet address.
| Field | Type | Description |
|---|---|---|
user_id | string | User who linked the identifier |
identifier_id | string | Linked identifier ID |
type | "email" | "wallet" | "custom" | Identifier type |
value | string | The identifier value (email address or wallet address) |
identifier.unlinked
Emitted when an identifier is removed from a user.
| Field | Type | Description |
|---|---|---|
user_id | string | User who unlinked the identifier |
identifier_id | string | Unlinked identifier ID |
type | "email" | "wallet" | "custom" | Identifier type |
value | string | The identifier value |
B2B recovery events (F0)
Fired by the B2B recovery enrollment flow (ADR-045). See B2B account recovery.
recovery.enrollment.issued
Emitted when your backend successfully issues a recovery enrollment ticket via POST /v1/users/:external_user_id/recovery/enroll. The enrollment_url is not included — it carries a live ticket and is log-leakable; integrators reconstruct it locally.
| Field | Type | Description |
|---|---|---|
user_id | string | TryMellon user ID receiving recovery |
external_user_id | string | Your external user ID |
ticket_id | string | Single-use enrollment ticket ID |
context_hash | string | SHA-256 context hash bound to the ticket (64 hex) |
expires_at | string | ISO 8601 — ticket TTL (15 min – 7 days, configurable) |
issued_at | string | ISO 8601 — issuance timestamp |
recovery.enrollment.completed
Emitted when the user opens the enrollment URL and finishes passkey registration. All previously registered credentials for the user are revoked atomically before this event fires; a new session token is issued immediately after.
| Field | Type | Description |
|---|---|---|
user_id | string | TryMellon user ID |
ticket_id | string | The consumed enrollment ticket ID |
credential_id | string | ID of the newly registered passkey |
reason | "b2b_enrollment" | Fixed literal — disambiguates from self-service recovery paths |
completed_at | string | ISO 8601 — completion timestamp |
Delivery semantics
- At-least-once. Network blips can produce duplicates. Use the envelope
idas your idempotency key. - Retries. Failed deliveries (non-2xx) are retried with exponential backoff up to 24 hours.
- Manual retry.
POST /v1/webhooks/deliveries/:deliveryId/retry. - History.
GET /v1/webhooks/deliveries?application_id=…&event_type=….