User verification events

ID.me requires two bits of information to create a User Verification Event Stream:

  • Receiver URL: The public URL to which ID.me should stream events.
    Example: https://example.com/api/v1/events
  • Authentication Method: If protected by authentication, the details of the auth pattern. We support:
No auth
Basic auth
Bearer tokens
OAuth2

If your Receiver URL uses another form of authentication, please reach out to us at partnersupport@id.me.

Architecture

Audience setup User verification event flow No Yes Yes No Set up Receiver URL Subscribe to one or more applications Select event handles to receive User begins verification for anAudience application Verification events are emitted Is the Audience subscribed tothis application and eventhandle? Event is not delivered to the Audience Event proceeds through the pipeline Has the user consented to shareinformation with thisapplication? Event is delivered to theAudience Receiver URL Event is embargoed User later grants consent Embargoed events are released Released events are delivered tothe Receiver URL

Setup your audience

1

Set up your Receiver URL

2

Specify one or more applications you want your audience to subscribe to

3

Specify the event handles you want to receive

Process

1

A user begins the verification process for an Audience’s application

2

Events are emitted

3

If the Audience is subscribed to the event handle, the event proceeds through the pipeline

4

A check is performed to see if the user has consented to share information with your application

5

If consent has been granted by the user, the event is emitted to your Audience’s Receiver URL

6

If consent has not been granted by the user, the event is embargoed

7

After the user consents to sharing information with your application, embargoed events are released and delivered to your Receiver URL

Event schema

Each event is delivered as a JSON payload. A data envelope carries routing metadata about where the event came from, and the nested event object carries the event itself.

Payload shape
{
"data": {
"source": "...",
"sourcetype": "...",
"event": {
"event": "...",
"object": { ... }
}
}
}

Every event carries the same set of common fields. Events that relate to a specific ID.me resource also carry that resource, in full, on the object field.

FieldTypeDescription
sourcestringThe ID.me environment that emitted the event. idme:dev in the ID.me Labs sandbox, idme:prod in production.
sourcetypestringThe category of event being delivered. Always idme:auth for user verification events.
eventobjectThe event itself. See The event object.

The event object

FieldTypeDescriptionExample value
event_idstringEvent identifier2737913b-4f42-4140-a474-39720eaf9cd5
eventstringEvent type. See Event types.session.signin
uuidstringID.me unique user identifierc3850702f02f4f948cede41610c2a715
user_emailstringUser’s email addressxbzi.gqcv@gmail.com
application_namestringName of the application associated with the eventAuth Portal
ipaddressstringIP address associated with the event55.55.55.55
device_fingerprintstringDevice fingerprint associated with the eventlu2pFqAQyLIr0MqVpDEV
useragentstringOperating system, vendor, and/or version of the requesting user agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0
created_atstringDate and time the event was created, in ISO 8601 format2026-07-04T13:12:26.877091Z
eidnullable stringCustomer-supplied context echoed back on the payload
app_idnullable stringCustomer-supplied context echoed back on the payload
statenullable object or stringThe value the customer passed in the OAuth state parameter, echoed back exactly as supplied. A JSON object is delivered as a structured object, and a plain string is delivered as a string.
objectnullable objectThe ID.me resource this event relates to. See The object field.

eid, app_id, and state carry customer-supplied context. They are additive and nullable: each is always present on the payload, with a null value when the event carries no such context.

The object field

The object field carries the full resource an event relates to, so you do not need a follow-up API call to act on the event. Its shape varies by event type, and event is the discriminator: read event first, then parse object according to that event’s resource.

Every resource carries a type field naming itself, so a receiver can also branch on the resource directly without maintaining an event-to-resource lookup table.

Event familyobject.typeResource
Multifactor eventsauthenticatorThe multifactor authentication method involved in the event
Pre-verified eventsverification_statusWhat ID.me already knows about the user when they arrive, before multifactor authentication
All other eventsnullThese events carry no associated resource

object is nullable. Events with no associated resource deliver "object": null rather than omitting the field, so receivers can read the field unconditionally.

object does not change which events you receive. Subscription, consent, and embargo behave exactly as described in Process: an event carrying a resource is gated on user consent on the same terms as any other event, and is released with its resource intact once consent is granted.

Audience field mappings apply only to eid, app_id, and state. Fields inside object cannot be renamed.

Events with no resource

Events that describe an action rather than a resource deliver "object": null.

session.signin
{
"data": {
"source": "idme:dev",
"sourcetype": "idme:auth",
"event": {
"event_id": "4c7e2a19-6b58-42d3-8e91-05f7c3a1b6d2",
"event": "session.signin",
"uuid": "c3850702f02f4f948cede41610c2a715",
"user_email": "xbzi.gqcv@gmail.com",
"application_name": "Auth Portal",
"ipaddress": "55.55.55.55",
"device_fingerprint": "lu2pFqAQyLIr0MqVpDEV",
"useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
"created_at": "2026-07-04T13:12:26.877091Z",
"eid": null,
"app_id": null,
"state": null,
"object": null
}
}
}

Handling events

Because object is polymorphic, branch on event before reading it.

const { event, object } = payload.data.event;
switch (event) {
case "2fa.complete":
// object.type === "authenticator"
recordFactor(object.method);
break;
case "session.verification_status":
// object.type === "verification_status"
if (object.is_preverified_for_policy) skipOnboarding();
break;
default:
// object may be null
break;
}

New fields may be added to any resource, and new resource types may be introduced, without a breaking change. Ignore fields you do not recognize rather than rejecting the payload.

Event types

EventDescription
2fa.completeSuccessful completion of multifactor authentication. event.object is an authenticator.
2fa.deliveryThe user’s chosen multifactor authentication option is sent to the user’s device. event.object is an authenticator.
2fa.downloadUser downloaded the recovery code. event.object is an authenticator.
2fa.initiateMFA method is selected. event.object is an authenticator.
2fa.optionsMFA methods are presented to the user. event.object is an authenticator.
2fa.recovery.completeThe recovery code is successfully used for MFA. event.object is an authenticator.
2fa.recovery.confirmUser clicks link in email to confirm updating MFA settings. event.object is an authenticator.
2fa.recovery.deliveryEmail sent to the user after requesting to change their MFA settings when logging in. event.object is an authenticator.
2fa.recovery.failureUser’s information entered to update their MFA cannot be validated and fails. event.object is an authenticator.
2fa.responseThe user enters the MFA code during authentication. event.object is an authenticator.
2fa.revokeUser removes an MFA method from My Account. event.object is an authenticator.
account.agreementUser accepts Terms of Service and Privacy Policy
account.lockout.deliveryThe user is sent an email to help with account recovery after lockout due to too many bad password attempts
account.password.changeEmail notification to the user once they’ve reset their password in the “forgot password” flow
account.password.completePassword was successfully reset
account.password.deliveryUser submitted their username in the “forgot password” flow and receives an email to start reset password flow
account.password.failureReset password failed because the link clicked from the email to reset password is no longer valid
account.password.responseUser clicked link in the email taking them to the reset password page
appointment.startUser starts the supervised flow
consent.allowUser allowed consent to authorize the [integration] to access identity verification data.
consent.denyUser denied consent to authorize the [integration] to access identity verification data.
consent.revokeUser revoked consent for an integration to access their data from their My Account settings.
email.account.confirmThe newly added email address to My Account was confirmed (via link click in email)
email.account.deliveryThe “confirm email” is sent to newly added email to confirm ownership before officially adding the email to My Account
email.confirmation.completeEmail was successfully confirmed by clicking the prompt in the email or entering the 6 digit code into the screen
email.confirmation.deliveryAn email was sent to the registered email to confirm ownership of the email
email.createAn email is added in the user’s ID.me My Account
email.primaryEmail in My Account was made the primary email
email.removeEmail listed in My Account was removed
federation.confirmation.completeUser taps the CTA in their email to confirm connecting their account
federation.confirmation.deliveryUser signs in using a social login (LinkedIn, etc.) and taps “Connect” to connect their ID.me account using that email
federation.connectSocial login is added as an option from My Account
federation.removeSocial login is removed as an option from My Account
inperson.appointments.attempt_createdAn identity attempt is created for the user.
inperson.appointments.bookedThe appointment is scheduled for the selected timeslot at the selected location.
inperson.appointments.closedOther in-progress appointments for a user are closed when an appointment is marked as credentialed.
inperson.appointments.credentialedThe user identity verification is completed and accepted.
inperson.appointments.deniedAn ID.me document reviewer has rejected one or more identity documents.
inperson.appointments.documents_uploadedThe user’s identity documents have been uploaded.
inperson.appointments.expiredThe appointment expires if the user does not complete in-person verification within 30 days. This is followed by a request to Sterling to cancel the order.
inperson.appointments.failed_dupeThe user failed the dupe check.
inperson.appointments.in_store_verifiedThe user has submitted their information at a kiosk and it has been reviewed by the in person technician. The payload has been received by ID.me from Sterling.
inperson.appointments.info_reviewedThe user has confirmed their submitted PII and appointment details.
inperson.appointments.location_selectedThe users searches for a kiosk location by city or zip code and makes a selection.
inperson.appointments.order_canceledThe appointment will be cancelled if it has been replaced by a new appointment or expired.
inperson.appointments.order_createdThe appointment request is sent to Sterling, which returns a registration code that the user can enter or scan via a QR code at the kiosk. (Note: this is distinct from the previous request to book the timeslot at the selected location).
inperson.appointments.pending_reviewThe user is asked to review their PII and appointment details.
inperson.appointments.pii_collectedThe user has submitted their PII on the PII entry screen.
inperson.appointments.pii_mismatchThe user failed pii mismatch.
inperson.appointments.replacedThe appointment was replaced by another. This is followed by a request to Sterling to cancel the order.
inperson.appointments.review_requestedAn ID.me review of identity documents has been requested for the user.
inperson.user.already_verifiedA user attempted to create an appointment but was informed that they are already verified.
session.failedIncorrect password is provided when signing in
session.limitedUser is already signed in within a different browser
session.lockout.appliedAccount is locked after too many failed password attempts
session.lockout.expired72 hours has passed after the locked has been applied. This re-enables the ability for the user to attempt login
session.signinUser successfully signed in to their ID.me account
session.signoutUser logs out of their ID.me account
session.signupSuccessfully created a new ID.me account by inputting an email and password
session.suspendedUser attempts to take an action but cannot proceed due to account suspension
session.timeoutA user’s session times out due to inactivity
session.verification_statusEmitted after login or signup and before multifactor authentication: whether the user already holds the identity level the requesting policy requires. event.object is a verification status.
status.revocation.appliedUser successfully closed their ID.me account
status.revocation.requestedUser in My Account takes action to close their account
status.signal.appliedIndicates an account takeover (ATO) has been detected and the user is attempting to reclaim the account. The status allows the account to complete re-verification.
status.suspension.appliedA user’s account is suspended preventing the user from using their ID.me login
status.suspension.removedThe user’s account suspensions status is removed
supervised.appointments.attendedUser made an appointment, waiting for the appointment time, acknowledged they were present, then joined the video session.
supervised.appointments.canceledUser made an appointment, then either rescheduled or canceled the appointment before they were able to attend the appointment.
supervised.appointments.createdUser created an appointment.
supervised.appointments.missedUser created an appointment, left, but did not rejoin the waiting room around the appointment time.
supervised.appointments.schedule_link_clickedUser clicked on the create appointment link on the waiting page.
transaction.completeSAML or OAuth success or failure
verification.choice.dtr_fullUser chose “Video Chat Agent” on alternate options screen with DTR Lite not enabled.
verification.choice.dtr_liteUser chose “Video Chat Agent” on alternate options screen with DTR Lite enabled.
verification.choice.in_personUser chose In-Person Verification from alternate options screen.
verification.choice.unsupervisedUser chose “Self Service” on alternate options screen.
verification.completeSuccessfully completed verification.
verification.initiateUnsupervised identity verification method is selected (i.e. document is selected).
verification.liveness.checkupSuccessfully completed liveness after initial NIST IAL2 + Liveness verification.
verification.optionsVerification methods are presented to the user when DTR is enabled (i.e. Self-service or Verify on a video call).
verification.phone.authorization.approvedApproved activity and email address associated with the account when transitioning to mobile.
verification.phone.authorization.deniedDenied activity and email address associated with the account when transitioning to mobile.
verification.progressUser is shown the “Review Info” screen at the end of unsupervised verification.
verification.redirect.alternate_supervisedUser voluntarily selects to verify via the supervised flow rather than being routed to the supervised flow from unsupervised (i.e., Direct-to-TR) when TR Lite is not enabled for DTR.
verification.transition.documents.app_linksMobile app links step presented.
verification.transition.documents.awaiting_mobileWaiting on the user to finish capture on mobile.
verification.transition.documents.document_reviewUser is shown their captured document for review.
verification.transition.documents.mobile_handoff_errorMobile handoff failed.
verification.transition.documents.photo_uploadPhoto document upload step presented.
verification.transition.documents.qr_captureQR code capture step presented for mobile handoff.
verification.transition.documents.smart_uploadGuided (smart) document capture step presented.
verification.transition.documents.text_phoneStep to text a capture link to the user’s phone.
verification.transition.documents.uploadDocument upload step entered.
verification.transition.documents.upload_fileFile-based document upload step presented.