Supported blockchains: The
blockchain field accepts solana, stellar, base, polygon, or monad. All examples use Solana, but the flow works identically across chains.Two types of auth are used throughout this flow:
- Steps 1–4 use your API key with the
customer_idin the URL path - Step 5 uses the presigned URL as the authentication token (no API key)
Flow
Generate Presigned URL — POST /ramp/onboarding-url
Show Details
Show Details
Even in the programmatic flow, you start by generating a presigned URL. This creates the customer organization and provides the auth token needed for agreement signing (Step 5). See POST /ramp/onboarding-url for the full schema.Response:
Copy
Ask AI
curl -X POST https://api.sand.etherfuse.com/ramp/onboarding-url \
-H "Authorization: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"customerId": "<customer_uuid>", # You generate this UUID
"bankAccountId": "<bank_account_uuid>", # You generate this UUID
"publicKey": "<wallet_public_key>",
"blockchain": "solana"
}'
Copy
Ask AI
{
"presigned_url": "https://devnet.etherfuse.com/onboarding?token=eyJhbGciOiJIUzI1NiIs..."
}
Save the presigned URL — you’ll need it for Steps 4 and 5. Valid for 15 minutes. The
customerId must be a new UUID, not your own organization’s ID.Submit Identity Data — POST /ramp/customer/{customer_uuid}/kyc
Show Details
Show Details
Submit the customer’s identity information via your API key. The
pubkey field is the wallet public key from Step 1 (not a UUID). See POST /ramp/customer//kyc for the full schema.Copy
Ask AI
curl -X POST https://api.sand.etherfuse.com/ramp/customer/<customer_uuid>/kyc \
-H "Authorization: <api_key>" \
-H "Content-Type: application/json" \
-d '{
"pubkey": "<wallet_public_key>",
"identity": {
"id": "<wallet_public_key>",
"email": "[email protected]",
"phoneNumber": "+521234567890",
"occupation": "Software Engineer",
"name": {
"givenName": "Juan",
"familyName": "Garcia"
},
"dateOfBirth": "1990-05-15",
"address": {
"street": "Av. Reforma 123",
"city": "Mexico City",
"region": "CDMX",
"postalCode": "06600",
"country": "MX"
},
"idNumbers": [
{ "value": "GAJU900515HDFRNN09", "type": "CURP" },
{ "value": "GAJU9005156V3", "type": "RFC" }
]
}
}'
Show Required fields reference
Show Required fields reference
When the customer signs their agreement (Step 5), all required fields must be present — either from this endpoint or via the
If any required field is missing at agreement signing, the request returns a
customerInfo field on the customer agreement.| Field | Required | Path in identity payload |
|---|---|---|
| First Name | Yes | name.givenName |
| Last Name | Yes | name.familyName |
| Phone Number | Yes | phoneNumber |
| Yes | email | |
| Occupation | Yes | occupation |
| Address | Yes | address (object: street, city, region, postalCode, country) |
| Date of Birth | No | dateOfBirth |
| CURP | Mexico only | idNumbers entry with type: "CURP" |
| RFC | Mexico only | idNumbers entry with type: "RFC" |
400 indicating which field was not provided.idNumbers is optional — defaults to empty. Only needed for Mexican customers (CURP and RFC). Non-Mexican customers can omit it entirely.Upload Documents — POST /ramp/customer/{customer_uuid}/kyc/documents
Show Details
Show Details
Upload government ID and selfie images as base64-encoded data URLs. See POST /ramp/customer//kyc/documents for the full schema.Upload ID Document (front and back):Upload Selfie:Requirements: JPEG or PNG, max 10MB per image. Labels:
Copy
Ask AI
{
"pubkey": "<wallet_public_key>",
"documentType": "document",
"images": [
{ "label": "id_front", "image": "data:image/jpeg;base64,/9j/4AAQ..." },
{ "label": "id_back", "image": "data:image/jpeg;base64,/9j/4AAQ..." }
]
}
Copy
Ask AI
{
"pubkey": "<wallet_public_key>",
"documentType": "selfie",
"images": [
{ "label": "selfie", "image": "data:image/jpeg;base64,/9j/4AAQ..." }
]
}
id_front, id_back (if applicable), selfie.In sandbox, you can submit any placeholder image — the content isn’t validated.
Register Bank Account — POST /ramp/customer/{customer_uuid}/bank-account
Show Details
Show Details
Register the customer’s Mexican bank account (CLABE) using your API key. The Business Account:
Valid country codes: GET /lookup/country-codes
account field accepts two variants — the system auto-detects Personal vs Business based on the fields present. See POST /ramp/customer//bank-account for the full schema.Personal Account:Copy
Ask AI
{
"account": {
"transactionId": "<uuid>",
"firstName": "Juan",
"paternalLastName": "Garcia",
"maternalLastName": "Lopez",
"birthDate": "19900515",
"birthCountryIsoCode": "MX",
"curp": "GAJU900515HDFRNN09",
"rfc": "GAJU9005156V3",
"clabe": "012345678901234567"
}
}
Copy
Ask AI
{
"account": {
"transactionId": "<uuid>",
"name": "Garcia Enterprises S.A. de C.V.",
"countryIsoCode": "MX",
"incorporatedDate": "20150101",
"rfc": "GEN150101ABC",
"clabe": "098765432109876543"
}
}
Show Bank account field reference
Show Bank account field reference
| Field | Personal | Business | Format |
|---|---|---|---|
transactionId | Required | Required | UUID (you generate) |
firstName | Required | — | |
paternalLastName | Required | — | |
maternalLastName | Required | — | |
birthDate | Required | — | YYYYMMDD |
birthCountryIsoCode | Required | — | ISO 3166-1 alpha-2 (e.g. MX) |
name | — | Required | Legal entity name |
incorporatedDate | — | Required | YYYYMMDD |
countryIsoCode | — | Required | ISO 3166-1 alpha-2 (e.g. MX) |
curp | Required | — | 18 characters |
rfc | Required | Required | Personal: 13 chars, Business: 12 chars |
clabe | Required | Required | Exactly 18 digits |
Alternative: Presigned URL auth — You can also register bank accounts via
POST /ramp/bank-account using the presigned URL instead of your API key. This is the path used by the Etherfuse hosted onboarding UI. See POST /ramp/bank-account for details.Accept Agreements
Show Details
Show Details
The customer must accept three agreements in order. Each uses the presigned URL as authentication. See the Agreements API reference for full schemas: electronic signature, terms and conditions, customer agreement.1. Electronic Signature Consent:2. Terms and Conditions:3. Customer Agreement:If any required identity fields are missing from Step 2, you can provide them here via The
User Authorization Required — These create legally binding obligations. The presigned URL authenticates the user and serves as their electronic signature authorization. Ensure the actual end user initiates or explicitly authorizes these requests.
Copy
Ask AI
POST /ramp/agreements/electronic-signature
{ "presignedUrl": "<presigned_url_from_step_1>" }
Copy
Ask AI
POST /ramp/agreements/terms-and-conditions
{ "presignedUrl": "<presigned_url_from_step_1>" }
Copy
Ask AI
POST /ramp/agreements/customer-agreement
{ "presignedUrl": "<presigned_url_from_step_1>" }
customerInfo:Copy
Ask AI
{
"presignedUrl": "<presigned_url_from_step_1>",
"customerInfo": {
"phone": "+521234567890",
"email": "[email protected]",
"occupation": "Software Engineer",
"additionalInfo": {
"curp": "GAJU900515HDFRNN09",
"rfc": "GAJU9005156V3"
}
}
}
customerInfo fields merge with whatever identity data is already on file. Only include what’s missing.In sandbox, the customer is auto-approved when the customer agreement is signed.
Monitor Status
Show Details
Show Details
Track onboarding progress via See Checking KYC Status for response details and status values.
kyc_updated webhooks or by polling GET /ramp/customer//kyc/:Copy
Ask AI
GET /ramp/customer/{customer_uuid}/kyc/{pubkey}
Show Bank account compliance
Show Bank account compliance
A bank account must be
compliant: true before you can create orders. Two paths to compliance:- Customer self-verifies — After submitting data via API, redirect the customer to the presigned URL. They complete identity verification (facial scan + ID matching) in the Etherfuse UI, which marks the bank account compliant immediately.
- Etherfuse admin reviews — Submit everything programmatically and wait for admins to review the uploaded documents. The customer’s selfie and government ID (Step 3) must be uploaded before the admin can complete the compliance check.
In sandbox, all bank accounts under an approved customer are considered compliant.
Show Data isolation
Show Data isolation
Partners can only access KYC data they submitted:
This prevents partners from accessing PII submitted by other partners or directly by users.
| Accessor | Data Visibility |
|---|---|
| Partner (via API key) | Only data where source_organization_id matches their org |
| Wallet Owner | All data for their wallet |
| Admin | All data |
Show Email suppression
Show Email suppression
When you submit KYC programmatically, Etherfuse suppresses standard KYC notification emails to the user. Your application is responsible for communicating status updates via webhook events.