Organization & KYB
Read your organization, onboard a new one, and submit business verification (KYB).
Get the organization
GET /v1/organization — Scope: organization:read
Returns the organization the API key belongs to.
bash
curl https://api.caiboglobal.com/v1/organization \
-H "X-API-Key: $CAIBO_API_KEY"Response — 200 OK
json
{
"id": "org_9f8e7d6c",
"object": "organization",
"legal_name": "Acme Inc",
"display_name": "Acme",
"country": "CA",
"status": "active",
"kyb_status": "verified",
"created_at": "2026-07-23T14:03:00Z"
}Errors
| HTTP | type | code | When |
|---|---|---|---|
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks organization:read. |
| 429 | rate_limit_error | rate_limited | Too many requests. |
Create an organization (onboarding)
POST /v1/organizations
This is the one endpoint that does NOT use an API key. It's authenticated with a Firebase ID token — the founder signs in first, and the organization is created for that user. It exists because you need a way to create your first organization (and thus your first key) before any API key exists. In practice you'll use the Business dashboard for this rather than calling it directly.
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <firebase-id-token> — not an API key. |
Content-Type | Yes | application/json |
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
legal_name | string | Yes | The business's legal name. |
display_name | string | No | Defaults to legal_name. |
country | string | Yes | ISO-3166 alpha-2. |
Request
bash
curl https://api.caiboglobal.com/v1/organizations \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "legal_name": "Acme Inc", "display_name": "Acme", "country": "CA" }'Response — 201 Created
Returns the new organization and a one-time test API key to bootstrap your integration.
json
{
"organization": {
"id": "org_9f8e7d6c",
"object": "organization",
"legal_name": "Acme Inc",
"display_name": "Acme",
"country": "CA",
"status": "pending",
"kyb_status": "unverified",
"created_at": "2026-07-23T14:03:00Z"
},
"api_key": {
"object": "api_key",
"prefix": "ck_test_a1b2",
"mode": "test",
"key": "ck_test_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}
}Errors use the standard envelope. A repeat onboarding for the same user returns 409 org_already_exists.Submit KYB
POST /v1/kyb — Scope: organization:write
Submits your business verification and moves the organization to kyb_status: pending. Required to unlock live keys and live payouts. You can't resubmit while already verified or under review — that returns 409 kyb_not_resubmittable.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
legal_name | string | Yes | Legal name. |
registration_no | string | Yes | Business registration number. |
incorporation_country | string | Yes | ISO-3166 alpha-2. |
beneficial_owners | object[] | Yes | At least one UBO. Total ownership can't exceed 100%. Sub-fields below. |
beneficial_owners[].name | string | Yes | Full name. |
beneficial_owners[].dob | string | Yes | Date of birth, YYYY-MM-DD. |
beneficial_owners[].ownership_pct | number | Yes | Ownership percentage, greater than 0 and at most 100. |
beneficial_owners[].country | string | Yes | ISO-3166 alpha-2. |
documents | object[] | Yes | At least one document. Sub-fields below. |
documents[].type | string | Yes | Document type, e.g. incorporation. |
documents[].reference | string | Yes | A URL or reference to the document. |
Request
bash
curl https://api.caiboglobal.com/v1/kyb \
-H "X-API-Key: $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"legal_name": "Acme Inc",
"registration_no": "123456789",
"incorporation_country": "CA",
"beneficial_owners": [
{ "name": "Jane Doe", "dob": "1980-01-01", "ownership_pct": 60, "country": "CA" },
{ "name": "John Roe", "dob": "1975-05-05", "ownership_pct": 40, "country": "US" }
],
"documents": [
{ "type": "incorporation", "reference": "https://docs.example/incorp.pdf" }
]
}'Response — 201 Created
json
{
"id": "kyb_1a2b3c4d",
"object": "kyb_submission",
"org_id": "org_9f8e7d6c",
"status": "pending",
"legal_name": "Acme Inc",
"registration_no": "123456789",
"incorporation_country": "CA",
"beneficial_owners": [
{ "name": "Jane Doe", "dob": "1980-01-01", "ownership_pct": 60, "country": "CA" },
{ "name": "John Roe", "dob": "1975-05-05", "ownership_pct": 40, "country": "US" }
],
"documents": [
{ "type": "incorporation", "reference": "https://docs.example/incorp.pdf" }
],
"created_at": "2026-07-23T14:03:00Z"
}Errors
| HTTP | type | code | When |
|---|---|---|---|
| 400 | invalid_request_error | bad_request | Missing/invalid fields: bad country code, an owner with ownership ≤ 0 or > 100, total ownership > 100%, no owners, or no documents. |
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks organization:write. |
| 409 | invalid_request_error | kyb_not_resubmittable | The organization is already verified or has a submission under review. |
| 429 | rate_limit_error | rate_limited | Too many requests. |
Get KYB status
GET /v1/kyb — Scope: organization:read
Returns your latest KYB submission, or 404 kyb_not_found if you haven't submitted one.
bash
curl https://api.caiboglobal.com/v1/kyb \
-H "X-API-Key: $CAIBO_API_KEY"Errors
| HTTP | type | code | When |
|---|---|---|---|
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks organization:read. |
| 404 | invalid_request_error | kyb_not_found | No submission exists yet. |