Extract Banking Data in Brazil (API with Hosted Widget)

In this guide, we walk you through everything you need to extract banking data about your users from Brazil's Open Finance Network using our API. This includes:

  • An overview of the data flow
  • Setting up Belvo's Hosted Widget to connect your users.
  • Getting your user's data based on webhook events sent by Belvo.
  • Providing your users a way to manage their consents.

Prerequisites

Before you proceed with your integration, make sure that you have:

  1. Gone through our getting started guide
    In the getting started guide, you'll create a Belvo account, generate some sandbox API keys, and set up a webhook URL.
    For testing purposes and developing your integration, we highly recommend using the Sandbox environment along with the Mockbank institution. You can find example credentials to simulate different users for the Mockbank institution here.

Data flow overview

Belvo uses an asynchronous workflow to improve the extraction of data and your flow. As you can see from the diagram below, once your user has connected their account using the Hosted Widget and the link is created, Belvo loads all the data asynchronously and then notifies you using webhooks that the data is available for you to retrieve.

Data flow for created links

Data flow for created links


Setting up the Hosted Widget

📘

We highly recommend using Belvo's hosted widget. It is designed to simplify your development and integration process, is compliant with Open Finance regulations, and is constantly monitored by a team of specialists to improve the user experience.

Our Hosted Widget can be embedded in your application as a webview and will guide your user through all the steps to grant their consent for you to access their data. This includes redirecting the user to their institution to provide consent and then back to your application.


You can view a simplified flow of what happens during the widget connection process in the diagram below:

Basically, whenever you want your user to connect their account from a financial institution in Brazil, you will need to:

1. Generate an access_token for the Hosted Widget (OFDA) using the users CPF or CNPJ.

See our step-by-step walkthrough on how to generate access token in the recipe below.

Additionally, check out our Generating an access_token section of our Hosted Widget (OFDA) guide.

2. Start the widget inside a webview in your application for your user.

See our step-by-step walkthrough on how to start the hosted widget in the recipe below.

Additionally, check out ourStarting the widget section of our Hosted Widget (OFDA) guide.

3.Listen for the success event that will include the link id.

This step requires some knowledge of handling redirects and their query parameters. For details regarding the events we send (and their format), see the Handling callback events section of our Hosed Widget (OFDA) guide.

To aid your development, we've created guides on how to set up deep links and listen for events for the following platforms:

Wait for webhooks and retrieve data

As Belvo utilizes an asynchronous workflow, once the link is created we automatically retrieve the last 12 months of historical data for the user that just connected their account. We'll notify you via webhook events once the data is extracted and you can retrieve it. For more details, see the Getting data section.

Getting data

Regardless if you use single or recurrent links, once your user completes the widget flow successfully, Belvo asynchronously retrieves the last 12 months of owner, account, transaction, and bill data for the link (historical updates). Once we have extracted the data, we notify you using a webhook that the information is ready to be retrieved.

If you are using recurrent links, Belvo will retrieve the updated information for the link according to your refresh rate (recurrent updates). Just like historical updates, we notify you using a webhook that the new information is ready to be retrieved.

Link Creation and Data Limits
When generating consent and creating the link, Belvo already consumes one operational limit of Owners, Accounts, Transactions, and Bills (to retrieve the historical data for your user). However, Belvo has implemented certain internal mechanisms to optimize the data retrieval limits. For more information, please see our dedicated Open Finance Network Limits (Brazil) article.

Brazil's Open Finance Network sets monthly limits regarding how often you can retrieve data for a specific person or business. These operational limits are linked to a combination of:

  • the user’s CPF or CNPJ
  • the API data you want to get (Owner, Account, Transaction, or Bill)
  • the Open Finance network certificate

Once the monthly operational limit of API calls is reached, no more information can be retrieved for the CPF/CNPJ until the start of the next calendar month. However, Belvo has implemented optimizations to maximize the amount of data you can retrieve for your users according to your data needs. For more information, please see our dedicated Open Finance Network Limits (Brazil) article.


Historical updates

Below you can see the flow of data for both single and recurrent links once a link is created:


Each time that you receive a webhook for a given resource (owners, accounts, transactions, or bills), you will need to make a GET call to that endpoint, using the link ID, to retrieve the information.

Get Owner information

Belvo will asynchronously retrieve the last 12 months owner data for your link and then send you a webhook once the information is ready to retrieve (see the webhook example below):

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "OWNERS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f8ca7a1-c28f-46f2-bb41-21633099a280",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_owners": 2 // Total number of owners
  }
}

Once you receive the webhook, you just need to make the following GET Owners request to retrieve the data for the given link:

curl --request GET 'https://api.belvo.com/api/owners/?link={id}' \
-u [Secret Key ID]:[Secret Key PASSWORD]
{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": "cf3acafc-8b89-4350-8350-3dc1a02c03c8",
            "link": "3d54d0d0-7ba6-453e-88ed-9963f76677a2",
            "created_at": "2024-05-23T11:02:48.229221Z",
            "email": "[email protected]",
            "emails": [
                {
                    "email": "[email protected]",
                    "is_main": true
                }
            ],
            "gender": "MALE",
            "address": "Rua Laguna 129, Porto Alegre, RS, 90820060, Brasil",
            "addresses": [
                {
                    "town": "Porto Alegre",
                    "state": "RS",
                    "address": "Rua Laguna 129",
                    "is_main": true,
                    "latitude": "-30.0953952",
                    "longitude": "-51.2279909",
                    "town_code": "4314902",
                    "postal_code": "90820060",
                    "country_code": "BRA",
                    "country_name": "Brasil",
                    "district_name": "Cavalhada",
                    "additional_info": "Casa Amarela"
                }
            ],
            "last_name": "Galvão",
            "birth_date": "1989-03-23",
            "filiations": [
                {
                    "type": "MOTHER",
                    "civil_name": "Andreia Galvao",
                    "social_name": "NA"
                }
            ],
            "first_name": "Tatiana",
            "document_id": {
                "document_type": "CPF",
                "document_number": "535.807.930-04"
            },
            "social_name": "",
            "collected_at": "2024-05-23T11:04:50.891662Z",
            "companies_id": [
                "25349207000105"
            ],
            "display_name": "Tatiana Galvão",
            "phone_number": "+55 51325421328",
            "nationalities": [
                {
                    "info": "true",
                    "documents": [
                        {
                            "type": "SOCIAL SEC",
                            "number": "423929299",
                            "issue_date": "2020-05-30",
                            "additional_info": "",
                            "expiration_date": "2022-08-21",
                            "country_of_issuance": "Brasil"
                        }
                    ]
                }
            ],
            "phone_numbers": [
                {
                    "type": "LANDLINE",
                    "number": "325421328",
                    "is_main": true,
                    "area_code": "51",
                    "extension": "258",
                    "country_code": "55",
                    "additional_info": "Informações adicionais."
                }
            ],
            "marital_status": "SINGLE",
            "second_last_name": "",
            "financial_profile": {
                "patrimony": {
                    "year": 2010,
                    "amount": "100000.04",
                    "currency": "BRL"
                },
                "company_id": "50685362000131",
                "informed_income": {
                    "date": "2021-05-21",
                    "amount": "100000.04",
                    "currency": "BRL",
                    "frequency": "OTHERS"
                },
                "occupation_code": "OTHER",
                "occupation_description": "01"
            },
            "is_local_resident": false,
            "financial_relation": {
                "products": [
                    {
                        "type": "SAVINGS_ACCOUNT",
                        "agency": "6272",
                        "number": "11188222",
                        "subtype": "INDIVIDUAL",
                        "check_digit": "4",
                        "clearing_code": "123"
                    },
                    {
                        "type": "CHECKING_ACCOUNT",
                        "agency": "6272",
                        "number": "94088392",
                        "subtype": "INDIVIDUAL",
                        "check_digit": "4",
                        "clearing_code": "123"
                    }
                ],
                "start_date": "2020-05-21T12:00:00Z",
                "procurators": [
                    {
                        "type": "ATTORNEY",
                        "civil_name": "NA",
                        "social_name": "NA",
                        "document_number": "76109277673"
                    }
                ],
                "product_services": [
                    "CHECKING_ACCOUNT"
                ],
                "product_services_additional_info": "Additional Information"
            },
            "additional_documents": [
                {
                    "type": "DRIVERS_LICENSE",
                    "number": "58438287",
                    "issue_date": null,
                    "check_digit": "P",
                    "additional_info": "SSP/RS",
                    "expiration_date": "2025-05-21",
                    "country_of_issuance": null,
                    "type_additional_info": "NA"
                },
                {
                    "type": "PASSPORT",
                    "number": "34229643119827236458",
                    "issue_date": "2018-05-24",
                    "check_digit": null,
                    "additional_info": null,
                    "expiration_date": "2022-05-24",
                    "country_of_issuance": "CAN",
                    "type_additional_info": null
                }
            ],
            "internal_identification": "9455ce84-f978-480e-be11-435119568b5d",
            "marital_status_additional_info": null
        }
    ]
}
ParameterTypeRequiredDescriptionExample
idstringtrueThe link_id you receive in your historical_update notification.2f8ca7a1-c28f-46f2-bb41-21633099a280

Get Account information

Belvo will asynchronously retrieve the last 12 months of account data for your link and then send you a webhook once the information is ready to retrieve (see the webhook example below):

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "ACCOUNTS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f8ca7a1-c28f-46f2-bb41-21633099a280",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_accounts": 5 // Total number of accounts found.
  }
}

Once you receive the webhook, you just need to make the following GET Accounts request to retrieve the data for the given link:

curl --request GET 'https://api.belvo.com/api/accounts/?link={id}' \
-u [Secret Key ID]:[Secret Key PASSWORD]
ParameterTypeRequiredDescriptionExample
idstringtrueThe link_id you receive in your historical_update notification.2f8ca7a1-c28f-46f2-bb41-21633099a280

Get Transaction information

Belvo will asynchronously retrieve the last 12 months of transaction data for your link and then send you a webhook once the information is ready to retrieve (see the webhook example below):

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "TRANSACTIONS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f8ca7a1-c28f-46f2-bb41-21633099a280",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_transactions": 19, // Total number of transactions found
    "total_inflow_transactions": 10, // Total number of inflow transactions
    "total_outflow_transactions": 9, // Total number of outflow transactions
    "first_transaction_date": "2017-01-03", // First transaction date
    "last_transaction_date": "2020-03-25" // Last transaction date
  }
}

Once you receive the webhook, you just need to make the following GET Transactions request to retrieve the data for the given link:

curl --request GET 'https://api.belvo.com/api/transactions/?link={id}' \
-u [Secret Key ID]:[Secret Key PASSWORD]
ParameterTypeRequiredDescriptionExample
idstringtrueThe link_id you receive in your historical_update notification.2f8ca7a1-c28f-46f2-bb41-21633099a280

Get Bill information

Belvo will asynchronously retrieve the last 12 months bill data for your link and then send you a webhook once the information is ready to retrieve (see the webhook example below):

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "BILLS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_bills": 2 // Total number of bills
  }
}

Once you receive the webhook, you just need to make the following GET Bills request to retrieve the data for the given link:

curl --request GET 'https://api.belvo.com/api/bills/?link={id}' \
-u [Secret Key ID]:[Secret Key PASSWORD]
ParameterTypeRequiredDescriptionExample
idstringtrueThe link_id you receive in your historical_update notification.2f8ca7a1-c28f-46f2-bb41-21633099a280

Recurrent updates

If you are using recurrent links, you will receive webhook events according to the frequency you established with Belvo (daily, weekly, monthly, and so on). Belvo sends the following webhook events for updates:

  • new_owners_available
    You will receive a new_owners_available webhook whenever we detect that there has been a change in account owners details. For more information, please see our dedicated Owners (Aggregation) webhook article.
  • new_accounts_available
    You will receive a new_accounts_available webhook whenever we detect that there has been a change in the accounts that the link has. For more information, please see our dedicated Accounts (Aggregation) webhook article.
  • new_transactions_available
    You will receive a new_transactions_available webhook whenever we detect that new transactions have occurred for any account the link has. For more information, please see our dedicated Transactions (Aggregation) webhook article.
  • new_bills_available
    You will receive a new_bills_available webhook whenever a new credit card bill statements has been generated for a billing period. For more information, please see our dedicated Bills (Aggregation) webhook article.


As soon as you receive a webhook about newly updated information, you just need to make the same GET call as you did for the historical update to receive the updated information.

# Retrieve owner data
curl --request GET 'https://api.belvo.com/api/owners/?link={id}'

# Retrieve account data
curl --request GET 'https://api.belvo.com/api/accounts/?link={id}'

# Retrieve transaction data
curl --request GET 'https://api.belvo.com/api/transactions/?link={id}'

# Retrieve bill data
curl --request GET 'https://api.belvo.com/api/bills/?link={id}'

Other webhook events

Belvo also notifies you when there are changes to your link's consent. You may receive the following webhooks relating to consents:

  • openfinance_consent_expired
  • openfinance_consent_with_unrecoverable_resources
  • openfinance_consent_with_temporarily_unavailable_resources

For the openfinance_consent_expired events, you can prompt your user to renew their consent using the My Belvo Portal. For more information, please see our dedicated Consent webhook article.


Adding a link to My Belvo Portal

Regulatory Requirement
According to Open Finance regulations, your users must have an easy-to-access way of managing their consents within your application or website.

Belvo has created the My Belvo Portal (MBP) that allows users to manage their consents in a simple and straightforward way, meeting all the requirements of the regulations.

In your application, you must include a clearly visible link to the MBP for your users to manage their consents.

The MBP can be set up in three different ways:

  • Public MBP
    On Belvo's website, we host a universal instance of the MBP that any user can use to manage their consents. This instance consolidates all the consents they have granted using Belvo's OFDA product. You simply need to redirect your user to https://meuportal.belvo.com/?mode=landing, where they can input their details. Your user will be able to see all the consents they’ve granted using Belvo (including other applications using Belvo to extract data from Brazil's Open Finance Network).
  • Customized MBP
    You can customize the MBP to display only the consents that your user has granted your application, making it easier for them to manage the consents.
  • Consent Renewal Mode
    The MBP can also be used to renew an expired consent. Belvo will send you a webhook when one of your user's consent's has expired.
Dedicated My Belvo Portal Guide
For details on how to set up the My Belvo Portal in your application, see our dedicated My Belvo Portal (OFDA) guide.

Additional resources

Integration checklist

We have created a dedicated checklist of all the things you should take into consideration when developing your OFDA integration. Check it out here: OFDA Integration Checklist.