Concepts

Events

Complete reference of all events emitted by AuthPI for webhooks, audit logs, and integrations.

Last updated 2026-07-03

AuthPI emits events whenever something significant happens in your account—a user signs up, a session is created, an API key is rotated, and so on. These events power webhooks, audit logs, and analytics.

This page documents all event types, their payloads, and when they’re triggered.

Event Structure

All events follow the CloudEvents 1.0 specification with AuthPI-specific extensions.

{
  "spec": "1.0",
  "id": "evt_01HN8K2X...",
  "type": "user.created",
  "source": "identities",
  "timestamp": 1705330953123,
  "subject": {
    "account_id": "acc_xxx",
    "issuer_id": "i_xxx",
    "user_id": "usr_xxx"
  },
  "auth": {
    "type": "api_key",
    "id": "key_xxx",
    "issuer": "i_xxx"
  },
  "data": {
    "user_id": "usr_xxx",
    "username_type": "email"
  }
}

Fields

FieldTypeDescription
specstringCloudEvents spec version (always "1.0")
idstringUnique event identifier
typestringEvent type (see categories below)
sourcestringService that emitted the event
timestampnumberUnix timestamp in milliseconds
subjectobjectResource identifiers the event relates to
authobjectWho or what triggered the event
dataobjectEvent-specific payload

Subject Fields

The subject object contains identifiers for filtering and routing:

FieldPresent When
account_idAlways
issuer_idEvent relates to an issuer
user_idEvent relates to a user
agent_idEvent relates to an agent
org_idEvent relates to an organization
client_idEvent relates to a client
session_idEvent relates to a session
api_key_idEvent relates to an API key
token_idEvent relates to a personal token
webhook_idEvent relates to a webhook

Delivery via Webhooks

When an event is delivered to a webhook, it is wrapped in a standard CloudEvents 1.0 envelope that differs slightly from the structure above:

  • subject becomes a single string set to the most specific entity ID (e.g. the user ID for user.created, the org ID for organization.deleted), and all subject fields are merged into data alongside the event-specific payload.
  • timestamp (Unix ms) is delivered as time (ISO 8601), and spec as specversion.
  • source identifies the delivering webhook, and auth is not included.

See the webhooks guide for the full delivered payload format.

Auth Types

The auth.type field indicates what triggered the event:

TypeDescription
userEnd user action (via portal or authenticated session)
clientOAuth client action
api_keyCore API call with API key
tokenCore API call with personal token
walletx402 wallet-authenticated action
systemAutomated system action (expiration, scheduled tasks)
unauthenticatedPublic endpoint (signup, login)
unknownAuth context could not be determined

User Events

Events related to user accounts and identity management.

Events emitted during hosted portal flows (signup, login, MFA) carry additional flow context in data: flow_type ("portal_flow"), flow_id, ip_address, user_agent, and trace_id. The payload examples below show only the event-specific fields.

Lifecycle

EventDescription
user.createdNew user account created
user.updatedUser profile or settings updated
user.deletedUser account permanently deleted
user.blockedUser account blocked (too many failed logins or admin action)
user.unblockedUser account unblocked

user.created payload:

{
  "user_id": "usr_xxx",
  "username_type": "email"
}

For users created through a hosted portal signup or SSO just-in-time provisioning, the payload also includes signup attribution when available: method ("password" or "sso"), ip_address, user_agent, and — for portal signups — flow_id.

user.created fires whenever the user record is created, including signups gated behind manual approval (those additionally emit user.approval.requested, and activation is signaled by user.approval.approved).

Authentication

EventDescription
user.verification.succeededCredential verification succeeded
user.verification.failedCredential verification failed

MFA

EventDescription
user.mfa.factor-createdMFA factor enrolled (TOTP, backup codes, etc.)
user.mfa.verification.succeededMFA verification succeeded
user.mfa.verification.failedMFA verification failed

MFA factor removal and backup-code regeneration are delivered as verifier events — user.verifier.deleted and user.verifier.updated respectively (see Credentials below).

user.mfa.verification.succeeded payload:

{
  "verifier_type": "totp"
}

Credentials (Verifiers)

EventDescription
user.verifier.createdNew credential added (password, passkey, TOTP, etc.)
user.verifier.updatedCredential updated (currently fires when backup codes are regenerated)
user.verifier.deletedCredential removed
user.password.changedPassword changed
user.password.reset-requestedPassword reset email sent
user.password.resetPassword reset completed

user.verifier.created payload:

{
  "verifier_id": "ver_xxx",
  "verifier_type": "passkey"
}

For OAuth verifiers (social sign-in), the payload also includes provider (e.g. "github") and method_id (the issuer auth method, am_...).

Email Management

EventDescription
user.email.verifiedEmail address verified
user.email.changedEmail address changed
user.email.change-requestedEmail change initiated (pending confirmation)
EventDescription
user.login-link.requestedMagic link login requested
user.login-link.consumedMagic link used for authentication

Signup Approval

EventDescription
user.approval.requestedSignup requires manual approval — fires alongside user.created; the user starts in a pending state
user.approval.approvedPending user approved and activated
user.approval.rejectedPending user rejected and blocked

user.approval.requested payload:

{
  "user_id": "usr_xxx",
  "username_type": "email"
}

signup_reason (user-provided) and triggered_rule (the approval rule that matched) are included when set. Decisions carry user_id and decided_by (the deciding admin); rejections also include the reason shown to the user.

EventDescription
user.consent.grantedUser granted OAuth consent to a client
user.consent.revokedConsent revoked for one client or for all clients

user.consent.granted payload:

{
  "consent_id": "cg_xxx",
  "client_id": "c_xxx",
  "scopes": ["openid", "profile", "email"]
}

Single-client revocations carry client_id and scope: "single"; revoke-all carries revoked_count and scope: "all".

Trusted Devices

EventDescription
user.device.trustedDevice trusted (skips MFA challenges until expiry)
user.device.revokedTrusted device revoked (single device or all)

user.device.trusted payload:

{
  "device_id": "dev_xxx",
  "fingerprint": "5f4dcc3b5aa7...",
  "name": "MacBook Pro",
  "expires_at": 1708527753000
}

Single revocations carry device_id; revoke-all carries revoked_count and revoke_all: true.

SSO Linking

EventDescription
user.sso.provisionedNew user provisioned just-in-time through organization SSO
user.sso.linkedExisting user linked to an SSO identity by email match

Both carry the same payload:

{
  "org_id": "org_xxx",
  "provider_user_id": "24f80cc5-52a1-4a5b-8f3e-9d7c1b2a3f4e"
}

provider_user_id is the sub claim from the organization’s identity provider.


Session Events

Events related to user sessions.

EventDescription
session.createdNew session created and activated
session.updatedSession metadata updated
session.token-refreshedSession tokens refreshed
session.expiredSession expired (TTL or idle timeout)
session.terminatedSession terminated. data carries previous_status and a short reason string such as user_logout, security_event, session_limit_exceeded, or other.
session.compromisedSession flagged as potentially compromised

session.created payload:

{
  "client_id": "c_xxx"
}

The session ID is in subject.session_id. Sessions created through a hosted portal sign-in also carry session_id, device_trusted, portal_flow_type (login, signup, or password_reset), and the portal flow context fields (flow_id, ip_address, user_agent, trace_id).

session.compromised payload:

{
  "reason": "refresh_token_reuse"
}

reason is refresh_token_reuse or device_fingerprint_mismatch; the session ID is in subject.session_id.

This event triggers when AuthPI detects potential token theft, such as when a refresh token is used after it should have been rotated. All tokens for the session are immediately revoked.


Organization Events

Events related to organizations and multi-tenancy.

Organization Lifecycle

EventDescription
organization.createdOrganization created
organization.updatedOrganization settings updated
organization.deletedOrganization deleted
organization.suspendedOrganization suspended (also fires organization.updated)
organization.reactivatedSuspended organization reactivated (also fires organization.updated)

organization.created payload:

{
  "name": "Acme Corporation",
  "org_type": "business",
  "created_by": "usr_xxx"
}

organization.suspended payload:

{
  "status": "suspended",
  "previous_status": "active",
  "status_at": 1705935753000,
  "status_reason": "non-payment",
  "status_by": "usr_xxx"
}

When an organization is suspended, newly issued tokens (fresh logins, refreshes, /userinfo) stop carrying its claims. Use this event to revoke your own application sessions for the organization immediately, rather than waiting for access tokens to expire. status_reason and status_by are present only if they were set in the update.

Memberships

EventDescription
organization.membership.createdUser added to organization
organization.membership.updatedMembership scopes or settings updated
organization.membership.deletedUser removed from organization

organization.membership.created payload:

{
  "member_id": "usr_xxx",
  "scopes": ["member", "projects:read"],
  "groups": [],
  "user_title": "Developer"
}

member_id is a user (usr_...) or agent (agt_...) ID; the matching user_id or agent_id subject field is set accordingly.

Invitations

EventDescription
organization.invitation.createdInvitation sent
organization.invitation.acceptedInvitation accepted
organization.invitation.declinedInvitation declined
organization.invitation.deletedInvitation revoked (carries reason: "revoked"; expiry emits no event)

organization.invitation.created payload:

{
  "invite_id": "inv_xxx",
  "email_invited": "new.employee@example.com",
  "expires_at": 1705935753000
}

inviter ({ id?, name? }) is included when it was provided on the create request.

Groups

EventDescription
organization.group.createdGroup created
organization.group.updatedGroup updated (scope changes re-sync member permissions)
organization.group.deletedGroup deleted (memberships re-synced)

organization.group.created payload:

{
  "group_id": "grp_xxx",
  "name": "Engineering",
  "scopes": ["projects:write"]
}

Updates carry group_id and updated_fields (the list of changed fields); deletes carry group_id and name.

SSO Configuration

EventDescription
organization.sso.enabledSSO enabled for the organization
organization.sso.disabledSSO disabled
organization.sso.updatedSSO configuration changed while enabled (including secret rotation)
organization.sso.domain-createdSSO domain added, pending DNS verification
organization.sso.domain-verifiedSSO domain ownership verified via DNS TXT record
organization.sso.domain-deletedSSO domain removed

organization.sso.enabled carries protocol (e.g. "oidc"); organization.sso.updated carries updated_fields (a secret rotation reports ["client_secret"]); the domain events carry domain (normalized to lowercase). organization.sso.disabled has no payload.


Agent Events

Events related to agent identities (non-human principals).

EventDescription
agent.createdAgent created
agent.updatedAgent updated
agent.deletedAgent deleted
agent.verifier.addedAgent credential added
agent.verifier.removedAgent credential removed

agent.created payload:

{
  "name": "Support Triage Agent",
  "description": "Triages inbound support tickets",
  "model": "claude-sonnet-4-5",
  "provider": "anthropic"
}

The agent ID is in subject.agent_id. agent.updated carries the fields that changed; agent.deleted has no payload.

agent.verifier.added payload:

{
  "verifier_id": "v_xxx",
  "verifier_type": "wallet"
}

verifier_type is wallet or secret; agent.verifier.removed carries the same fields.


Client Events

Events related to OAuth clients (applications).

EventDescription
client.createdOAuth client registered
client.updatedClient configuration updated
client.deletedClient deleted
client.secret.rotatedClient secret rotated
client.blockedClient blocked
client.unblockedClient unblocked

client.created payload:

{
  "name": "My Web App",
  "description": null,
  "type": "internal",
  "confidential": true,
  "protocol": "oidc"
}

The client ID is in subject.client_id.

client.secret.rotated carries no event-specific payload (data is {}) — the client, issuer, and account IDs are in subject, and the event timestamp is the rotation time.

Machine Tokens

EventDescription
machine.token.issuedAccess token issued via the client_credentials flow

machine.token.issued payload:

{
  "subject_type": "client",
  "scope_count": 3
}

subject_type is client (M2M client) or agent; subject carries the matching client_id or agent_id. The event fires on token issuance only, not on each use.


API Key Events

Events related to API keys for programmatic access.

EventDescription
api-key.createdAPI key created
api-key.updatedAPI key settings updated
api-key.deletedAPI key revoked
api-key.blockedAPI key blocked
api-key.unblockedAPI key unblocked

api-key.created payload:

{
  "name": "Production API Key",
  "scopes": ["users:read", "users:write"]
}

The key, organization, issuer, and account IDs are in subject.


Personal Token Events

Events related to personal access tokens (user-owned).

EventDescription
user.personal-token.createdPersonal token created
user.personal-token.updatedPersonal token updated
user.personal-token.deletedPersonal token revoked

user.personal-token.created payload:

{
  "name": "CI/CD Token",
  "scopes": ["repos:read"]
}

The token and user IDs are in subject.token_id and subject.user_id.


Issuer Events

Events related to issuer configuration.

EventDescription
issuer.createdIssuer created
issuer.updatedIssuer configuration updated
issuer.deletedIssuer deleted
issuer.auth-method.createdAuth method added (OAuth provider, etc.)
issuer.auth-method.updatedAuth method configuration updated
issuer.auth-method.deletedAuth method removed

issuer.auth-method.created payload:

{
  "issuer_id": "i_xxx",
  "method_id": "am_xxx",
  "method_type": "oauth2",
  "name": "Google"
}

Account Events

Events related to your account: lifecycle, billing credits, and custom domains.

Account Lifecycle

EventDescription
account.createdAccount created
account.updatedAccount changed (profile, features, limits, billing, payment methods, domains, suspension)
account.deletedAccount deleted

The account.updated payload always carries account_id plus a field describing what changed — for example changes (the updated fields), organization_changes, domain_added / domain_removed / domain_verified, primary_domain, or status ("suspended" / "active").

Credits

EventDescription
account.credits.updatedCredits added (topup or bonus) or refunded
account.credits.depletedBalance reached zero — fires once per depletion cycle, reset by the next topup

account.credits.updated payload:

{
  "account_id": "acc_xxx",
  "transaction_type": "topup",
  "entry_id": "cle_xxx",
  "amount_μusd": 10000000,
  "balance_after_μusd": 12500000,
  "operation": null,
  "reference": "pi_3OaXXXX"
}

transaction_type is topup, bonus, or refund. Bonus entries add expires_at; refunds add related_entry_id (the charge being refunded).

account.credits.depleted payload:

{
  "account_id": "acc_xxx",
  "balance_μusd": -1200,
  "trigger_entry_id": "cle_xxx"
}

Custom Domains

EventDescription
account.domain.addedCustom domain added to the account
account.domain.removedDomain removed
account.domain.assignedVerified domain assigned to an issuer
account.domain.unassignedDomain unassigned from its issuer

Payloads carry account_id and host; assignment events add issuer_id, and reassignments include previous_issuer_id. Domain verification itself is reported through account.updated with domain_verified.


Webhook Events

Events related to webhook configuration (meta-events).

EventDescription
webhook.createdWebhook subscription created
webhook.updatedWebhook configuration updated
webhook.deletedWebhook deleted
webhook.pausedWebhook manually disabled or auto-paused after persistent delivery failures
webhook.resumedDisabled webhook reactivated

Email Events

Events related to email delivery.

EventDescription
email.sentEmail sent successfully
email.failedEmail delivery failed

Subscribing to Events

Via Webhooks

Configure webhooks to receive events in real-time:

curl -X POST https://api.authpi.com/v1/accounts/{account_id}/webhooks \
  -u "{key_id}:{key_secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "User Events",
    "url": "https://your-server.com/webhooks/authpi",
    "events": ["user.created", "user.deleted", "session.compromised"],
    "auth": {
      "type": "signature",
      "signature_algorithm": "hmac-sha256"
    }
  }'

Event Filtering

Webhooks subscribe to exact event names (e.g. ["user.created", "user.deleted"]) — wildcard patterns are not supported. Unknown event names and internal-only event types (exception and api-key.verified, which never fan out to customer webhooks) are rejected when a webhook is created or updated. To narrow delivery to specific entities within your account, use subject filters.

Via API

Query historical events through the Core API:

curl "https://api.authpi.com/v1/accounts/{account_id}/events?type=user.created&limit=100" \
  -u "{key_id}:{key_secret}"

Filter parameters:

ParameterDescription
typeFilter by event type
sourceFilter by source service
user_idFilter by user
org_idFilter by organization
sinceEvents after timestamp
untilEvents before timestamp
limitMaximum results (default 50, max 1000)

Common Patterns

Sync Users to External Systems

Subscribe to user lifecycle events to keep external systems in sync:

{
  "events": ["user.created", "user.updated", "user.deleted"]
}

Security Monitoring

Monitor for security-relevant events:

{
  "events": [
    "user.verification.failed",
    "session.compromised",
    "user.blocked"
  ]
}

Audit Logging

Capture all administrative actions:

{
  "events": [
    "user.created",
    "user.updated",
    "user.deleted",
    "organization.created",
    "organization.updated",
    "organization.deleted",
    "client.created",
    "client.updated",
    "client.deleted",
    "issuer.updated"
  ]
}

Billing Integration

Track usage-relevant events:

{
  "events": [
    "user.created",
    "organization.created",
    "session.created"
  ]
}

Event Delivery

Events are delivered asynchronously with at-least-once semantics. This means:

  • Events may occasionally be delivered more than once
  • Your webhook handler should be idempotent (use the event id to deduplicate)
  • Events are typically delivered within seconds, but delays can occur during high load

For webhook retry behavior and failure handling, see the Webhooks guide.


Next Steps