For the complete documentation index, see llms.txt. This page is also available as Markdown.

Retry KYC

Handle a UR-initiated request for a user to redo part or all of their KYC. UR issues a retry directive, notifies you over webhook, and your platform claims a new session and drives the user through th

This page documents retry KYC (also called additional KYC): the flow UR uses when an already-onboarded user must resubmit some or all of their KYC data. Typical triggers are a compliance re-check on a live account, remediation after Fiat24 rejects an account, and an onboarding session that expired before it completed.

Retry KYC reuses the endpoints you already integrated for onboarding. What changes is the entry point: instead of calling /create-account, you claim a session that UR created for you, then run only the steps UR asks for.

Only UR operations staff can start a retry. Neither your platform nor the user can start one. POST /api/fma/v1/kyc/session/create fails with 30034 when no retry directive is pending for the user.

Retry KYC (this page)
Onboarding restart

Who starts it

UR operations only

Your platform

When

The user is already onboarded, and compliance wants data resubmitted

Onboarding failed, for example Sumsub returned RED

How you enter

POST /api/fma/v1/kyc/session/create, after fma.additional_kyc.required

POST /api/fma/v1/create-account again, with the same X-External-User-Id

Scope

Only the steps taskType names

The whole onboarding flow

1. Where this fits

Retry KYC works with the onboarding path your partnerId already uses. The dataChannel field in the webhook payload tells you which path applies to the user, and the steps you run come from that path:

dataChannel

Your onboarding path

Retry entry point for the user data

push

Data push to UR

POST /api/fma/v1/kyc/sync-data

sdk

POST /api/fma/v1/kyc/sumsub-access-token, then the Sumsub SDK

shared-token

POST /api/fma/v1/kyc/reuse-share-token, then POST /api/fma/v1/kyc/check

Two payload fields drive everything you do:

  • taskType tells you what the user must redo. Treat this field as authoritative.

  • fiat24Mode tells you how the session finishes, and specifically whether you call /kyc/submit.

What to read for your channel

Every section applies to every channel except the per-channel walkthroughs in section 5, which you can read selectively:

Your dataChannel

Read in section 5

Skip

push

Push channel

SDK channel, shared-token channel, and the two SDK-only notes about the access-token timeout and the SDK closing immediately

sdk

SDK channel

Push channel, shared-token channel

shared-token

Shared-token channel

Push channel, SDK channel

Read Webhooks alongside this page for the envelope, signature verification, and delivery contract that apply to both retry events.

2. Lifecycle

The diagram below traces one user end to end: first-time onboarding, registration with the banking partner, going live, and then a retry that UR operations issue later. Part A is onboarding, covered in depth on your channel's own page; part B is what this page documents.

Pick your channel. The retry phases are structurally identical across channels, and only the data collection step differs.

Part A is documented in full on Managed Custody SDK KYC.

No Sumsub SDK is involved on this channel. All data collection happens in your own UI, during onboarding and during a retry alike.

Part A is documented in full on Shared-token KYC reuse.

Registration with the banking partner happens once per user, in part A2. That is why most retries carry fiat24Mode: "ops_offline" and need no /kyc/submit. You see auto_register on a retry only when the user never completed that registration, for example when their first onboarding session expired before it reached submit. In that case the retry finishes registration and you receive fma.account.result with status: "activated" in addition to fma.additional_kyc.completed.

3. Webhooks

Retry KYC uses two events. Both belong to the partner-managed (FMA) event family and are sent only to partners on an FMA integration. Subscribe to both:

Event
UR sends it when
You act by

fma.additional_kyc.required

UR operations creates the directive

Claiming the session and guiding the user

fma.additional_kyc.completed

The user finishes the last step of the retry session

Recording completion; no further call is required

fma.additional_kyc.required

UR sends the following when the directive is created. Like every UR webhook, the retry events arrive in the standard {event, data, timestamp} envelope described in Webhooks:

The data fields carry the following meaning:

Field
Type
Meaning

directiveId

string

Identifies this retry request. Use it to correlate the completed event and for support tickets.

type

string

Always retry for this flow. Other values are reserved.

taskType

string

What the user must redo: full, passport, address_recheck, or redo_form_a. See section 5.

retryLevel

number

The retry category UR operations selected. Informational; taskType is the field you act on.

fiat24Mode

string

auto_register or ops_offline. Decides whether you call /kyc/submit. See section 6.

dataChannel

string

push, sdk, or shared-token. Matches your integration path.

externalUserId

string

Your user identifier, the same value you send in X-External-User-Id.

urId

number

The user URID, as a 64-bit integer.

retryOfSessionId

string

The session this retry replaces. That session is already sealed.

retryReason

string

Free text from UR operations. Safe to show to your support staff, not to the user.

requiredFields

array

Push channel only: the exact field paths to correct, for example registerRequest.address.street. Empty for other channels.

deadlineAt

number

Unix seconds, or 0 when no deadline is set. Informational only: UR does not expire the directive or the session when it passes, and no event fires at the deadline. Use it to prioritize your outreach to the user. The consequences of missing it are applied off-platform by compliance.

createdAt

number

Unix seconds when UR created the directive.

fma.additional_kyc.completed

UR sends the following when the retry session completes:

Two data fields differ from the required payload:

  • sessionId is the retry session that just completed, the same value /kyc/session/create returned to you.

  • retryOfSessionId points at the session that the completed session replaced, so the two events carry different values in this field. That difference is expected.

directiveId, taskType, retryLevel, and fiat24Mode carry the same values in both events, so you can match them without extra lookups.

Delivery and idempotency

Both events follow the standard delivery contract in Webhooks: at-least-once delivery, signed with EIP-191, retried with jittered exponential backoff over roughly 48 hours until your endpoint returns 2xx.

Two points specific to retries:

  • Dedupe on X-Webhook-Request-Id, as you do for every other UR event. That header is stable across the first delivery and every retry of the same message. Return 2xx only after you persist the event.

  • A resent directive does not produce a duplicate event. UR keys outbound emission on a business key derived from the directiveId for required and from the sessionId for completed, so if UR operations resend a directive after a delivery incident, you receive the original message rather than a second one. This is UR-side suppression; it is not a substitute for your own idempotency on X-Webhook-Request-Id.

4. Claim the new session

Call POST /api/fma/v1/kyc/session/create after you receive fma.additional_kyc.required. UR consumes the pending directive and creates the session that carries the reduced step list:

Send the partner signature headers you already use for every FMA endpoint. The body is optional: pass {"externalUserId": "your-user-id"} only when you cannot set the X-External-User-Id header.

Keep the following behaviors in mind:

  • Retrying the call is safe. If your first call succeeded but you lost the response, calling again returns the same sessionId as long as that session is still active. UR does not create a second session.

  • The previous session is gone. UR sealed it when operations created the directive. Calls that carry retryOfSessionId fail with 30006.

  • One pending directive per user. UR allows at most one pending directive for a user at a time.

  • Poll the state if you need it. GET /api/fma/v1/kyc/session/current returns sessionId, state, and dataChannel for the active session.

5. What your users must do

The taskType field maps to the following user actions:

taskType

The user redoes

full

Every data collection step, as in first-time onboarding

address_recheck

Address and location proof, then Form A

passport

Identity document scan and face liveness, then Form A

redo_form_a

Form A only; no data is recollected

The state values a retry session reports

GET /api/fma/v1/kyc/session/current reports the step the user is on. A retry session runs a reduced step list, so it reports step names that never appear during first-time onboarding:

Channel and taskType

state sequence

SDK, passport

IdOrPassportOrOtherIdInformationScan, IdAndLiveness, SignFormA

SDK, address_recheck

AddressProof, SignFormA

SDK, full

ConfirmYourCountryOfResidence, AddressProof, IdOrPassportOrOtherIdInformationScan, IdAndLiveness, SignFormA (questionnaire steps interleave)

SDK or shared-token, redo_form_a

SignFormA only

Push, full

PartnerDataIngestion, IdentityVerification, SignFormA, plus AwaitingPenny when the user takes the penny transfer path

Push, address_recheck or redo_form_a

SignFormA only. The session starts at SignFormA; you patch the data with /kyc/sync-data while the state stays there

Push channel

1

Claim the session

Call POST /api/fma/v1/kyc/session/create and store the returned sessionId.

2

Resubmit the data

Call POST /api/fma/v1/kyc/sync-data. When requiredFields is non-empty, send only those paths; UR merges them into the stored snapshot. When requiredFields is empty and taskType is full, send the complete payload, because UR starts the snapshot empty for a full retry.

3

Complete identity verification

Run the identity verification step your integration uses, either the penny transfer or the NFC document read. Only taskType: "full" includes this step on the push channel. When state goes straight to SignFormA, skip it.

4

Sign Form A

Call GET /api/fma/v1/kyc/form-a-info with the sessionId, present the text to the user, then call POST /api/fma/v1/kyc/sign-form with the sessionId and textHash.

5

Finish the session

Follow section 6: call POST /api/fma/v1/kyc/submit only when fiat24Mode is auto_register.

SDK channel

1

Claim the session

Call POST /api/fma/v1/kyc/session/create and store the returned sessionId.

2

Request a Sumsub access token

Call POST /api/fma/v1/kyc/sumsub-access-token with an empty body. Set your client timeout to 60 seconds or more: before UR issues the token, UR resets the specific Sumsub steps the retry targets and verifies that each reset took effect, which can take up to 30 seconds. If your call still times out, the server side usually finished; call again to get the token.

3

Launch the Sumsub SDK

Relay the token to your app and launch the SDK. The SDK stops at the step or steps the retry targets, not the whole workflow. The user submits that data and the SDK finishes.

4

Sign Form A

Call GET /api/fma/v1/kyc/form-a-info with the sessionId, then POST /api/fma/v1/kyc/sign-form with the sessionId and textHash. Poll GET /api/fma/v1/kyc/session/current until state is SignFormA if you need a trigger.

5

Finish the session

Follow section 6: call POST /api/fma/v1/kyc/submit only when fiat24Mode is auto_register.

If the SDK opens and closes immediately without asking the user for anything, stop and report it through your dedicated integration channel with the directiveId. A retry session must always ask the user for the targeted step. An immediate completion means the data was not recollected, and the result is not valid for the compliance review that triggered the retry.

Shared-token channel

1

Claim the session

Call POST /api/fma/v1/kyc/session/create and store the returned sessionId.

2

Have the user redo KYC in your Sumsub tenant

Run the steps that taskType names in your own workflow, then mint a fresh single-use share token scoped to UR's clientId. A token you minted for the earlier session is not valid for the retry session.

3

Hand off the share token

Call POST /api/fma/v1/kyc/reuse-share-token with the new sessionId and the fresh token, then read the verdict with POST /api/fma/v1/kyc/check.

4

Sign Form A

Call GET /api/fma/v1/kyc/form-a-info, then POST /api/fma/v1/kyc/sign-form.

5

Finish the session

Follow section 6: call POST /api/fma/v1/kyc/submit only when fiat24Mode is auto_register.

6. How the session finishes: fiat24Mode

fiat24Mode reflects whether the retry session includes the Fiat24 registration step. A user can register with Fiat24 exactly once in their lifetime, so UR includes that step only for a user who never completed it:

fiat24Mode

Registration step

Your last call

How the session ends

auto_register

Included

POST /api/fma/v1/kyc/submit

UR runs the registration, then sends fma.additional_kyc.completed

ops_offline

Not included

POST /api/fma/v1/kyc/sign-form

The session completes on its own after the last step, then UR sends fma.additional_kyc.completed. UR operations handles the Fiat24 side offline

7. Two fields named retryLevel

The webhook payload and GET /api/fma/v1/kyc/session/current both return a field named retryLevel, and the two values mean different things:

Source
Meaning
Example

fma.additional_kyc.required and .completed payload

The retry category UR operations selected

6 for a document rescan

GET /api/fma/v1/kyc/session/current response

How many sessions the user has had, where 0 is the first onboarding

2 for the user third session

Read the retry category from the webhook payload, and read taskType when you need to know what the user must do. Do not derive either one from session/current.

8. Integration checklist

Confirm the following before you handle production retries:

  • Your webhook endpoint subscribes to fma.additional_kyc.required and fma.additional_kyc.completed.

  • Your webhook handler is idempotent on X-Webhook-Request-Id and returns 2xx only after it persists the event.

  • Your client timeout for POST /api/fma/v1/kyc/sumsub-access-token is 60 seconds or more, on the SDK channel.

  • Your code branches on fiat24Mode and calls /kyc/submit only for auto_register.

  • Your code branches on taskType, and your support flow expects a liveness capture whenever taskType is passport.

  • Your code drops any sessionId you cached for the user when a retry directive arrives, and uses the sessionId from /kyc/session/create.

  • Your code treats deadlineAt as informational and does not block the user after it passes.

9. Error reference

The endpoints in this flow return HTTP 200 with a business code. The following codes are specific to retry KYC:

Code
Meaning
What to do

30034

No pending retry directive for this user

No retry is pending. Do not create a session speculatively; wait for fma.additional_kyc.required. Check that your signature headers identify the same partnerId and externalUserId as the webhook.

30006

sessionId not found

The session is sealed, or it belongs to another user or partner. Claim the retry session and use its sessionId.

30031

No active KYC session for this user

The user has no active session. Claim the retry session first.

30007

Session state does not allow this call

For /kyc/submit, this means the retry flow has no registration step, so the mode is ops_offline. Skip the submit; the session completes on its own.

20007

Form A cannot render because stored data is incomplete

On the push channel, resubmit the missing paths with /kyc/sync-data. On other channels, report the directiveId through your dedicated integration channel.

40003

A UR dependency is momentarily unavailable

Retry the call after a few seconds.

10. Glossary

Term
Definition

Retry directive

The record UR operations creates to request a retry. Identified by directiveId.

Retry session

The session UR creates when you call /kyc/session/create for a pending directive. Identified by sessionId.

taskType

The authoritative description of what the user must redo in this retry.

fiat24Mode

Whether the retry session includes Fiat24 registration, and therefore whether you call /kyc/submit.

Form A

The declaration text the user signs before UR can act on the KYC data.

Last updated