Increase limits

Raise a COMPANY subaccount's operating limits by submitting Proof of Address for the company and its UBO.

Business accounts only. Proof of Address raises the operating limits of a COMPANY subaccount. Its KYB must be APPROVED before you can submit Proof of Address.

Overview

A newly verified COMPANY subaccount transacts under a default limit. To raise it, you submit two Proof of Address documents, independent of KYB Level 1:

  • Company address — proves the registered business address.
  • UBO address — proves the Ultimate Beneficial Owner's residence.

Each document is uploaded, then submitted, then polled separately. Both must be APPROVED for the higher limits to take effect.

  • POST /api/kyc/document — register a PDF and get a one-time upload URL. Use documentType: "PROOF-OF-ADDRESS-COMPANY" for the company address and documentType: "PROOF-OF-ADDRESS" for the UBO residence.
  • POST /api/kyb/proof-of-address — submit one uploaded document, get back an attemptId.
  • GET /api/kyb/proof-of-address/{attemptId} — poll the attempt (PENDINGAPPROVED or REJECTED).

Flow

  1. Confirm the COMPANY subaccount's KYB is APPROVED.
  2. Company address — register a PROOF-OF-ADDRESS-COMPANY document, upload the PDF, poll until ready: true, then submit it with addressType: "COMPANY".
  3. UBO address — register a PROOF-OF-ADDRESS document, upload the PDF, poll until ready: true, then submit it with addressType: "UBO".
  4. Poll each attemptId until status: APPROVED.

Documents must be single-sided PDFs, typically dated within the last 3 months.

Uploading a Proof of Address document

Proof of Address documents reuse the document upload endpoints. Register the document, PUT the PDF to the returned URL, then poll readiness — the only difference is the documentType.

1. Register the document — POST /api/kyc/document

curl --request POST \
  --url https://api.hodle.com.br/api/kyc/document \
  --header "Authorization: Bearer $API_KEY" \
  --header "Content-Type: application/json" \
  --data '{ "subAccountId": "c852df87-...", "documentType": "PROOF-OF-ADDRESS-COMPANY" }'
FieldTypeRequiredDescription
subAccountIdstringYesThe COMPANY subaccount the document belongs to.
documentTypestringYesPROOF-OF-ADDRESS-COMPANY (company address) or PROOF-OF-ADDRESS (UBO residence).
201 Created
{
  "success": true,
  "data": {
    "documentId": "doc_poa_9a1...",
    "uploadUrlFront": "https://uploads.hodle.com.br/..."
  }
}

2. Upload the PDF

curl --request PUT \
  --url "$UPLOAD_URL_FRONT" \
  --header "If-None-Match: *" \
  --header "Content-Type: application/pdf" \
  --data-binary "@company-address.pdf"

3. Check readiness — GET /api/kyc/document/{documentId}

curl --url "https://api.hodle.com.br/api/kyc/document/doc_poa_9a1...?subAccountId=c852df87-..." \
  --header "Authorization: Bearer $API_KEY"
200 OK
{ "success": true, "data": { "documentId": "doc_poa_9a1...", "ready": true } }

Poll until ready: true, then submit the document below.

POST /api/kyb/proof-of-address

Submit one ready document. Call it once for the company address and once for the UBO address — each call returns its own attemptId.

Request

curl --request POST \
  --url https://api.hodle.com.br/api/kyb/proof-of-address \
  --header "Authorization: Bearer $API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "subAccountId": "c852df87-ac61-4259-8242-6451658dfedb",
    "uploadedPoAId": "doc_poa_9a1...",
    "addressType": "COMPANY"
  }'
const res = await fetch('https://api.hodle.com.br/api/kyb/proof-of-address', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.HODLE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    subAccountId,
    uploadedPoAId,
    addressType: 'COMPANY',
  }),
})
const data = await res.json()
import os, requests

res = requests.post(
    "https://api.hodle.com.br/api/kyb/proof-of-address",
    headers={
        "Authorization": f"Bearer {os.environ['HODLE_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "subAccountId": sub_account_id,
        "uploadedPoAId": uploaded_poa_id,
        "addressType": "COMPANY",
    },
)
data = res.json()

Parameters

FieldTypeRequiredDescription
subAccountIdstringYesThe COMPANY subaccount's id.
uploadedPoAIdstringYesdocumentId of the uploaded Proof of Address PDF, with ready: true.
addressTypestringYesCOMPANY for the company address, UBO for the beneficial owner's residence.
sandboxRejectbooleanNoSandbox only. true simulates a rejected attempt; ignored in production.

Response

202 Accepted
{
  "success": true,
  "data": {
    "attemptId": "att_poa_1e6b...",
    "addressType": "COMPANY",
    "status": "PENDING",
    "createdAt": "2026-07-22T22:00:00.000Z"
  }
}

Errors

400 — KYB not approved
{ "success": false, "error": "KYB Level 1 must be approved before submitting Proof of Address" }
404 — subaccount not found
{ "success": false, "error": "Subaccount not found for this platform" }

GET /api/kyb/proof-of-address/{attemptId}

Poll a submitted attempt until it resolves.

Request

curl --request GET \
  --url https://api.hodle.com.br/api/kyb/proof-of-address/att_poa_1e6b... \
  --header "Authorization: Bearer $API_KEY"
const res = await fetch(
  `https://api.hodle.com.br/api/kyb/proof-of-address/${attemptId}`,
  { headers: { Authorization: `Bearer ${process.env.HODLE_API_KEY}` } },
)
const data = await res.json()
import os, requests

res = requests.get(
    f"https://api.hodle.com.br/api/kyb/proof-of-address/{attempt_id}",
    headers={"Authorization": f"Bearer {os.environ['HODLE_API_KEY']}"},
)
data = res.json()

Response

status: APPROVED
{
  "success": true,
  "data": {
    "attemptId": "att_poa_1e6b...",
    "addressType": "COMPANY",
    "status": "APPROVED",
    "resultMessage": null,
    "createdAt": "2026-07-22T22:00:00.000Z",
    "updatedAt": "2026-07-22T22:01:43.000Z"
  }
}
status: REJECTED
{
  "success": true,
  "data": {
    "attemptId": "att_poa_1e6b...",
    "addressType": "UBO",
    "status": "REJECTED",
    "resultMessage": "Document older than 3 months",
    "createdAt": "2026-07-22T22:00:00.000Z",
    "updatedAt": "2026-07-22T22:01:43.000Z"
  }
}

Status values

StatusMeaning
PENDINGUnder review. Keep polling.
APPROVEDAccepted. Higher limits apply once both company and UBO are APPROVED.
REJECTEDFailed. resultMessage describes why; upload a fresh document and resubmit.