curl --request POST \
--url https://api.sand.etherfuse.com/organization \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"accountType": "personal",
"displayName": "Ana Ejemplo",
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"userInfo": {
"displayName": "Ana Ejemplo",
"email": "[email protected]"
}
}
'const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
accountType: 'personal',
displayName: 'Ana Ejemplo',
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
userInfo: {displayName: 'Ana Ejemplo', email: '[email protected]'}
})
};
fetch('https://api.sand.etherfuse.com/organization', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sand.etherfuse.com/organization"
payload = {
"accountType": "personal",
"displayName": "Ana Ejemplo",
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"userInfo": {
"displayName": "Ana Ejemplo",
"email": "[email protected]"
}
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"displayName": "Ana Ejemplo",
"accountType": "personal",
"approvedAt": null,
"createdAt": "2026-10-01T14:30:00Z",
"updatedAt": "2026-10-01T14:30:00Z"
}{
"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>"
]
}Create customer organization
Creates a customer organization under yours. It starts unapproved; it is approved once its KYC or KYB is. Register its bank accounts and wallets afterwards with Register payment account.
All fields are optional, so {} creates a bare personal organization. If id is already in use the request returns 409 conflict.
Account types
personal: an individual who completes KYC. SenduserInfoso we can email them about their verification.business: a company that completes KYB.userInfois rejected. Sendcountryto set up KYB at creation, and add the people who complete it with Add organization member.
accountType defaults to personal today and will become required. Send it explicitly.
Signing customers in
For a personal organization whose customer signs in with a JWT (see JWT User Authentication), send the JWT sub as id. A business organization has its own id; never reuse a customer’s sub as one, which returns 409.
curl --request POST \
--url https://api.sand.etherfuse.com/organization \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"accountType": "personal",
"displayName": "Ana Ejemplo",
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"userInfo": {
"displayName": "Ana Ejemplo",
"email": "[email protected]"
}
}
'const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
accountType: 'personal',
displayName: 'Ana Ejemplo',
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
userInfo: {displayName: 'Ana Ejemplo', email: '[email protected]'}
})
};
fetch('https://api.sand.etherfuse.com/organization', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sand.etherfuse.com/organization"
payload = {
"accountType": "personal",
"displayName": "Ana Ejemplo",
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"userInfo": {
"displayName": "Ana Ejemplo",
"email": "[email protected]"
}
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"displayName": "Ana Ejemplo",
"accountType": "personal",
"approvedAt": null,
"createdAt": "2026-10-01T14:30:00Z",
"updatedAt": "2026-10-01T14:30:00Z"
}{
"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.
Body
Whether this org is an individual or a company:
personal: an individual customer completing KYC. SenduserInfo.business: a company completing KYB.userInfois rejected.
Optional today and defaults to personal. It will become required, so send it explicitly now.
personal, business "personal"
The organization's display name: the friendly label shown in UIs and API responses. For a business org completing KYB, the legal entity name is captured separately via legalName.
Optional info about the end user. Required eventually for personal orgs. Rejected on business orgs (those don't have a single end user).
Show child attributes
Show child attributes
ISO 3166-1 alpha-2 country code (e.g. MX). Business orgs only; rejected on personal orgs. When provided, Etherfuse generates the KYB onboarding at creation, seeding the company entity with this country so the user lands straight in KYB. Omit it and the user is prompted for their country when they begin KYB.
"MX"
Legal entity name for the KYB company entity (e.g. the incorporated name on the company's registry documents). Pass it together with country when generating the KYB onboarding at creation; rejected without country. Independent of displayName: renaming the org does not change the legal name, and vice versa.
"Acme Corporation S.A. de C.V."
Response
The new organization.
personal: an individual who completes KYC. business: a company that completes KYB.
personal, business When the organization's KYC or KYB was approved. Null until then.