Prerequisites
- An API key for the environment you’re integrating against. See Authentication.
- A webhook endpoint subscribed to
application.approvedandapplication.rejected. See Webhooks. - The customer’s primary country (ISO 3166-1 alpha-2 or alpha-3, e.g.
USorUSA).
Flow
- Discover the onboarding requirements for the customer’s country.
- Upload each required document and keep the returned
doc_...ids. - Submit the application with the collected fields and document ids.
- Listen for
application.approvedorapplication.rejected. - Fetch the new customer.
Step 1 — Discover requirements
Requirements are country-specific. Call the discovery endpoint to learn which fields and documents to collect. Never hardcode them.fields[] (the data to collect), documents[] (the document checklist), and individualRequirements[] (per-person rules). A control person is a beneficial owner or controlling person of the business — the individuals you list in ownership.persons[]; individualRequirements[] tells you how many each country requires and which role each must hold.
fields[].name is a dot-path. Render your collection UI from fields[], and validate against each field’s type, required, and constraints. See Requirements by Country for the full schema.
Country codes are normalized server-side. You can send alpha-2 (
US) or
alpha-3 (USA); the response always echoes alpha-3.Step 2 — Upload documents
Upload each document the requirements ask for. The endpoint is multipart with an optionalpurpose form field. Ordinary onboarding documents can omit it; identity attestations use purpose=kyc. Repeat once per file.
id. Customer-level documents (e.g. incorporation papers) go in the top-level documentIds[]; documents that belong to a specific person (e.g. their government ID) go in that person’s ownership.persons[].documentIds[].
Step 3 — Submit the application
Turn eachfields[].name dot-path into a nested object (businessInfo.taxId → businessInfo: { taxId }), attach the document ids, and POST to /v2/onboarding.
202 Accepted with the new application in processing. The customer does not exist yet. customerId is null until the application is approved.
Pass your own
clientReferenceId to correlate the application with a record in
your system. It is echoed back on the response and on every webhook for this
application.Step 4 — Listen for the result
When review completes, Conduit delivers one of two webhooks. Both include yourclientReferenceId.
application.approved — the customer is now active. customerId is populated.
application.rejected — no customer is created. reason explains why.
Step 5 — Fetch the customer
On approval, retrieve the customer with thecustomerId from the webhook.
Handling a rejection
A rejected application is terminal. No customer is created, andcustomerId stays null. The application.rejected webhook carries a human-readable reason when one is available. There is no per-field breakdown. The reason arrives on the webhook only, so persist it when you receive it.
Confirm an application’s status at any time. This helps if a webhook was missed:
status but not the rejection reason. Capture the reason from the webhook.
Correct and resubmit
A rejection does not block the business. A rejected application no longer counts as active. Once you’ve corrected the data, submit a fresh application for the same tax ID and beneficial owners. Submit it as a newPOST /v2/onboarding with:
- a new
Idempotency-Key— reusing the rejected submission’s key replays its original response instead of creating a new application. - the same
clientReferenceId— keeps every attempt correlated to one record in your system.
To abandon an application that is still in review, before any decision, call
POST /v2/applications/{applicationId}/cancel. Approved and rejected
applications are terminal and cannot be cancelled.