Skip to main content
Connected accounts let you — the integrator — run KYB (businesses) or KYC (individuals) on behalf of your own end clients, server-to-server, without redirecting anyone to a hosted flow. Each connected account is a receiver at our settlement partner that is private to your organization and bound to one mode (test or live). Two roles:
  • seller — a business or individual that will receive payments and settle to its own bank/PIX. On approval, Caratuva provisions settlement rails so the seller is payout-ready.
  • buyer — a payer you verify ahead of a payment.
This is the onboarding/verification surface. v1 makes a connected seller payout-ready (verified receiver + off-ramp wallet + registered PIX destination), but routing a payment intent’s funds to a connected seller — and letting a connected buyer pay without re-KYC — are a follow-on. Buyer KYC for the hosted payment flow is unchanged (Buyer KYC).

Authentication & scopes

All routes use your API key (X-API-Key: pk_<test|live>_...). The key’s prefix fixes the mode — a connected account created with a pk_test_ key is invisible to live and routes to the settlement partner sandbox. Routes require the relevant scope (keys with no scopes set are unrestricted, for backward compatibility):
ScopeGrants
connected_accounts:writecreate, ToS, upload-url, submit, payout-config
connected_accounts:readget, list

The lifecycle

create ──▶ (tos-session ▶ tos-accepted) ──▶ [upload-url …] ──▶ submit ──▶ verifying ──▶ approved | rejected

                                                                 seller approved ───▶ settlement provisioned
                                                                                    └▶ payout-config (PIX)
status values: created (local shell, no receiver yet) · verifying (submitted to the settlement partner) · approved · rejected.

1. Create

curl -X POST https://api.caratuva.com/v1/connected-accounts \
  -H "X-API-Key: $CARATUVA_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "role": "seller",
    "entityType": "business",
    "externalId": "merchant-42",
    "legalName": "Acme Comércio LTDA",
    "country": "BR"
  }'
FieldTypeRequiredNotes
roleseller | buyeryesWhat the end client will do once verified.
entityTypebusiness | individualyesSelects the verification path on submit.
externalIdstring (1–200)noYour primary key for this end client. Unique per (org, mode). Re-creating with the same value returns the existing account — safe under retry.
email, legalName, displayName, country, taxIdstringnoIdentity hints; finalised on submit.
Returns a ConnectedAccount with status: "created".

2. Terms of Service (per end client)

Our settlement partner requires ToS acceptance before a receiver can be created. Mint a session, direct your end client to the URL, and record the tos_id from the redirect.
# Mint a session
curl -X POST https://api.caratuva.com/v1/connected-accounts/{id}/tos-session \
  -H "X-API-Key: $CARATUVA_API_KEY" -H "content-type: application/json" \
  -d '{ "redirectUrl": "https://app.example.com/onboarding/{id}/tos-done" }'
# -> { "url": "https://...", "idempotencyKey": "..." }

# After the redirect carries ?tos_id=...
curl -X POST https://api.caratuva.com/v1/connected-accounts/{id}/tos-accepted \
  -H "X-API-Key: $CARATUVA_API_KEY" -H "content-type: application/json" \
  -d '{ "tosId": "tos_..." }'
tos-accepted requires a session minted first (it binds the redirect to this account, closing the cross-account tos_id replay window). You may also pass tosId directly on submit; it must match the recorded value.

3. Documents (optional)

Provide your own pre-hosted HTTPS URLs in the submit body, or mint short-lived signed upload URLs:
curl -X POST https://api.caratuva.com/v1/connected-accounts/{id}/upload-url \
  -H "X-API-Key: $CARATUVA_API_KEY" -H "content-type: application/json" \
  -d '{ "kind": "id_doc_front", "contentType": "image/jpeg" }'
# -> { uploadUrl, publicUrl, uploadHeaders, uploadMethod, expiresAt }
kind: selfie · id_doc_front · id_doc_back · proof_of_address · incorporation_doc · proof_of_ownership_doc. For business beneficial owners, pass ownerIndex (a zero-based integer, 0–20). PUT the bytes to uploadUrl with the returned headers, then pass publicUrl in submit. Returns 503 KycStorageDisabled if document storage isn’t configured — use pre-hosted URLs instead.

4. Submit to the settlement partner

One endpoint; the fields required depend on (role, entityType). Missing fields return 400 ConnectedAccountMissingFields with the offending paths. Seller business (createKyb, Brazilian CNPJ):
curl -X POST https://api.caratuva.com/v1/connected-accounts/{id}/submit \
  -H "X-API-Key: $CARATUVA_API_KEY" -H "content-type: application/json" \
  -d '{ "email": "ops@acme.com.br", "legalName": "Acme Comércio LTDA", "cnpj": "12345678000199" }'
Individual (createKyc):
curl -X POST https://api.caratuva.com/v1/connected-accounts/{id}/submit \
  -H "X-API-Key: $CARATUVA_API_KEY" -H "content-type: application/json" \
  -d '{
    "email": "jane@example.com",
    "firstName": "Jane", "lastName": "Doe",
    "dateOfBirth": "1990-04-12",
    "idDocCountry": "US", "idDocType": "PASSPORT",
    "selfieFile": "https://...", "idDocFrontFile": "https://..."
  }'
Buyer business (createBuyerKyb) requires legalName, formationDate, taxId, website, country, address fields, incorporationDocFile, proofOfOwnershipDocFile, and at least one owners[] beneficial owner (role, name, dateOfBirth, taxId, address, idDocType, selfieFile, idDocFrontFile, proofOfAddressDocType, proofOfAddressDocFile). submit is idempotent while the account is verifying/approved — it returns the current submission rather than creating a second receiver. In the sandbox, KYB auto-approves; KYC resolves to verifying and completes via webhook.

5. Seller payout destination (PIX)

After a seller is approved, register where it gets paid. The raw PIX key is sent to our settlement partner and never stored by Caratuva.
curl -X POST https://api.caratuva.com/v1/connected-accounts/{id}/payout-config \
  -H "X-API-Key: $CARATUVA_API_KEY" -H "content-type: application/json" \
  -d '{ "pixKey": "acme@pix.example.com", "accountHolderName": "Acme Comércio LTDA" }'
Sellers only, and the account must be approved first (400 ConnectedAccountNotApproved otherwise). After this, the account reports payoutConfigured: true.

Read

curl https://api.caratuva.com/v1/connected-accounts/{id} -H "X-API-Key: $CARATUVA_API_KEY"
curl "https://api.caratuva.com/v1/connected-accounts?role=seller&status=approved&limit=50" \
  -H "X-API-Key: $CARATUVA_API_KEY"
The ConnectedAccount object includes status, receiverId, tosAccepted, payoutConfigured, and approvedAt / rejectedAt. List is cursor-paginated (nextCursor), filterable by role and status.

How status updates land

The settlement partner’s verification decision arrives at Caratuva’s signed inbound webhook; Caratuva resolves the receiver to your connected account and updates its status (idempotently). A terminal decision (approved/rejected) also purges any documents Caratuva stored for the account. To observe the result today, poll GET /v1/connected-accounts/:id (or GET /v1/connected-accounts?status=verifying) until status is terminal. In the sandbox, seller-business KYB auto-approves synchronously on submit, so the submit response already carries approved.
Outbound webhook events for connected-account status changes (e.g. connected_account.approved) are a follow-on — unlike payment intents, a connected account isn’t tied to an invoice timeline. For now, poll the read endpoints.