/idv, but arrive with most of the work done.
Three requirements always remain the customer’s: confirming their email, the liveness selfie, and accepting the customer agreement. There is no API for those. For a flow where the customer only signs the agreement, see Sumsub shared token.
The order matters
Personal data comes first. A customer’s requirements are assigned from the country you send, and that assignment is asynchronous, so documents and answers sent before it lands are refused with a409. The kyc_updated webhook fires when it lands; send once step 2 returns a requirements list.
1
Submit personal data
2
Read what is being asked for
3
Upload the documents being asked for
4
Submit the questionnaire answers
5
Launch the customer for the rest
Email confirmation, the liveness selfie, and the customer agreement.
1. Submit personal data
202 Accepted
POST /ramp/customer/{customer_id}/verification.
Re-submitting overwrites what you sent before and is safe. It never moves the customer’s review status on its own.
2. Read what is being asked for
Triggered by thekyc_updated webhook rather than a timer, where you can: it fires when the customer is routed and the requirement list becomes available.
requiresLaunch: false is yours to send; true can only be done by the customer. When everything outstanding reads true, you have nothing left to send. Full vocabulary: Tracking verification status.
3. Upload documents
multipart/form-data, with files sent as files. Nothing is base64-wrapped into JSON.
tax_document here too, where the customer’s country requires one. See Country-specific requirements.
Every part, the accepted document types, and the file limits: POST /ramp/customer/{customer_id}/verification/documents.
4. Submit the questionnaire answers
Questions only. Documents, including a region’s tax document, go through step 3. Each submission names the questionnaire it answers intype:
Send
type even though there is one value. More questionnaires may be added, and a request naming one that doesn’t exist is rejected listing the ones that do, rather than being applied to the wrong questionnaire. The customer agreement is a questionnaire too and will never appear here: consent is collected from the customer in /idv.industry is a code you have to look up. GET /ramp/verification/occupations returns every accepted value as { code, label }. Submit the code: the label is display copy, can be reworded, and is not accepted. An unrecognized code is refused with a 400 naming it, so a typo fails at the request rather than leaving the requirement quietly outstanding.
5. Launch the customer
Launch into/idv exactly as in the hosted flow. The customer is shown only what’s left: email confirmation, the liveness selfie, and the customer agreement.