Onboard your customers: verify identity (KYC) with one hosted flow, then attach their wallet and bank account.
Onboard each of your customers by verifying their identity (KYC) and attaching their wallet and bank account. There is a single flow:
Create the customer’s organization via the API.
Launch them into Etherfuse’s hosted /idv flow, which collects their identity document, runs the identity/liveness check, and captures the required agreement signatures, all in one hosted step.
Register their wallet and bank account via the API, before or after /idv.
It works the same in sandbox as in production.
One flow, one hosted step. Identity verification and agreement signing both happen inside /idv. You no longer submit identity fields, upload ID images, or run a separate agreements launch over the API; those endpoints are deprecated. The partner’s job is: create the org, launch /idv, and attach a wallet and bank account.
What the customer does in /idv (production). Etherfuse verifies identity with a government-issued ID plus a live selfie (face match + liveness), and the customer signs the required agreements. There’s no single mandated document; any valid government ID works. Most customers are approved automatically; Etherfuse may review a submission before approving.In sandbox, the checks don’t actually run. See Completing /idv in sandbox.
1
Create the customer's organization (POST /ramp/organization)
Show Details
Create a personal organization for your customer. You generate the id. This UUID becomes the customer’s org id and is what you’ll reference everywhere else (quotes, orders, KYC status, and the /idv launch). Optionally include wallets and a bank_account to set everything up in one call. See POST /ramp/organization for the full schema.
userInfo is recommended and will eventually be required. When provided, Etherfuse pre-creates the user record so the customer’s sign-in during /idv attaches to the right user, and we can email them on status changes (KYC approved/rejected, bank account verified, etc.).
Partner fees: To set a default partner fee for this child org, add "partnerFeeDefaultBps": 100 (0–500 bps) to the request body. This fee layers on top of platform fees for all quotes under this org. See Fees.
2
Launch the customer into /idv
Show Details
Send the customer into the hosted /idv flow, where they complete identity verification and sign the required agreements in a single authenticated session. Mint a short-lived user JWT with scope: verification and sub = the org id you created in Step 1, then have the customer’s browser hand it to /auth/launch with target: /idv. See Identity verification for the flow, and JWT User Authentication for signing and launching.
The JWT sub MUST equal the org id from Step 1. This is what resolves the launch to the customer you pre-created. If the sub is anything else, the launch registers a brand-new person instead of verifying your customer, and the KYC won’t attach to their org.
Append &lang=es to the target (/idv?lang=es) to render the entire flow in Spanish. Omit it or pass lang=en for English. Pass an optional return_url on the launch to send the customer back to your app when they finish.
Camera access. The identity/liveness scan needs the camera. If you embed the launch in an iframe, set allow="camera *; microphone *" on the iframe element. The bare allow="camera" only grants the iframe’s own src origin, but the scan SDK uses the camera from a nested frame, so without the * the scan cannot start. A top-level tab or popup needs nothing extra.
3
Register the customer's wallet and bank account (via API)
Show Details
Attach the customer’s wallet and Mexican bank account (CLABE) with your API key, using the org id as the customer_id, either in the create-org call (Step 1) or afterwards. Register a wallet with POST /ramp/customer/{customer_id}/wallet for each blockchain the customer will transact on (solana, stellar, base, polygon, monad); it becomes order-eligible once the customer’s KYC is approved. Register the bank account (a Mexican CLABE) with POST /ramp/customer/{customer_id}/bank-account, shown below:
Treat production bank account registration as permanent. Mexican banking regulations make it extremely difficult to change or replace a bank account once it has been registered under a given RFC. Double-check the CLABE, RFC, and CURP before submitting in production. CLABEs with the 646 prefix are not supported. Use a CLABE from a different bank.
Sandbox bank auto-approval. Register with the placeholder RFC XEXX010101000 to skip SPEI provider registration and mark the account active immediately. Any other RFC in sandbox is treated as a real registration and won’t auto-approve. The placeholder is rejected in production. See the Sandbox Reference.
When KYC is approved a kyc_updated webhook fires (status: "approved", approved: true) and the customer’s wallet becomes order-eligible. See Checking KYC status for response details and status values.
In sandbox the identity checks don’t actually run, so you can complete /idv with fake data: upload any document images you like for the ID and selfie steps and the verification will pass. No real personal information is required.The one exception: Mexico. If the customer selects Mexico, they must upload a Constancia de Situación Fiscal (the SAT tax-status PDF) at the tax-document step, or the flow won’t pass. Any constancia works; it just needs to look like a valid one. Use this example constancia for testing, or any real constancia with any data in it.
The customer started the flow but hasn’t submitted everything
submitted
Submitted, awaiting review (manual or automated)
approved
Cleared; the customer can transact
denied
A rejected verdict, or a previously-approved customer whose approval was revoked
The same five values are published on the kyc_updated webhook’s status field. A denial (rejected verdict or revoked approval) surfaces as denied, with the reason in currentRejectionReason (and updateReason on the webhook). A needs-work flag surfaces as in_progress, with the detail in needsWork and userMessage.
If KYC is rejected, the updateReason in the webhook (or currentRejectionReason in the status response) explains why. To resubmit, launch the customer into /idv again (same scope: verification, sub = org id); they can correct the flagged information. The new attempt creates a fresh review; old rejected data remains for audit purposes.
Show Bank account status
A bank account must be active before you can create orders against it. That’s when the SPEI provider has accepted it and reports it ready. Check the status in the registration response or via GET /ramp/bank-accounts, and you’ll receive a bank_account_updated webhook when it changes, so you can react without polling.
In sandbox, register the bank account with the placeholder RFC XEXX010101000 to skip SPEI provider registration and mark it active immediately. Any other RFC goes through the SPEI provider’s sandbox as a real registration and will not auto-approve.
Show Webhooks
Register a webhook for kyc_updated events to receive status updates. See POST /ramp/webhook for setup and payload details.Approved: