New Ory Agent Security is now live! Claim your complimentary test drive. Get Started!

Skip to main content

Live event streams

You can stream events (sign-ups, logins, machine-to-machine tokens issued, and many more) in real-time, live as they happen in your Ory Network project, to your own infrastructure. Pipe those events into your own data warehouse, data lake, or flavor of choice, and use them to power your own analytics, dashboards, data science, and more.

Live event streams are available for Ory Network enterprise contracts. Talk to your account manager or reach out directly.

Event shape​

Ory emits events for many different actions. All events abide by the same schema:

{
"name": string, // The unique name of the event (e.g., "IdentityCreated").
"version": string, // The numerical schema version of the event as a string.
"timestamp": string, // ISO 8601 formatted timestamp when the event occurred.
"projectId": string, // The ID of the Ory project the event belongs to.
"eventAttributes": map<string, string> // Additional event-specific attributes.
}

Example:

{
"name": "WebhookSucceeded",
"version": "1",
"timestamp": "2025-05-16 11:18:56",
"eventAttributes": {
"GeoLocationCity": "Munich",
"TraceID": "4bf92f3577b34da6a3ce929d0e0e4736",
"WebhookID": "",
"WebhookTriggerID": "18093e08-0f72-445f-aacb-151fc777a232"
}
}

Important:

  • Per the JSON specification, ordering of keys in objects is not guaranteed and should not be relied upon.
  • New keys can appear at any time, consumers should be designed to handle this.
  • The exact content in the eventAttributes field is not documented and not considered stable. That means that no backwards compatibility guarantees are made for them.

If you intend to write a consumer that needs a detailed schema and stability guarantees about the eventAttributes field, please open a support ticket.

Identity attributes​

The IdentityID and ExternalID attributes are exceptions to the rule above. Their names and meaning are stable:

  • IdentityID is the ID of the identity the event is about.
  • ExternalID is the identity's external ID. It's omitted when the identity doesn't have one. Use it to match events to user records in your own system without reading the identity from the Ory API.

Both attributes are set on IdentityCreated, IdentityUpdated, IdentityDeleted, LoginSucceeded, MFAChallengeIssued, MFASucceeded, RegistrationSucceeded, RecoverySucceeded, RecoveryInitiatedByAdmin, SettingsSucceeded, VerificationSucceeded, and all Session* events. LoginFailed, MFAFailed, RecoveryFailed, SettingsFailed, and VerificationFailed carry them only when Ory identified the identity before the flow failed, for example on a wrong password.

IdentityDeleted carries the external ID the identity had when it was deleted.

ExternalID is delivered to your event stream only. Ory doesn't keep it in its own analytics.

Correlating events​

All events that Ory emits while handling one request share the same TraceID attribute in eventAttributes. The value is the W3C Trace Context trace ID of that request: 32 lowercase hexadecimal characters. Use it to group the events of a single request, including events from different Ory services that took part in the same request, such as Ory Identities completing a login and Ory OAuth2 accepting it.

A browser flow usually spans several requests, and each request has its own TraceID. To follow a self-service flow or a session across requests, use the flow and session identifiers in eventAttributes.

The TraceID is absent when no trace ID is available and on events that summarize many requests, such as PermissionsChecked. Treat the key as optional.

Identifying the initiator​

Events that Ory emits while handling an authenticated admin API request say who made the request. This applies to the admin APIs of Ory Identities, Ory OAuth2, and Ory Permissions, whether you call them with a project API key or through the Ory Console, and to SCIM provisioning requests.

AttributeDescription
InitiatorTypeThe kind of initiator: api_key, console_user, or scim_client.
InitiatorIDThe ID of the API key, the ID of the Ory Console user, or the ID of the SCIM client.
InitiatorNameThe name of the API key. Only present when InitiatorType is api_key.

Example: an identity deleted with a project API key.

{
"name": "IdentityDeleted",
"version": "1",
"timestamp": "2026-10-01 11:18:56",
"eventAttributes": {
"InitiatorID": "874d556b-5be1-4478-8582-5b7607dbdde6",
"InitiatorName": "CI pipeline",
"InitiatorType": "api_key",
"IdentityID": "d48cadd7-7b4a-491e-b9a8-21446868812e"
}
}

InitiatorID identifies who performed the action. IdentityID identifies the identity the event is about. For console_user, InitiatorID is the ID of the user's Ory Console account, not of an identity in your project.

The initiator attributes are absent on events from self-service flows and other public APIs, where the end user acts on their own account, and on events from work that Ory starts itself, such as sending courier messages. Treat the keys as optional.

Security context​

An event stream can include the security context of the request behind each event. Use it to feed a security information and event management (SIEM) system. The option is off by default.

When the option is on, events caused by a request carry these keys in eventAttributes:

KeyValue
ClientIPThe IP address of the client that called Ory.
UserAgentThe User-Agent header of the request, cut off after 512 bytes.
RequestMethodThe HTTP method, for example POST.
RequestHostThe host name the client called, for example auth.example.com.
RequestPathThe URL path, for example /self-service/login. It never includes the query string.

Keep in mind:

  • ClientIP and RequestHost describe whoever called Ory. When your backend calls Ory on behalf of a user, they describe your backend, unless it forwards the user's IP address in the True-Client-IP header.
  • Requests that go through the Ory Proxy or Ory Tunnel report the oryapis.com host of your project.
  • Events that have no request behind them, such as events that summarize many requests, carry none of these keys.
  • Ory doesn't store these values in its analytics.

To turn the option on, select Include security context when you create or edit an event stream in the Ory Console, or set include_security_context to true through the Ory APIs. When you update a stream and omit the field, the stream keeps its current setting. You can turn the option off at any time.

Event names​

The following is a list of all events that are currently supported. The first column corresponds to the name field in an event. New event names may be added in the future, in which case this list will be updated accordingly. These names are also the values you can use in an event stream's event type filter.

Ory Identities​

EventDescription
IdentityCreatedA new identity (user or account) has been created.
IdentityDeletedAn identity has been deleted from the system.
IdentityUpdatedAn existing identity's details have been modified or updated. The IdentityActive attribute in the event indicates the state of the active flag, as many SCIM providers deactivate users by setting active=false.
JsonnetMappingFailedMapping claims or attributes from an OIDC or SAML IdP failed.
LoginFailedA user's login attempt has failed, possibly due to incorrect credentials. IdentityID is set when the attempt was matched to an identity. SelfServiceMethodUsed names the method that rejected the submission, and is empty when no method handled it, such as when the flow expired or the request did not address a method.
LoginInitiatedA new login flow has been created and basic validation passed.
LoginSucceededA user has logged into their account. SelfServiceMethodUsed names the method. SelfServiceSSOProviderUsed names the social sign-in or SAML provider. SelfServiceCodeChannelUsed is email or sms when a one-time code was used.
MFAChallengeIssuedA login flow asked a signed-in user for a second factor. MFAOfferedMethods lists the second factors the flow offers. A challenge with no MFASucceeded or MFAFailed for the same FlowID was never answered.
MFAFailedA submission to a second-factor login flow failed, for example because of a wrong code or an expired flow. Emitted together with LoginFailed.
MFASucceededA user completed a second-factor login flow. SelfServiceMethodUsed names the second factor. Emitted together with LoginSucceeded.
RecoveryFailedA password or account recovery attempt has failed.
RecoveryInitiatedByAdminAn admin has initiated account recovery on behalf of a user.
RecoverySucceededA password or account recovery attempt has succeeded.
RegistrationFailedA user's attempt to register has failed due to errors or invalid data.
RegistrationInitiatedA new registration flow has been created and basic validation passed.
RegistrationSucceededA user has registered and created an account. SelfServiceSSOProviderUsed names the social sign-in or SAML provider. SelfServiceCodeChannelUsed is email or sms when a one-time code was used.
SCIMGroupCreatedA new SCIM group has been created. Includes ScimClient attribute.
SCIMGroupDeletedA SCIM group has been deleted. This event will also trigger IdentityUpdated events for all affected users. Includes ScimClient attribute.
SCIMGroupUpdatedA SCIM group has been updated. Modifying members of a group will also emit IdentityUpdated events for all affected users. Includes ScimClient attribute.
SCIMProvisioningErrorAn error occurred during the SCIM provisioning process, check the SCIMError Detail attribute for more information.
SessionChangedA sessions details have been modified or updated.
SessionCheckedA check has been performed to verify the session's validity or status.
SessionIssuedA new session has been initiated for a user.
SessionLifespanExtendedThe duration of a session has been extended, allowing the user to remain authenticated longer.
SessionRequiredAALRaisedA trusted producer, such as a login after web hook, raised the authenticator assurance level the session must reach. The user is sent to two-factor login, or to enrollment if they have no second factor.
SessionRevokedA session has been explicitly terminated or invalidated.
SessionTokenizedAsJWTA session has been converted into a JSON Web Token (JWT).
SettingsFailedAn attempt to change account or session settings has failed.
SettingsSucceededAn attempt to change account or session settings has succeeded.
VerificationFailedA user's identity verification attempt has failed.
VerificationSucceededA user's identity verification has succeeded.
WebhookDeliveredA webhook has been sent to the configured endpoint for processing.
WebhookFailedA webhook delivery or processing has failed at the receiving endpoint.
WebhookSucceededA webhook has been processed and acknowledged by the receiving endpoint.
CourierMessageAbandonedA courier message has been abandoned.
CourierMessageDispatchedA courier message has been dispatched.
DeviceAuthnKeyRegisteredA device authentication key enrollment was attempted.
DeviceAuthnKeyRemovedA device authentication key removal was attempted.
DeviceAuthnKeyUsedA device authentication key was used for step-up authentication.
DeviceAuthnKeySecretRotatedThe PIN secret of a device authentication key was re-issued.
DeviceAuthnKeyLockedA device authentication key was disabled after too many wrong PIN attempts.

Ory OAuth2​

EventDescription
OAuth2LoginAcceptedA user's OAuth2 login has been accepted and the authentication process has succeeded.
OAuth2LoginRejectedA user's OAuth2 login attempt has been rejected due to invalid credentials or authorization issues.
OAuth2ConsentAcceptedThe user has accepted the consent screen, granting requested permissions to the OAuth2 client.
OAuth2ConsentRejectedThe user has rejected the consent screen, refusing to grant the requested permissions.
OAuth2ConsentRevokedThe user has revoked previously granted consent for an OAuth2 client, removing its permissions.
OAuth2ClientCreatedA new OAuth2 client (application) has been created and registered in the system.
OAuth2ClientDeletedAn OAuth2 client has been deleted from the system.
OAuth2ClientUpdatedAn existing OAuth2 client's details have been updated or modified.
OAuth2AccessTokenIssuedAn OAuth2 access token has been issued to a client or user.
OAuth2TokenExchangeErrorAn error occurred during the OAuth2 token exchange process, possibly due to invalid requests.
OAuth2AccessTokenInspectedAn OAuth2 access token has been inspected to verify its validity or check its claims.
OAuth2AccessTokenRevokedAn OAuth2 access token has been revoked, invalidating it for future use.
OAuth2RefreshTokenIssuedA refresh token has been issued, allowing the client to obtain a new access token.
OAuth2RefreshTokenReuseDetectedA refresh token was presented again after it had already been rotated. The OAuth2RefreshTokenReuseKind attribute says whether it was a replay or a concurrent rotation.
OIDCIdentityTokenIssuedAn OpenID Connect (OIDC) identity token has been issued to authenticate the user's identity.
OAuth2DeviceUserCodeAcceptedA user entered a valid user code in the OAuth2 device authorization flow.

Ory Permissions​

EventDescription
RelationtuplesCreatedA new relation tuple has been created, representing a relationship between entities.
RelationtuplesDeletedAn existing relation tuple has been deleted, removing the relationship between entities.
RelationtuplesChangedA relation tuple has been modified, indicating a change in the relationship between entities.
PermissionsExpandedPermissions have been expanded, likely increasing access or privileges for certain users or entities.
PermissionsCheckedA permission check has been performed to verify if access is allowed for a given action or resource.

Ory Network​

EventDescription
ProjectCreatedA project was created.
ProjectUpdatedA project was updated.
ProjectDeletedA project was deleted.
StripeSubscriptionUpdatedA Stripe subscription was updated.
APIKeyCreatedAn API key was created.
APIKeyDeletedAn API key was deleted.
CustomDomainCreatedA custom domain was created for a project.
CustomDomainDeletedA custom domain was deleted from a project.
CustomDomainUpdatedA custom domain was updated.
ProjectMemberInviteCreatedAn invitation for a project member was created.
ProjectMemberInviteAcceptedA project member invitation was accepted.
ProjectMemberInviteCancelledA project member invitation was canceled.
ProjectMemberInviteDeclinedA project member invitation was declined.
ProjectMemberInviteDeletedA project member invitation was deleted.
ProjectMemberRemovedA member was removed from a project.
OrganizationOnboardingPortalLinkCreatedAn onboarding link for an organization was created.
OrganizationOnboardingPortalLinkDeletedAn onboarding link for an organization was deleted.
OrganizationOnboardingPortalLinkUpdatedAn onboarding link for an organization was updated.
SAMLProviderCreatedA SAML provider was created.
SAMLProviderDeletedA SAML provider was deleted.
SAMLProviderUpdatedA SAML provider was updated.
OIDCProviderCreatedAn OIDC provider was created.
OIDCProviderDeletedAn OIDC provider was deleted.
OIDCProviderUpdatedAn OIDC provider was updated.
SCIMClientCreatedA SCIM client was created.
SCIMClientDeletedA SCIM client was deleted.
SCIMClientUpdatedA SCIM client was updated.

Delivery guarantees​

  1. Possible duplicates: There might be duplicates in the event stream. While rare (typically caused by retries because of network issues), consumers should be prepared to deal with them, for example by implementing deduplication logic.
  2. Best-effort delivery: Event delivery is best-effort. While most events are delivered reliably, events may be lost under adverse conditions (for example, system crashes during request processing). Delivery is not guaranteed to be "at-least-once".
  3. No delivery latency SLA: Ory does not offer a Service Level Agreement (SLA) for event delivery duration (the time between an event occurring and it appearing in your consumer or the Ory Console UI). However, typical delivery times are observed to be less than 5 seconds.
  4. No ordering guarantees: Events may arrive in any order, both within a request and across different requests.

Stronger guarantees can be implemented for your use case if needed, in this case please open a support ticket.

Configure event streams​

Is your workload not running on AWS or you don't want to use SNS? Reach out to discuss your requirements! Event streams can be implemented for any data warehouse, data lake, or equivalent solution.

Stream to HTTPS endpoint​

To stream events to an HTTPS endpoint, provide the URL of the endpoint when configuring the event stream:

  1. Go to your project in the Ory Console.

  2. Click Project settings in the top navigation bar.

  3. Click Event streams in the left sidebar.

  4. Click Create new Event Stream.

https://console.ory.com/projects/b3b748e5-7ddc-4860-a672-2436a877dc93/settings/event-streams

Event streams page with the Create new Event Stream button

  1. In the Create new Event Stream dialog:

    • Event Stream Type — Select HTTPS.

    • HTTPS endpoint — Enter the URL of your endpoint, for example https://example.com/my-event-endpoint.

    • Authentication — Optional. Select how Ory authenticates each delivery. For API key header, enter the Header name your endpoint expects, for example X-API-Key, and the API key. For Bearer token, enter the token. See Authenticate deliveries.

  2. Click Create. The new stream appears in the event streams table.

https://console.ory.com/projects/b3b748e5-7ddc-4860-a672-2436a877dc93/settings/event-streams

Create new Event Stream dialog with HTTPS type selected and API key header authentication

Unencrypted HTTP endpoints are not supported. Your endpoint must be able to handle POST requests with a JSON body, and respond with a 2xx status code to acknowledge successful processing of the event. HTTP redirects are not followed and are treated as delivery failures.

Your endpoint should support HTTP/2. HTTP/2 multiplexing lets Ory deliver many events concurrently over a single connection, which makes event delivery more efficient.

Authenticate deliveries​

Ory can authenticate each delivery to your endpoint. You configure authentication in the Ory Console when you create or edit a stream, or through the Ory API and the Ory SDKs. The Ory CLI sets only the endpoint URL. Pick the scheme your endpoint or API gateway expects:

  • Basic authentication: include the credentials in the endpoint URL, for example https://username:[email protected]/my-event-endpoint. Ory sends them in the Authorization header.
  • API key header: set https_auth_type to api_key, name the header in https_auth_header_name (for example x-api-key), and provide the key in https_auth_secret. Ory sends the key in that header on every delivery. The header name can be at most 128 bytes. It cannot be a header Ory sets itself, such as Content-Type, User-Agent, or any Ory-* or X-Ory-* header, or a connection-specific header that HTTP/2 does not allow, such as Connection, Keep-Alive, Upgrade, or TE. The key can be at most 4096 bytes. You can combine an API key header with credentials in the URL unless the header is Authorization.
  • Bearer token: set https_auth_type to bearer and provide the token, at most 4096 bytes, in https_auth_secret. Ory sends it as Authorization: Bearer <token>. Bearer authentication cannot be combined with credentials in the URL, because both use the Authorization header.

For example, to create a stream that authenticates with an API key:

POST /projects/{project_id}/eventstreams
{
"type": "https",
"https_endpoint": "https://example.com/my-event-endpoint",
"https_auth_type": "api_key",
"https_auth_header_name": "x-api-key",
"https_auth_secret": "<your API key>"
}

Ory never returns a secret: API responses show xxxxx in place of https_auth_secret, and mask the credentials in https_endpoint. When you update a stream, omit a secret to keep the stored value, send a new value to rotate it, or set https_auth_type to none to remove authentication.

A stored https_auth_secret is only sent to the endpoint and under the scheme it was set for. Changing https_endpoint, even only its path, or switching between api_key and bearer, requires https_auth_secret in the same update. Ory rejects the update otherwise, before it sends any request to the endpoint.

In the Ory Console, the Edit event stream dialog shows a stored API key or bearer token as an empty, locked field. Leave it as it is to keep the secret, or click Change next to it and enter a new value to rotate it. Selecting a different Authentication scheme or entering a new HTTPS endpoint unlocks the field, and you must enter the secret again. Select None to remove authentication.

Ory sends the connectivity test message with the same authentication as regular deliveries, so an endpoint that rejects unauthenticated requests still passes the check when you create or update the stream.

Stream to AWS SNS​

Configuring AWS SNS as an event stream destination is easy and requires no exchange of confidential information.

  1. Create an AWS SNS topic, and record its ARN (Amazon Resource Name), for example:
arn:aws:sns:us-east-1:123456789012:my-topic
  1. Create an AWS IAM role with publish permission to that topic. Sample IAM policy:
IAM role policy (replace <YOUR TOPIC ARN> with your topic ARN created above)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OryNetworkEventStreamPublish",
"Effect": "Allow",
"Action": ["sns:Publish"],
"Resource": ["<YOUR TOPIC ARN>"]
}
]
}

Record the ARN of the IAM role you created, for example:

arn:aws:iam::123456789012:role/ory-network-event-streamer
  1. Attach the following trust policy to the IAM role you created in step 2, replacing <YOUR PROJECT UUID> with your project ID:
Trust policy (replace <YOUR PROJECT UUID>)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "601538168777"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "<YOUR PROJECT UUID>"
}
}
}
]
}

This allows Ory Network to assume the role in your AWS account, and publish to your SNS topic.

  1. Configure the event stream, replacing the ARNs with those recorded in steps 1 and 2:

    a. Go to your project in the Ory Console.

    b. Click Project settings in the top navigation bar.

    c. Click Event streams in the left sidebar.

    d. Click Create new Event Stream.

    e. In the Create new Event Stream dialog:

    • Event Stream Type — Select AWS SNS.

    • Role ARN — Paste the IAM role ARN from step 2.

    • Topic ARN — Paste the SNS topic ARN from step 1.

    f. Click Create. The new stream appears in the event streams table.

    https://console.ory.com/projects/b3b748e5-7ddc-4860-a672-2436a877dc93/settings/event-streams

    Create new Event Stream dialog with AWS SNS type selected

  2. You are now ready to receive events in your AWS SNS topic!

tip

For development purposes, you can subscribe an email address to your topic, and receive events via email. For production use, subscribe AWS SQS, AWS Kinesis Data Firehose, or any other AWS service that can consume events from an SNS topic. Check the AWS documentation for ideas.

Filter events​

By default, an event stream delivers every event of your project. To deliver only some of them, set the stream's event_types to the events it should deliver. Each entry is either an exact name from the event names tables or a pattern that matches several of them. Events that match no entry are not delivered to that stream. Filtering one stream has no effect on your other event streams.

In a pattern, * matches any sequence of characters, and no other wildcard is supported. For example, Session* selects every session event, OAuth2* selects every OAuth2 event, and *Failed selects every failure event across all products.

Set the filter when you create a stream, or change it on an existing stream:

Updating an event stream is a partial update, so send only event_types to change the filter and keep every other setting:

curl --location --request PUT "https://api.console.ory.com/projects/${ORY_PROJECT_ID}/eventstreams/${EVENT_STREAM_ID}" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${WORKSPACE_API_KEY}" \
--data '{
"event_types": ["*Failed", "Session*", "OAuth2AccessTokenRevoked"]
}' | jq

The response contains the stored filter, sorted and without duplicates.

Every entry must match at least one event name from the tables above. A request with an unknown name, a pattern that matches no event, or a pattern that uses a wildcard other than * fails with a 400 Bad Request error that names the invalid entry. The combined length of all entries in a filter cannot exceed twice the combined length of all event names in the tables above.

  • To keep the current filter when you update a stream, for example to pause or resume it, omit event_types.
  • To remove the filter so that the stream delivers every event again, send an empty list: "event_types": [].
  • An exact name matches only that event. A stream filtered by names alone does not receive event types that Ory adds later until you add them to its filter.
  • A pattern also matches event types that Ory adds later when their names match. Those events are delivered and count toward your event stream usage like any other delivered event.
  • The filter is applied when an event is delivered. If you change the filter of a paused stream, the new filter also applies to the events that were buffered while it was paused.
  • Events that a filter excludes do not count toward your event stream usage.

Pause and resume event streams​

You can pause an event stream to temporarily stop delivering events to its destination without deleting the stream or its configuration. Pause a stream while its destination is undergoing maintenance, is misconfigured, or is being replaced, then resume it to continue delivery. Pausing one event stream has no effect on your other event streams.

Pause or resume a stream​

  1. Go to your project in the Ory Console.
  2. Click Project settings in the top navigation bar.
  3. Click Event streams in the left sidebar. The Status column shows whether each stream is Active or Paused.
  4. Open the ⋯ menu next to the stream and click Pause or Resume.

You can also change the status through the Ory APIs. Updating an event stream is a partial update: send only the status field (active or paused) and every other setting keeps its current value. This is the recommended way to pause or resume a stream, because resubmitting the destination is not required.

When you resume a stream, Ory first verifies that the destination is reachable, the same check that runs when you create or update a stream.

Create a stream as paused​

When you create a stream in the Ory Console, set Status to Paused to save it without starting delivery. This is useful when you want to configure a stream before its destination is ready. Resume it later from the stream's ⋯ menu.

What happens to events while a stream is paused​

In short: while a stream is paused Ory keeps receiving your project's events and buffers them for that stream for up to 7 days. Resume within that window and Ory delivers everything that was buffered while the stream was paused.

In more detail:

  • Pausing only stops delivery. Ory keeps collecting the events your project produces and holds them in an internal buffer dedicated to that stream. Nothing is delivered to your destination while the stream is paused.
  • Buffered events are retained for up to 7 days. When you resume the stream, Ory delivers the buffered backlog first and then continues with new events. This catch-up delivery follows the same guarantees as normal delivery: best-effort, possibly out of order, and possibly with duplicates.
  • Events that have been buffered for longer than 7 days are permanently discarded, whether or not you resume the stream. A stream that stays paused for more than 7 days keeps only the most recent 7 days of events; anything older is lost.
  • Buffered events go through the stream's event type filter when they are delivered, so a filter you change while the stream is paused applies to them too.

Pausing one stream does not affect your other event streams, and does not affect events available elsewhere in Ory, such as the project's activity view in the Ory Console.

warning

Pausing buffers events for up to 7 days. If a stream stays paused for longer, the oldest events are permanently lost. Resume the stream within 7 days to receive everything you missed.

Retry policy​

If your event stream destination is unavailable or misconfigured, Ory Network will retry sending the event multiple times with an exponential backoff between attempts.