Events
The event log of a membership.
ErtisAuth records an event for most of what happens in a membership: sign-ins, token refreshes, user changes, role changes, sent webhooks and mails… Events serve three purposes:
- an audit log you can read and query through the API,
- the trigger of webhooks,
- the trigger of mail hooks.
The event object#
{
"_id": "66f1c0d2a4b5c6d7e8f90190",
"event_type": "UserUpdated",
"utilizer_id": "66f1c0d2a4b5c6d7e8f90124",
"document": {
"_id": "66f1c0d2a4b5c6d7e8f90127",
"username": "ada",
"lastname": "King",
"…": "…"
},
"prior": {
"_id": "66f1c0d2a4b5c6d7e8f90127",
"username": "ada",
"lastname": "Lovelace",
"…": "…"
},
"event_time": "2026-01-05T09:12:44Z",
"membership_id": "66f1c0d2a4b5c6d7e8f90123"
}| Field | Description |
|---|---|
event_type | What happened (see the list below). |
utilizer_id | The id of the user or application who caused the event, or system. |
document | The resource after the change. Empty for deletions. |
prior | The resource before the change, for updates and deletions. |
event_time | When it happened, in UTC. |
Password hashes and application secrets are never part of events.
Event types#
Tokens#
| Event | document |
|---|---|
TokenGenerated | user, and token with the metadata of the new token: token_type, expires_in, refresh_token_expires_in, created_at |
TokenRefreshed | user, and token with the metadata of the new token, as above. A refresh also records a TokenGenerated event. |
TokenVerified | token with token_type and, for Bearer tokens, is_refresh_token and expires_at (for Basic tokens, application_id) |
TokenRevoked | token with token_type and expire_time of the revoked access token. One event per revoked token pair. |
Token events never contain the tokens themselves, so the event log and webhook receivers can't be used to act as a user.
Users and user types#
| Event | When |
|---|---|
UserCreated | A user was created, including by a provider sign-up |
UserUpdated | A user was updated, activated or frozen |
UserDeleted | A user was deleted |
UserPasswordChanged | A password was changed, or set with a reset token |
UserPasswordReset | A password reset was requested |
UserTypeCreated, UserTypeUpdated, UserTypeDeleted | A user type changed |
Other resources#
| Events |
|---|
ApplicationCreated, ApplicationUpdated, ApplicationDeleted |
RoleCreated, RoleUpdated, RoleDeleted |
ProviderCreated, ProviderUpdated, ProviderDeleted |
WebhookCreated, WebhookUpdated, WebhookDeleted |
MailhookCreated, MailhookUpdated, MailhookDeleted |
TokenCodePolicyCreated, TokenCodePolicyUpdated, TokenCodePolicyDeleted |
Device code flow#
| Event | document |
|---|---|
TokenCodeApproved | user (who approved), and code with user_code, client_info (the device) and created_at |
TokenCodeDenied | the same, for a denied code |
The device code is never part of these events. See Device Code Flow.
Hook results#
| Event | document |
|---|---|
WebhookRequestSent | The result of a successful webhook call: request, response status and body, attempt number |
WebhookRequestFailed | The same for a failed attempt, with the error |
MailhookMailSent | The recipients |
MailhookMailFailed | The recipients and the error |
Note: don't create a webhook or mail hook on its own result events (
WebhookRequestSent, WebhookRequestFailed, MailhookMailSent, MailhookMailFailed): each call would trigger the next one.Endpoints#
All routes are under /memberships/{membershipId}.
| Method | Route | Description | Permission |
|---|---|---|---|
GET | /events/{id} | Get an event | events.read.{id} |
GET | /events | List events | events.read |
POST | /events/_query | Query events | events.read |
Events are read-only.
Examples#
The latest sign-ins of a user:
curl -X POST 'https://auth.example.com/memberships/<membership_id>/events/_query?limit=20&sort=event_time%20desc' \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{
"where": {
"event_type": "TokenGenerated",
"utilizer_id": "66f1c0d2a4b5c6d7e8f90127"
}
}'Who changed roles this month:
{
"where": {
"event_type": { "$in": [ "RoleCreated", "RoleUpdated", "RoleDeleted" ] },
"event_time": { "$gte": "2026-01-01T00:00:00Z" }
},
"select": { "event_type": 1, "utilizer_id": 1, "event_time": 1, "document.slug": 1 }
}Failed webhook calls:
{ "where": { "event_type": "WebhookRequestFailed" } }Note: events contain personal data (the user documents). Grant
events.read only to those who need the audit log, and plan a retention policy for the events collection.Found a mistake in the docs? Open an issue