Verification

Verification flow: start, status, and token validation (Loom API v1).

Verification flow (v1)

Verification in Loom API v1 is a three-step flow: you start a session, the user completes identity verification via iDenfy's hosted UI, then you poll status or receive a webhook and optionally validate tokens.

Overview

  1. POST /verify/start — Create a session; receive verificationId and sessionUrl.
  2. GET /verify/status — Poll verification status by verificationId.
  3. POST /tokens/validate — Validate a JWT token to confirm the result in your backend.

All endpoints require the tenant API key in the x-tenant-api-key header.


POST /verify/start

Start a new verification session. Returns a verificationId and a sessionUrl to redirect or embed for the user.

Request

POST https://api.loomapi.com/verify/start

Headers

HeaderRequiredDescription
x-tenant-api-keyYesYour tenant API key
Content-TypeYesapplication/json

Body

The request body is optional. Accepted fields:

FieldTypeDescription
userAgentstring (optional)User agent string of the end user's browser
ipstring (optional)IP address of the end user

Unknown fields are rejected — the schema uses strict validation. Do not send metadata, callback_url, user_id, session_id, or similar; the API will return a 400.

{}

Or with optional fields:

{
  "userAgent": "Mozilla/5.0 ...",
  "ip": "203.0.113.42"
}

Response (201)

{
  "verificationId": "cjld2cjxh0000qzrmn831i7rn",
  "status": "started",
  "provider": "idenfy",
  "sessionUrl": "https://ui.idenfy.com/?authToken=...",
  "config": {
    "pollingIntervalMs": 3000,
    "tokenType": "jwt"
  }
}
FieldDescription
verificationIdUse this to poll status or correlate webhooks
statusAlways started on creation
providerAlways idenfy in v1
sessionUrlSend the user here to complete identity verification
config.pollingIntervalMsRecommended polling interval if not using webhooks
config.tokenTypeToken format issued on approval (jwt)

GET /verify/status

Check the status of a verification session.

Request

GET https://api.loomapi.com/verify/status?verificationId=cjld2cjxh0000qzrmn831i7rn

Headers

HeaderRequiredDescription
x-tenant-api-keyYesYour tenant API key

Query parameters

ParameterRequiredDescription
verificationIdYesThe verificationId from the start response

Response (200)

{
  "verificationId": "cjld2cjxh0000qzrmn831i7rn",
  "status": "approved",
  "confidence": 0.95,
  "createdAt": "2024-01-15T14:30:00.000Z",
  "completedAt": "2024-01-15T14:31:00.000Z"
}

Status values

StatusMeaning
pendingSession created, user has not started
startedUser has opened the iDenfy flow
submittedUser submitted documents; iDenfy processing
approvedVerification passed
deniedVerification failed — documents rejected
resubmissioniDenfy requested re-submission of documents
rejectedPermanently rejected

Note: When using iDenfy, POST /verify/complete is not available — iDenfy is webhook-only. Results arrive via the iDenfy callback to /verify/callback. Poll /verify/status or use outbound webhooks.


POST /tokens/validate

Validate a JWT token to confirm the user's verification result on your backend.

Request

POST https://api.loomapi.com/tokens/validate

Headers

HeaderRequiredDescription
x-tenant-api-keyYesYour tenant API key
Content-TypeYesapplication/json

Body

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response (200)

Valid token:

{ "valid": true, "over18": true, "reason": "OK" }

Invalid or expired token:

{ "valid": false, "over18": false, "reason": "TOKEN_EXPIRED" }
FieldTypeDescription
validbooleanWhether the token is valid
over18booleanWhether the verified person is 18 or over
reasonstringSee reason codes below

Reason codes

ReasonMeaning
OKToken is valid
TOKEN_EXPIREDToken has passed its expiry time
TOKEN_REVOKEDToken was explicitly revoked
TOKEN_NOT_FOUNDToken does not exist in the system
UNDERAGE_OR_UNKNOWNVerification completed but age could not be confirmed as 18+

Example: minimal flow

# 1. Start verification
RESP=$(curl -s -X POST https://api.loomapi.com/verify/start \
  -H "x-tenant-api-key: $LOOM_TENANT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}')

VERIFICATION_ID=$(echo "$RESP" | jq -r '.verificationId')
SESSION_URL=$(echo "$RESP" | jq -r '.sessionUrl')

echo "Send user to: $SESSION_URL"

# 2. Poll status (or use webhooks instead)
curl -s "https://api.loomapi.com/verify/status?verificationId=$VERIFICATION_ID" \
  -H "x-tenant-api-key: $LOOM_TENANT_API_KEY"

# 3. When you have a token from the session, validate it
curl -s -X POST https://api.loomapi.com/tokens/validate \
  -H "x-tenant-api-key: $LOOM_TENANT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"token": "YOUR_JWT_TOKEN"}'

Webhooks

Instead of polling, configure a webhook URL in the dashboard to receive verification.completed events. See Outbound Webhooks for payload format and signature verification.


Error responses

CodeMeaning
400Invalid request body (unknown fields, bad format)
401Invalid or missing x-tenant-api-key
404verificationId not found
429Rate limit exceeded — see Retry-After header

Full error format in Errors.


Next steps