curl --request POST \
--url https://api.sand.etherfuse.com/organization/{organizationId}/verification \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"firstName": "Ana",
"lastName": "Ejemplo",
"dateOfBirth": "1990-01-01",
"taxId": "XAXX010101000",
"country": "MEX",
"address": {
"street": "Av. Reforma 100",
"city": "Ciudad de Mexico",
"region": "CDMX",
"postalCode": "06600",
"country": "MEX"
}
}
'const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
firstName: 'Ana',
lastName: 'Ejemplo',
dateOfBirth: '1990-01-01',
taxId: 'XAXX010101000',
country: 'MEX',
address: {
street: 'Av. Reforma 100',
city: 'Ciudad de Mexico',
region: 'CDMX',
postalCode: '06600',
country: 'MEX'
}
})
};
fetch('https://api.sand.etherfuse.com/organization/{organizationId}/verification', 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}/verification"
payload = {
"firstName": "Ana",
"lastName": "Ejemplo",
"dateOfBirth": "1990-01-01",
"taxId": "XAXX010101000",
"country": "MEX",
"address": {
"street": "Av. Reforma 100",
"city": "Ciudad de Mexico",
"region": "CDMX",
"postalCode": "06600",
"country": "MEX"
}
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "inProgress"
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/invalid-request",
"title": "Invalid request",
"status": 400,
"detail": "dateOfBirth must be a date in YYYY-MM-DD format; country 'MX' is not a recognized ISO 3166-1 alpha-3 country code (e.g. MEX); address.city is required",
"instance": "tag:etherfuse.com,2026-08-28:R2-70010/9b2f4c1e-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
}{
"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>"
]
}Submit verification data
First call in the KYC API flow. Nothing else is accepted before it: country is what routes the customer to their country’s requirements.
Answers 202, not 200. We validate the request before we answer and record it with the verification provider after. A 202 means accepted, not satisfied. Read the result from the kycUpdated webhook or GET /organization/{organizationId}/kyc?requirements=true.
Submitting again overwrites what was sent before, and never moves the customer’s review status on its own. Personal organizations only.
curl --request POST \
--url https://api.sand.etherfuse.com/organization/{organizationId}/verification \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"firstName": "Ana",
"lastName": "Ejemplo",
"dateOfBirth": "1990-01-01",
"taxId": "XAXX010101000",
"country": "MEX",
"address": {
"street": "Av. Reforma 100",
"city": "Ciudad de Mexico",
"region": "CDMX",
"postalCode": "06600",
"country": "MEX"
}
}
'const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
firstName: 'Ana',
lastName: 'Ejemplo',
dateOfBirth: '1990-01-01',
taxId: 'XAXX010101000',
country: 'MEX',
address: {
street: 'Av. Reforma 100',
city: 'Ciudad de Mexico',
region: 'CDMX',
postalCode: '06600',
country: 'MEX'
}
})
};
fetch('https://api.sand.etherfuse.com/organization/{organizationId}/verification', 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}/verification"
payload = {
"firstName": "Ana",
"lastName": "Ejemplo",
"dateOfBirth": "1990-01-01",
"taxId": "XAXX010101000",
"country": "MEX",
"address": {
"street": "Av. Reforma 100",
"city": "Ciudad de Mexico",
"region": "CDMX",
"postalCode": "06600",
"country": "MEX"
}
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "inProgress"
}{
"type": "https://docs.etherfuse.com/ramp/v2/errors/invalid-request",
"title": "Invalid request",
"status": 400,
"detail": "dateOfBirth must be a date in YYYY-MM-DD format; country 'MX' is not a recognized ISO 3166-1 alpha-3 country code (e.g. MEX); address.city is required",
"instance": "tag:etherfuse.com,2026-08-28:R2-70010/9b2f4c1e-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
}{
"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.
Body
Personal data a partner submits on the customer's behalf.
YYYY-MM-DD. Any other format is a 400.
"1990-01-01"
The customer's tax identification number. The RFC for a Mexican customer.
"XAXX010101000"
The customer's country, as an ISO 3166-1 alpha-3 code. Alpha-2 codes and country names are rejected. This is the one country field for the customer (there is no separate nationality), and its value routes them to their country's requirements.
"MEX"
The customer's residential address. Required, and it must match the identity document you upload; the provider cross-checks the two.
Show child attributes
Show child attributes
Response
Accepted and being applied. The customer's current verification status is returned.
Where the customer's verification stands after a write. status is the same value GET /organization/{organizationId}/kyc reports.
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