Interpret session results
Understand what a session's status and outcome mean, and what to do next
A session has two layers. Telling them apart is the key to using the Trust Platform correctly:
- Where the session got to: its
sessionStatus, one ofCREATED,RUNNING,COMPLETED,ABORTED,EXPIREDorERROR. This is the technical state of the flow. - What the business decision was: its
outcome, eitheracceptedorrejected. It is only set when the session reachedCOMPLETED. For every other status,outcomeisNO_OUTCOME.
So COMPLETED does not mean "approved". It means the flow finished, and the flow may have finished by rejecting the user. Your integration should branch on the outcome, not only on the status, and read the reason codes when the outcome is rejected.
This page puts the whole picture in one place: what each status means, which webhook fires, and what your backend should do next.
Decision matrix
sessionStatus | outcome | What happened | Webhook | Recommended action |
|---|---|---|---|---|
COMPLETED | accepted | The flow finished and the user passed | session.completed | Grant access. Fetch the data blocks for your records |
COMPLETED | rejected | The flow finished and the user was declined | session.completed | Read the reason code from the data blocks. Decide whether to retry or stop |
ABORTED | NO_OUTCOME | The user stopped, or rollback retries ran out | session.aborted | If the user returns, start a new session |
EXPIRED | NO_OUTCOME | The session lifetime was reached (default 24 h) | session.expired | Start a new session |
ERROR | NO_OUTCOME | A technical failure occurred in a step | session.error | Check lastStep.stepStatusDetails. Contact support with the eventId |
session.completed means the flow finished, not that the user passed. The accepted or rejected decision is in the outcome. The same applies to the mobile SDK: a completed result (FlowOutcome.completed on iOS, TrustPlatformResult.Completed on Android) only tells you that the flow ended. Always read the outcome before acting.
From webhook to action
When a session ends, IDnow notifies you with a webhook. Getting from that notification to a decision in your system takes five steps:
- Receive the webhook. The request body is a JWT, not plain JSON. Verify its signature and standard claims (
iss,aud,sub,exp,iat) before trusting anything inside it.audmust match the endpoint URL you configured, andsubis the event ID. See Webhook events. - Read the event. Decode the payload and look at the fields under
data, in particulareventName(session.completed,session.aborted,session.expiredorsession.error) andpayload.sessionStatus. - Check whether there is a decision to read. If
sessionStatusisCOMPLETED, the flow finished with a business outcome. For any other terminal status there is no outcome: use the decision matrix above. - Fetch the result. Call
GET /api/v1/{environment}/sessions/{sessionId}and readoutcome. If it isaccepted, act on the success. If it isrejected, you need the reason. See Get session results. - Read the reason and act. Fetch the session's data blocks with
GET /api/v1/{environment}/sessions/{sessionId}/datablocks. Steps that make a decision record why: look forVerification.terminationReason.code(verification steps) orDigitalSignals.reasons[].code(signal steps), then decide whether to retry or stop. See Get data blocks and Rejection reasons.
Related pages
| Page | What it covers |
|---|---|
| Sessions | Every sessionStatus value and how sessions move between them |
| Rejection reasons | Where decision details live in the data blocks |
| Get session results | The session endpoint and its response |
| Get data blocks | The data blocks endpoint and its response |
| Webhook events | Event types, payload fields and JWT verification |
| Error codes | Errors returned by the API itself |
API error codes and verification reason codes are two different families. API error codes describe a failed API request. Reason codes describe why a verification step reached its decision, and are found in the data blocks.