curl --request GET \
--url https://api.sand.etherfuse.com/ramp/customer/{customer_id}/kyc \
--header 'Authorization: <api-key>'const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://api.sand.etherfuse.com/ramp/customer/{customer_id}/kyc', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sand.etherfuse.com/ramp/customer/{customer_id}/kyc"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text){
"approvedAt": "2026-05-01T16:00:00Z",
"currentRejectionReason": null,
"customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"documents": [],
"needsWork": false,
"selfies": [],
"status": "approved"
}Get KYC status
Returns the current KYC verification status for a customer, resolved from the customer’s account. The overall status matches the logic used for orders, so it stays consistent with whether the customer can transact, and approved is the only value that lets them. Submission details such as rejection reasons and timestamps are visible only to the partner that submitted the data.
The requirements breakdown
Pass ?requirements=true to add a requirements array describing, step by step, what this customer’s verification still needs. Each entry carries a type, a status, and a requiresLaunch flag, which is what separates “I still owe data over the API” from “it is time to launch the customer”. It is opt-in because resolving it costs upstream calls; omit the parameter and the response is unchanged.
The breakdown covers personal verification only. Requesting it for a business customer returns 400; track a business with GET /ramp/organization/{id}/kyb/status instead.
requirements is omitted entirely until the customer has been routed to their country’s requirements. Before that there is no country-specific requirement set to describe, and reporting the router’s own steps would read as “this customer is done” precisely when nothing has happened. After that the list holds the customer’s current stage, plus requirements already satisfied. It never lists a later stage’s requirements, so it grows as they advance: proof_of_address appears only when the identity document carried no address, and customer_agreement appears last. Send only what is listed as pending or action_required; a requirement sent before it is listed is accepted and then refused in the background. Re-read the list after every kyc_updated; no single response is the full list. See Requirements unlock in stages.
Prefer the webhook
kyc_updated is how you learn that something changed. Read this endpoint on demand, or in response to that webhook when you need to know what specifically is outstanding. With ?requirements=true it resolves against the verification provider on every call, so it is not built for tight polling. See Tracking verification status.
curl --request GET \
--url https://api.sand.etherfuse.com/ramp/customer/{customer_id}/kyc \
--header 'Authorization: <api-key>'const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://api.sand.etherfuse.com/ramp/customer/{customer_id}/kyc', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sand.etherfuse.com/ramp/customer/{customer_id}/kyc"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text){
"approvedAt": "2026-05-01T16:00:00Z",
"currentRejectionReason": null,
"customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"documents": [],
"needsWork": false,
"selfies": [],
"status": "approved"
}Authorizations
API key sent in the Authorization header.
Path Parameters
The customer (child org) ID. Must belong to the caller's organization or a direct child.
Query Parameters
Include the per-requirement requirements breakdown. Off by default. Personal customers only; a business customer returns 400.
Response
The org-level KYC status for the customer
KYC status response
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Unified KYC status for the customer's organization.
not_started: no KYC startedin_progress: the customer started the flow but hasn't submitted everythingsubmitted: submitted, awaiting review (manual or automated)approved: cleared; the customer can transactdenied: a rejected verdict, or a previously-approved customer whose approval was revoked (reason incurrentRejectionReason)
not_started, in_progress, submitted, approved, denied Whether KYC is marked on-chain. Only present for Solana wallets. For other blockchain types (Stellar, EVM), this field is omitted as on-chain marking doesn't apply.
What the customer's verification still needs, step by step. Present only when asked for with ?requirements=true and the customer has been routed to their country's requirements; omitted otherwise.
Show child attributes
Show child attributes