Cumbuca Gateway API Quickstart
Reference for the Cumbuca Open Finance data-sharing API: participant directory, data-sharing consent lifecycle, Phase 2 data consumption endpoints, and the shared consent management portal.
Background - Open Finance Brasil
This section is a high-level primer for readers new to the ecosystem. If you already know how Open Finance Brasil works, jump straight to Overview.
What is Open Finance Brasil
Open Finance Brasil is a Central Bank-regulated programme that lets customers (individuals and legal entities) share their financial data across institutions in a standardised, secure way. The same idea that powered Pix's interoperability is applied to the rest of the financial stack: accounts, cards, credit, investments, and FX.
The Central Bank (BACEN) sets the rules and publishes the regulated APIs; a Deliberative Council coordinated by an industry-wide governance structure operationalises them through working groups (security, customer experience, infrastructure, etc.). Compliance is not optional: every regulated institution must expose the standard APIs in the way the spec defines.
Participation roles
Each institution joins the ecosystem under one or more roles. For data sharing, the roles split into a passive side (holds the data) and an active side (asks for the data):
| Role | Description |
|---|---|
| Transmissor de Dados passive | Typically banks; serves data requests on behalf of consented customers. |
| Receptor de Dados active | Typically fintechs / advisors; requests customer data to power their product. |
An institution can hold multiple roles simultaneously (data and payments). For this data-sharing reference, the relevant tag in the participants directory is DADOS; that's what you'll see filtered in GET /consent-management/v1/participants.
Client vs server in the protocol. The passive/active split lines up directly with the OAuth client/server split. The Receptor de Dados plays the role of OAuth client: it registers via DCR, asks for authorisation, holds the access token, and makes the API calls. The Transmissor de Dados plays the role of Authorisation Server (AS) and resource server: it authenticates the user, issues consents and tokens, and serves the regulated endpoints. So when you read "AS" in the FAPI-BR spec, picture the bank that holds the customer's data; when you read "client", picture the fintech driving the integration.
Implementation phases
The programme rolled out in four phases. The labels are still used everywhere in the spec and in conversations:
- Phase 1 (Open Data). Public, no-consent-needed information about institutions, products, rates, branches.
- Phase 2 (Customer Data). Consented sharing of customer-owned data: accounts, cards, credit operations, investments, FX. Most of the GETs you'll find under Data Consumption live here.
- Phase 3 (Services). Payment initiation and credit portability (out of scope for this reference).
- Phase 4 (Extensions). Continuous refinements to the earlier phases.
How institutions communicate
Two cross-cutting standards govern every request between institutions:
- mTLS (mutual TLS). Both sides present X.509 certificates issued by approved CAs (CertiSign, Serpro, Soluti). The TLS handshake itself is the first layer of authentication: an institution that isn't in the directory can't even open a connection.
- Message signing (JWS). Sensitive request and response bodies (such as recurring consent retrieval) are wrapped in a compact JWS: the body is a base64url
header.payload.signaturestring, signed with a separate signing certificate. This guarantees integrity end-to-end, even when the message passes through proxies.
These two combined implement the FAPI-BR security profile, a Brazilian regional flavour of OpenID Foundation's Financial-grade API standard. On top of FAPI-BR, the standard OAuth 2.0 / OIDC building blocks are used:
- DCR (Dynamic Client Registration): institutions register their OAuth clients programmatically.
- PAR (Pushed Authorisation Request): the authorisation request is pre-registered on the holder side, so the redirect URL the user sees is short, signed, and tamper-proof.
- OIDC redirect flow: the user is sent to the holder's bank, authenticates, authorises, and is redirected back to the initiator's
callbackApplicationUri.
For first-time integrations all of this orchestration (directory lookup, DCR, token exchange, PAR, mTLS handshake) happens for every call. It's a lot of moving parts.
Simplified request flow, putting the pieces together for a typical authorised data read:
Every arrow between client and AS rides on mTLS. Steps that expose private data (steps 2 and 5/6) additionally carry JWS-signed payloads. The customer's browser is only involved on steps 3 and 4: the redirect handoff that triggers authentication and brings the user back.
Consent at the centre
Every cross-institution data read is anchored on a consent. The consent is a regulated artefact created on the holder side and tied to:
- The customer's identification document (CPF or CNPJ).
- The permissions being authorised.
- An expiration window.
- The active institution (the data receiver) that asked for it.
Until the consent is in AUTHORISED state, no protected resource can be read. After it expires, the holder will refuse the call. Picking up consent state and reacting to it (see GET /consent-management/v1/consents/{consentId}) is therefore central to any integration.
Where Cumbuca fits in
Cumbuca acts as the regulatory plumbing for institutions that want to participate as data receivers without having to build the full FAPI-BR stack in-house. The two-prefix structure you'll see throughout this reference reflects that:
/consent-management/...: Cumbuca's orchestration layer. A single HTTP call internally chains DCR → token → consent creation → PAR → redirect URL, so the integrator only deals with one request per business operation./open-finance/...: transparent proxy to the regulated APIs. mTLS and JWS verification of responses happen inside the proxy.
The rest of this document is the API reference for those two layers.
Overview
The API surface is organized in three groups, all served under the same PARTNER_BASE_URL unless noted otherwise:
/consent-management/...: Cumbuca orchestration endpoints. Internally chain DCR → Token → Consent creation → PAR → Redirect URL, so the client only needs to call a single HTTP endpoint per business operation./open-finance/...: transparent proxy to the regulated Open Finance Brasil APIs. mTLS, JWS request/response signing, and other regulatory plumbing are handled by the proxy.https://[sandbox.]directory.openbankingbrasil.org.br/participants: the official OF Brasil participants directory. Surfaced through the Cumbuca API as/consent-management/v1/participants.
How Access Works
Authentication to the Cumbuca API is built on two layers:
- mTLS: every connection rides on a mutually authenticated TLS handshake against the Cumbuca CA.
- Bearer access token: obtained from
POST /auth/v1/tokenand sent asAuthorization: Bearer <access_token>on every call. Required for every endpoint in this reference except the two auth endpoints themselves.
Beyond those two layers, the only piece of state the client carries from one call to the next is the consentId, which scopes the request to a specific authorised consent.
- Client calls
POST /auth/v1/tokenover mTLS with its credentials. The response carries anaccess_token, a short-livedexpires_in, and a long-livedrefresh_token. - The client sends
Authorization: Bearer <access_token>on every subsequent call. - When the access token expires, the client calls
POST /auth/v1/tokenwithgrant_type=refresh_tokento obtain a new access token without re-submitting credentials.
client_id must also be provisioned on the Cumbuca side. Until it is, you can still obtain tokens, but every other call fails with 401 UNAUTHORIZED and detail client_id is not provisioned. If you see that detail, contact Cumbuca to complete provisioning; the token itself is fine.
- Client calls
POST /consent-management/v1/consentsover mTLS with a valid bearer token. - On
201, Cumbuca returns the regulated payload (data.consentId,data.redirectUrl,data.consent). - The client persists
data.consentIdfor later use. - User is redirected to
data.redirectUrl, authorises the consent at the bank, and is redirected back to the client'scallbackApplicationUri.
On every subsequent call to a consent-protected endpoint (the data reads under /open-finance/... and the consent lookup itself), the client must:
- Send
Authorization: Bearer <access_token>. - Send the
consentIdas thex-consent-idheader. - Send
x-authorisation-server-ididentifying the target institution.
Cumbuca resolves the caller from the client_id carried in the bearer token and forwards the request to the regulated API under that client's identity. The upstream response flows back to the client unchanged.
x-consent-id required? Every endpoint that operates on an existing consent; that is, every endpoint except GET /consent-management/v1/participants (no consent involved) and POST /consent-management/v1/consents (the call that creates the consent in the first place).
client_id in the bearer token. Every call is executed under that identity, so a client can't act on another client's data. mTLS remains a transport requirement on every connection (including POST /auth/v1/token); it is not used for per-consent checks.
Common Headers
Every request to the partner API uses some combination of the following headers:
| Header | Required when | Value |
|---|---|---|
Authorization | Every endpoint except POST /auth/v1/token | Bearer <access_token> obtained from the auth endpoints |
x-authorisation-server-id | Every regulated call (except auth and GET /consent-management/v1/participants) | Authorisation Server ID of the target institution (from the directory) |
authorizationServerId query | Same endpoints as x-authorisation-server-id | Query-parameter alternative to the header. Takes precedence when both are supplied. |
x-consent-id | Phase 2 data reads | consentId returned by the consent creation call |
content-type | POSTs with a JSON body | application/json |
Error Format
The partner returns errors as JSON in the response body for any non-2xx HTTP status. The shape follows the Open Finance Brasil regulated format:
{
"errors": [
{
"code": "INVALID_REQUEST",
"title": "Validation failed",
"detail": "data.payment.amount must be a string"
}
]
}
Multiple entries in errors[] are possible when several validation failures are reported in the same response.
| Header | Meaning |
|---|---|
x-nexus-request-id | Correlation id (UUIDv7) present on every response, success or error, and propagated to the upstream services. Log it and quote it in support tickets. |
x-nexus-error-source | Present on every error response: client means the gateway rejected your request or credentials (auth, validation, rate limit, 404); upstream means the bank / an upstream service returned the error or failed, including 4xx passed through from the bank; gateway means Cumbuca itself failed. Use it to classify failures without parsing bodies. |
| Code | HTTP | Meaning | Retry? |
|---|---|---|---|
UNAUTHORIZED | 401 | Missing, malformed, or expired bearer token, or the token's client_id is not provisioned | No; fix credentials / provisioning |
INVALID_CLIENT | 401 | Missing or invalid Basic credentials on POST /auth/v1/token | No |
INVALID_GRANT | 400 | Token request failed: bad, expired, or reused refresh_token, or the authorisation server is unavailable | Only when the detail is "authorization server unavailable" or "token request failed" (transient authorisation-server problems) |
INVALID_REQUEST | 400 | Malformed body or missing required field / header | No |
UNSUPPORTED_GRANT_TYPE | 400 | grant_type other than client_credentials / refresh_token | No |
UNSUPPORTED_MEDIA_TYPE | 415 | Body with a content-type other than JSON / form-urlencoded | No |
RATE_LIMITED | 429 | Per-client rate limit exceeded; see Rate limits | Yes, after retry-after |
NOT_FOUND | 404 | No route matches the request (returned only to authenticated callers) | No |
INTERNAL_ERROR | 500 | Unexpected gateway failure | Yes, with backoff |
OPUS_ERROR | upstream status | Upstream returned an error whose body could not be relayed as-is | Depends on status |
OPUS_UNAVAILABLE | 502 | Upstream transport failure or timeout | Yes (transient) |
REGISTER_ERROR | upstream status | The reciprocity store returned an error with an empty or unreadable body | Depends on status |
REGISTER_UNAVAILABLE | 502 | The reciprocity store is unreachable | Yes (transient) |
UPSTREAM_ERROR | 502 | The shared-consent portal returned a non-2xx response | Yes (transient) |
UPSTREAM_UNAVAILABLE | 502 | The shared-consent portal is unreachable | Yes (transient) |
POST /openid/authorize return 422 with the body {"error", "error_description"}, the only error in this API that does not use the errors[] envelope above.
Rate Limits
Requests are rate limited per client_id over a fixed time window shared across all bearer-authenticated endpoints of the API (consents, data reads, everything). When the limit is exceeded the API returns 429 with code RATE_LIMITED and a retry-after response header carrying the integer number of seconds until the window resets; honour it before retrying.
POST /auth/v1/tokenis not rate limited.- No
x-ratelimit-*headers are emitted on successful responses; the only signal is the 429 itself. - Limits are configured per environment (default 600 requests per 60 s), so don't hardcode assumptions; drive backoff from
retry-after.
Timeouts & Retries
Calls proxied to the data-holding bank run under an upstream budget of roughly 30 seconds; once it is exhausted the gateway answers 502 (OPUS_UNAVAILABLE). Set client-side timeouts of at least ~35 seconds or you will truncate slow-but-successful responses.
- GETs may be retried by the gateway itself, only on connection-level failures (max 2 retries, i.e. up to 3 attempts total, no backoff), and are safe for you to retry as well.
- Writes are never retried by the gateway. A
502on a POST or PATCH is indeterminate: the operation may or may not have reached the bank. Reconcile with a GET instead of blindly retrying: after an ambiguous failure onPOST /consent-management/v1/consents, look the consent up before creating a new one. - There is no idempotency-key support; build your own deduplication for writes.
502/*_UNAVAILABLEerrors are transient and retryable. Note that an authorisation-server outage onPOST /auth/v1/tokensurfaces as400 INVALID_GRANT("authorization server unavailable"), not as a 5xx.
Callback URIs
Consent-creating endpoints accept a callbackApplicationUri in the request body. After the user authorises (or rejects) the consent on the user's bank, the bank redirects them back to that URI carrying status query parameters. Each business flow conventionally uses its own callback path so the redirect handler can route appropriately:
| Flow | Suggested callbackApplicationUri |
|---|---|
| Data sharing | https://<your-host>/consent/callback |
Quickstart - Data Sharing
End-to-end flow for reading data from a user's bank account: ask consent, pick one account, and pull its transactions.
-
Get an access token: call
POST /auth/v1/tokenwith your credentials over mTLS. Keep the returnedaccess_tokenfor the calls below, and therefresh_tokenfor when the access token expires (call this same endpoint withgrant_type=refresh_token). Every call from here on must carryAuthorization: Bearer <access_token>. -
Pick the user's bank: call
GET /consent-management/v1/participants?role=DADOS&familyType=accountsto let the directory filter server-side:role=DADOSkeeps only data-sharing institutions andfamilyType=accountskeeps only those exposing the accounts APIs you'll read below. Capture the chosenauthorisationServerId. -
Create the data-sharing consent: call
POST /consent-management/v1/consentswith the user's document and the permissions you need (at minimumACCOUNTS_READ,ACCOUNTS_TRANSACTIONS_READ, andRESOURCES_READ). You'll get back aconsentIdand aredirectUrl. -
Send the user to the bank: redirect the browser to the returned
redirectUrl. The user authenticates and authorises the sharing on the bank's site, then is redirected back to yourcallbackApplicationUri. -
Complete the authorisation: when the bank redirects back to your
callbackApplicationUri, capture the full query string (it containscode,id_token, andstate). POST it toPOST /openid/authorizein the body'sdatafield. A204 No Contentresponse means Cumbuca has validated the code with the bank and the consent is now being authorised. -
Confirm the consent is authorised: when the callback hits, call
GET /consent-management/v1/consents/{consentId}and checkstatus == "AUTHORISED". If it'sREJECTED, stop here and show an error. -
List the user's accounts: call
GET /open-finance/accounts/v2/accountswith the authorisedconsentIdin thex-consent-idheader. Pick theaccountIdyou want to read from (e.g. the first checking account). -
Read the transactions: call
GET /open-finance/accounts/v2/accounts/{accountId}/transactionsusing the same headers. The response contains the transaction history underdata[].
Authentication
All endpoints in this reference (except the one below) require an Authorization: Bearer <access_token> header. Access tokens are short-lived; long-lived refresh tokens let the client renew them without re-exchanging credentials.
POST/auth/v1/token
Issues an access token using either the Client Credentials or Refresh Token grant type. This endpoint does not use the Bearer token; instead, send your client credentials as Authorization: Basic base64(client_id:client_secret).
content-type | required application/x-www-form-urlencoded |
Authorization | required Basic <base64(client_id:client_secret)> |
| Field | Value |
|---|---|
grant_type | required client_credentials or refresh_token |
scope | Optional: space-separated list of scopes. Applies to client_credentials only. |
refresh_token | Required when grant_type is refresh_token. The token returned by a previous response. |
POST /auth/v1/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
grant_type=client_credentials
{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "eyJhbGciOi...",
"refresh_expires_in": 2592000
}
Directory
GET/consent-management/v1/participants
Returns all institutions registered in the Open Finance Brasil participants directory. Clients should filter by the roles they care about, typically DADOS (data) and CONTA (payments), and by claim Status == "Active".
Authorization | required Bearer <access_token> |
role query | Filters entries whose OrgDomainRoleClaims contain the given role, e.g. DADOS (data) or CONTA (payments). Role types are subject to change; check the directory spec for the current list. |
familyType query | Filters entries whose ApiResources contain the given ApiFamilyType, e.g. accounts, credit-cards-accounts. |
[
{
"CustomerFriendlyName": "Banco X",
"CustomerFriendlyLogoUri": "https://...",
"AuthorisationServerIds": ["asid-uuid"],
"OrgDomainRoleClaims": [
{ "Role": "DADOS", "Status": "Active" },
{ "Role": "CONTA", "Status": "Active" }
],
"ApiResources": [{ "ApiFamilyType": "accounts" }],
"Organisations": [{ "RegisteredName": "BANCO X S.A." }]
}
]
POST/openid/authorize
Completes the OAuth 2.0 authorisation loop. After the data provider redirects the user back to your callbackApplicationUri, POST the full callback query string here so Cumbuca can exchange the authorisation code for tokens and finalise the consent. Returns 204 No Content on success.
Authorization | required Bearer token |
x-authorisation-server-id | required |
{
"data": "code=LxSev...&id_token=eyJ...&state=dXJu..."
}
{
"error": "authorization_failed",
"error_description": "authorization could not be completed"
}
Data Sharing Consent
POST/consent-management/v1/consents
Creates a data-sharing consent (Phase 2). Returns a consentId and a redirectUrl the end user must be redirected to in order to authorise the consent at the data-holding bank.
Authorization | required Bearer <access_token> | |
x-authorisation-server-id | required | |
authorizationServerId query | Same endpoints as x-authorisation-server-id | Query-parameter alternative to the header. Takes precedence when both are supplied. |
{
"data": {
"callbackApplicationUri": "https://.../consent/callback",
"loggedUser": {
"document": { "identification": "12345678901", "rel": "CPF" }
},
"businessEntity": { // optional - when the logged user acts as a legal-entity representative
"document": { "identification": "12345678000199", "rel": "CNPJ" }
},
"permissions": [
"ACCOUNTS_READ", "ACCOUNTS_BALANCES_READ",
"RESOURCES_READ"
],
"expirationDateTime": "2026-05-28T15:10:00Z"
}
}
| Field | Type | Notes |
|---|---|---|
data.callbackApplicationUri | string | required Absolute URI |
data.loggedUser.document.identification | string | required CPF or CNPJ (digits only) |
data.loggedUser.document.rel | enum | required "CPF" or "CNPJ" |
data.businessEntity | object | optional Present when the logged user represents a legal entity |
data.permissions | string[] | required Regulated OF permission strings; see appendix |
data.expirationDateTime | ISO 8601 | required Maximum lifetime of the consent |
{
"data": {
"consentId": "urn:cumbuca:C123ABC...",
"redirectUrl": "https://auth.bank.example/oauth2/authorize?..."
}
}
businessEntity) created with an authorisation-server id turns AUTHORISED, Cumbuca automatically performs a single read of GET /open-finance/customers/v2/personal/identifications using that consent and registers the returned record for reciprocity. To enable it, when your institution does not delegate reciprocity (the default), Cumbuca automatically adds the CUSTOMERS_PERSONAL_IDENTIFICATIONS_READ permission to the consent, which is what authorises the read. This read is billable and appears in the bank's logs seconds after authorisation even though you did not issue it. It never changes your API responses, and records you register yourself via PUT /personal/identifications/register always take precedence. See the reciprocity guide.
GET/consent-management/v1/consents/{consentId}
Returns the current state of a data-sharing consent: status (AWAITING_AUTHORISATION, AUTHORISED, REJECTED, CONSUMED), permissions, and expiration. Useful for polling after the user is redirected back from the bank, and for displaying consent state in management screens.
consentId | required ID returned by the consent creation call |
Authorization | required Bearer <access_token> | |
x-authorisation-server-id | required | |
authorizationServerId query | Same endpoints as x-authorisation-server-id | Query-parameter alternative to the header. Takes precedence when both are supplied. |
{
"data": {
"consentId": "urn:raidiambank:c4bb1a06-8dcf-4935-9696-b40bf6911f50",
"consent": {
"data": {
"consentId": "urn:raidiambank:c4bb1a06-...",
"status": "AUTHORISED",
"creationDateTime": "2026-01-29T16:34:29Z",
"statusUpdateDateTime": "2026-01-29T16:34:41Z",
"expirationDateTime": "2026-07-29T16:34:27Z",
"permissions": ["ACCOUNTS_READ", "ACCOUNTS_BALANCES_READ", "RESOURCES_READ"]
},
"links": { "self": "https://matls-api.<bank>/open-finance/consents/v3/consents/<consentId>" },
"meta": { "requestDateTime": "2026-01-29T16:35:00Z" }
}
}
}
data.consent is the verbatim regulated payload returned by the data-holding bank (with its own data / links / meta sections per the OF Brasil spec), and the outer data.consentId is a convenience field added by the orchestration layer so callers don't have to dig into data.consent.data.consentId.
Consent lifecycle. Beyond creation and lookup, three lifecycle operations are available: DELETE /consent-management/v1/consents/{consentId} revokes the consent (returns 204); POST .../consents/{consentId}/authorisation-retry mints a fresh redirectUrl when the original authorisation attempt lapsed (e.g. the user abandoned the bank redirect); and POST .../consents/{consentId}/extends renews an AUTHORISED consent's expiration. This POST alone additionally requires the x-customer-user-agent and x-fapi-customer-ip-address headers, and a companion GET on the same path lists the extension history.
Data Consumption (Phase 2) - Authenticated GETs
All endpoints in this section follow the same shape:
- Method: GET
- Headers:
Authorization: Bearer <access_token>,x-authorisation-server-id,x-consent-id - Response:
{ "data": [...] }(regulated OF Brasil format) - Retries: data reads are billable; see Rate limits and Timeouts & retries before adding retry logic.
Customers
| Endpoint | Notes |
|---|---|
GET /open-finance/customers/v2/personal/identifications | Natural person identification |
GET /open-finance/customers/v2/business/identifications | Legal entity identification |
GET /open-finance/customers/v2/personal/financial-relations | Personal financial relationships |
GET /open-finance/customers/v2/business/financial-relations | Business financial relationships |
GET /open-finance/customers/v2/personal/qualifications | Personal qualifications (income, etc.) |
GET /open-finance/customers/v2/business/qualifications | Business qualifications |
Accounts (Checking / Savings)
| Endpoint | Notes |
|---|---|
GET /open-finance/accounts/v2/accounts | List accounts |
GET /open-finance/accounts/v2/accounts/{accountId} | Account details |
GET /open-finance/accounts/v2/accounts/{accountId}/balances | Balances |
GET /open-finance/accounts/v2/accounts/{accountId}/overdraft-limits | Overdraft limits |
GET /open-finance/accounts/v2/accounts/{accountId}/transactions | Transactions |
Credit Cards
| Endpoint | Notes |
|---|---|
GET /open-finance/credit-cards-accounts/v2/accounts | List card accounts |
GET /open-finance/credit-cards-accounts/v2/accounts/{id} | Card account details |
GET /open-finance/credit-cards-accounts/v2/accounts/{id}/bills | Bills |
GET /open-finance/credit-cards-accounts/v2/accounts/{id}/bills/{billId}/transactions | Bill transactions |
GET /open-finance/credit-cards-accounts/v2/accounts/{id}/limits | Card limits |
GET /open-finance/credit-cards-accounts/v2/accounts/{id}/transactions | Card transactions |
Credit Operations (4 families)
Generic shape for the scopes loans, financings, invoice-financings, and unarranged-accounts-overdraft:
Endpoint (with {scope}) | Notes |
|---|---|
GET /open-finance/{scope}/v2/contracts | List contracts |
GET /open-finance/{scope}/v2/contracts/{contractId} | Contract details |
GET /open-finance/{scope}/v2/contracts/{contractId}/payments | Payment history |
GET /open-finance/{scope}/v2/contracts/{contractId}/scheduled-instalments | Scheduled instalments |
GET /open-finance/{scope}/v2/contracts/{contractId}/warranties | Collateral / warranties |
Investments (5 families)
Scopes: bank-fixed-incomes, credit-fixed-incomes, variable-incomes, treasure-titles, funds.
| Endpoint | Notes |
|---|---|
GET /open-finance/{scope}/v1/investments | List investments |
GET /open-finance/{scope}/v1/investments/{id} | Investment details |
GET /open-finance/{scope}/v1/investments/{id}/balances | Balances |
GET /open-finance/{scope}/v1/investments/{id}/transactions | Historical transactions |
GET /open-finance/{scope}/v1/investments/{id}/transactions-current | Current-period transactions |
Exchanges (FX)
| Endpoint | Notes |
|---|---|
GET /open-finance/exchanges/v1/operations | List FX operations |
GET /open-finance/exchanges/v1/operations/{operationId} | Operation details |
GET /open-finance/exchanges/v1/operations/{operationId}/events | Operation events |
Resources (discovery)
| Endpoint | Notes |
|---|---|
GET /open-finance/resources/v3/resources | Lists every resource the consent grants access to |
Reciprocity
As a data receiver you are also expected to make your own account holders' registration data available to the ecosystem (reciprocidade). The write below populates the reciprocity store Cumbuca serves on your behalf: once a customer is registered, other Open Finance participants querying your institution get a positive account-holder check and the registered identification data.
PUT/personal/identifications/register
Registers (or updates) the personal-identification record of one of your account holders. Writes are idempotent upserts keyed by the customer's CPF and attributed to the client_id in your bearer token. Call it when a customer becomes an account holder and whenever their registration data changes. Records you write here always take precedence over the gateway's automatic reciprocity registration.
Authorization | required Bearer <access_token> |
content-type | required application/json |
{
"data": { "cpf": "12345678901" }
}
Consent Management
Lets the end user view, manage, and revoke all the consents they've authorised for the client. The call returns a one-time URL; redirect the user there to open the management portal. See also Reciprocity for the register write that keeps your own account holders' data available to the ecosystem.
POST/management/result
Returns a one-time URL with an embedded session token. Redirect the end user to that URL to access the consent management portal. You call this endpoint on the gateway (same base URL and Bearer token as every other endpoint in this reference); Cumbuca then signs a PS256 JWT internally and delivers it to the shared-consent portal on your behalf, so your integration never handles the JWT.
Authorization | required Bearer <access_token> |
content-type | required application/json |
{
"document": "12345678901",
"representativeCpf": "98765432100"
}
| Field | Type | Notes |
|---|---|---|
document | string | required The end user's CPF (11 digits) or CNPJ (14 digits) |
representativeCpf | string | optional The representative's CPF, only used when document is a CNPJ and a legal-entity representative is acting on behalf of the company |
{
"redirectUrl": "https://.../management/?token=..."
}
Appendix
Permissions mapping
Open Finance Brasil groups permissions by data category and grouping (the granular sharing unit the user authorises). Each grouping maps to a set of regulated permission strings. RESOURCES_READ must always be included when creating a data-sharing consent.
| Role | Data category | Grouping | Permissions |
|---|---|---|---|
DADOS |
Registration | Registration data (individual) | CUSTOMERS_PERSONAL_IDENTIFICATIONS_READ |
RESOURCES_READ | |||
| Additional information (individual) | CUSTOMERS_PERSONAL_ADITTIONALINFO_READ |
||
RESOURCES_READ | |||
| Registration data (legal entity) | CUSTOMERS_BUSINESS_IDENTIFICATIONS_READ |
||
RESOURCES_READ | |||
| Additional information (legal entity) | CUSTOMERS_BUSINESS_ADITTIONALINFO_READ |
||
RESOURCES_READ | |||
| Accounts | Balances | ACCOUNTS_READ |
|
ACCOUNTS_BALANCES_READ | |||
RESOURCES_READ | |||
| Limits | ACCOUNTS_READ |
||
ACCOUNTS_OVERDRAFT_LIMITS_READ | |||
RESOURCES_READ | |||
| Statements | ACCOUNTS_READ |
||
ACCOUNTS_TRANSACTIONS_READ | |||
RESOURCES_READ | |||
| Credit Card | Limits | CREDIT_CARDS_ACCOUNTS_READ |
|
CREDIT_CARDS_ACCOUNTS_LIMITS_READ | |||
RESOURCES_READ | |||
| Transactions | CREDIT_CARDS_ACCOUNTS_READ |
||
CREDIT_CARDS_ACCOUNTS_TRANSACTIONS_READ | |||
RESOURCES_READ | |||
| Bills | CREDIT_CARDS_ACCOUNTS_READ |
||
CREDIT_CARDS_ACCOUNTS_BILLS_READCREDIT_CARDS_ACCOUNTS_BILLS_TRANSACTIONS_READ | |||
RESOURCES_READ | |||
DADOS |
Credit Operations | Contract data | LOANS_READ |
LOANS_WARRANTIES_READ | |||
LOANS_SCHEDULED_INSTALMENTS_READ | |||
LOANS_PAYMENTS_READ | |||
FINANCINGS_READ | |||
FINANCINGS_WARRANTIES_READ | |||
FINANCINGS_SCHEDULED_INSTALMENTS_READ | |||
FINANCINGS_PAYMENTS_READ | |||
UNARRANGED_ACCOUNTS_OVERDRAFT_READ | |||
UNARRANGED_ACCOUNTS_OVERDRAFT_WARRANTIES_READ | |||
UNARRANGED_ACCOUNTS_OVERDRAFT_SCHEDULED_INSTALMENTS_READ | |||
UNARRANGED_ACCOUNTS_OVERDRAFT_PAYMENTS_READ | |||
INVOICE_FINANCINGS_READ | |||
INVOICE_FINANCINGS_WARRANTIES_READ | |||
INVOICE_FINANCINGS_SCHEDULED_INSTALMENTS_READ | |||
INVOICE_FINANCINGS_PAYMENTS_READ | |||
RESOURCES_READ | |||
DADOS |
Investments | Operation data | BANK_FIXED_INCOMES_READ |
CREDIT_FIXED_INCOMES_READ | |||
FUNDS_READ | |||
VARIABLE_INCOMES_READ | |||
TREASURE_TITLES_READ | |||
RESOURCES_READ | |||
DADOS |
Foreign Exchange | Operation data | EXCHANGES_READ |
RESOURCES_READ |