curl --request GET \
--url https://api.sand.etherfuse.com/organization/{organizationId}/kyc \
--header 'Authorization: <api-key>'const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://api.sand.etherfuse.com/organization/{organizationId}/kyc', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sand.etherfuse.com/organization/{organizationId}/kyc"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text){
"organizationId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"status": "inProgress",
"currentRejectionReason": null,
"selfies": [],
"documents": [],
"approvedAt": null,
"needsWork": false,
"userMessage": null,
"requirements": [
{
"type": "personalData",
"status": "satisfied",
"requiresLaunch": false
},
{
"type": "identityDocument",
"status": "pending",
"requiresLaunch": false
},
{
"type": "selfie",
"status": "pending",
"requiresLaunch": true
}
]
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/quote-expired",
"title": "Quote expired",
"status": 400,
"detail": "quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not exist",
"instance": "tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"errors": [
{
"pointer": "#/accountDetails/clabe",
"detail": "This field is required."
}
],
"required": [
"<string>"
],
"missing": [
"<string>"
]
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/quote-expired",
"title": "Quote expired",
"status": 400,
"detail": "quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not exist",
"instance": "tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"errors": [
{
"pointer": "#/accountDetails/clabe",
"detail": "This field is required."
}
],
"required": [
"<string>"
],
"missing": [
"<string>"
]
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/quote-expired",
"title": "Quote expired",
"status": 400,
"detail": "quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not exist",
"instance": "tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"errors": [
{
"pointer": "#/accountDetails/clabe",
"detail": "This field is required."
}
],
"required": [
"<string>"
],
"missing": [
"<string>"
]
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/quote-expired",
"title": "Quote expired",
"status": 400,
"detail": "quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not exist",
"instance": "tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"errors": [
{
"pointer": "#/accountDetails/clabe",
"detail": "This field is required."
}
],
"required": [
"<string>"
],
"missing": [
"<string>"
]
}Get KYC status
Returns the organization’s KYC status. The overall status uses the same logic as orders, so approved is the only value that lets the customer transact. 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 separates “I still owe data over the API” from “it is time to launch the customer”. It is opt-in because it calls the verification provider; without it the response leaves requirements out.
The breakdown covers personal verification only. Requesting it for a business organization returns 400 invalid-request; track a business with GET /organization/{organizationId}/kyb instead.
requirements is left out until the customer has been routed to their country’s requirements. 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: proofOfAddress appears only when the identity document carried no address, and customerAgreement appears last. Send only what is listed as pending or actionRequired; a requirement sent before it is listed is accepted and then refused in the background. Read the list again after every kycUpdated; no single response is the full list. See Requirements unlock in stages.
Prefer the webhook
Subscribe to kycUpdated to learn that something changed. Read this endpoint on demand, or after that webhook when you need to know what is outstanding. With ?requirements=true it calls the verification provider every time, so do not poll it tightly. See Tracking verification status.
curl --request GET \
--url https://api.sand.etherfuse.com/organization/{organizationId}/kyc \
--header 'Authorization: <api-key>'const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://api.sand.etherfuse.com/organization/{organizationId}/kyc', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sand.etherfuse.com/organization/{organizationId}/kyc"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text){
"organizationId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"status": "inProgress",
"currentRejectionReason": null,
"selfies": [],
"documents": [],
"approvedAt": null,
"needsWork": false,
"userMessage": null,
"requirements": [
{
"type": "personalData",
"status": "satisfied",
"requiresLaunch": false
},
{
"type": "identityDocument",
"status": "pending",
"requiresLaunch": false
},
{
"type": "selfie",
"status": "pending",
"requiresLaunch": true
}
]
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/quote-expired",
"title": "Quote expired",
"status": 400,
"detail": "quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not exist",
"instance": "tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"errors": [
{
"pointer": "#/accountDetails/clabe",
"detail": "This field is required."
}
],
"required": [
"<string>"
],
"missing": [
"<string>"
]
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/quote-expired",
"title": "Quote expired",
"status": 400,
"detail": "quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not exist",
"instance": "tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"errors": [
{
"pointer": "#/accountDetails/clabe",
"detail": "This field is required."
}
],
"required": [
"<string>"
],
"missing": [
"<string>"
]
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/quote-expired",
"title": "Quote expired",
"status": 400,
"detail": "quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not exist",
"instance": "tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"errors": [
{
"pointer": "#/accountDetails/clabe",
"detail": "This field is required."
}
],
"required": [
"<string>"
],
"missing": [
"<string>"
]
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/quote-expired",
"title": "Quote expired",
"status": 400,
"detail": "quote 5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b has expired or does not exist",
"instance": "tag:etherfuse.com,2026-08-28:R2-10120/0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"errors": [
{
"pointer": "#/accountDetails/clabe",
"detail": "This field is required."
}
],
"required": [
"<string>"
],
"missing": [
"<string>"
]
}Authorizations
API key sent in the Authorization header, with no Bearer prefix.
Path Parameters
The organization this call acts for: your API key's organization or one of its customer organizations. Any other id returns 404 not-found.
Query Parameters
Include the per-requirement requirements breakdown. Off by default. Personal organizations only; a business organization returns 400.
Response
The organization's KYC status.
notStarted: verification has not started.inProgress: the customer started but has not submitted everything.submitted: submitted and waiting for review.approved: cleared.denied: rejected, or a previous approval was revoked.
notStarted, inProgress, submitted, approved, denied Why the last review rejected the customer, when it did. Visible only to the partner that submitted the data.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
True when the customer has to correct something and resubmit.
What the customer has to fix, when needsWork is true.
What the customer's verification still needs, step by step. Present only with ?requirements=true, and only once the customer has been routed to their country's requirements.
Show child attributes
Show child attributes