Last updated

Aggregation Webhooks

A webhook is a web callback that Belvo uses to send notifications about a specific link. You will need to set up webhooks in order to use Belvo's APIs.

Set up webhooks

To set up a new webhook:

  1. In your Belvo dashboard, go to the data webhooks section.

  2. In the Data Webhooks tab, click +New webhook.

  3. Fill in the New webhook form with the required information.

    • URL: the URL to receive the webhook notifications.
    • Authorization: an optional authorization token to use if your URL is protected.
  4. Click Create webhook.

✳️ Done! The webhook is now set up and your application will be notified of new events related to your links.

Using Additional Authentication

For security reasons, you can add an additional layer of authentication to your webhook calls. When you create your webhook, in the Authentication (Optional) field, enter either:

  • Basic and a base64-encoded `username:password string (for Basic authentication)
  • Bearer and a token (for Bearer authentication)

Webhook types

All webhook events come with a core payload (as described in the code example).

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "ACCOUNTS",
  "process_type": "historical_update", // Indicates why the webhook was triggered
  "webhook_code": "historical_update", // Webhook type
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28", // Link
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id", // Your external ID for the link, if you provided one.
  "data": { 
    // Contents of the webhook. For more information, please see the relative Webhook type documentation.
    
  }
}
ParameterRequiredTypeDescriptionExample
webhook_idtruestringThe Belvo webhook ID.aadf41a1fc8e4f79a49f7f04027ac999
webhook_typetruestringThe resource that this webhook relates to.ACCOUNTS
process_typetruestringThe process_type parameter indicates why the webhook event was triggered. We return one of the following values:
  • historical_update: The webhook was triggered as we finished a historical update for the data retrieval (for recurrent links and for single links with fetch_resources).
  • recurrent_update: The webhook was triggered due to the recurrent (cyclical) refresh of the data.
  • async_post: The webhook was triggered as the asynchronous retrieval of data from a POST call is complete.
ACCOUNTS
webhook_codetruestringThe event that triggered the webhook.STATUS_UPDATE
object_idtruestringThe ID of the object this webhook relates to.d2e40773-19f6-48d1-93c3-3590ec0c74df
external_idtruestringThe unique identifier you provided when creating the object. For charges and transactions, this field will always return null.c3c51aaf-aaa3-400c-926d-87ab62e195fd
datatrueobjectAn object containing specific data about the event. The fields returned in this object depend on the webhook_type and webhook_code. For information about the data specific for a given webhook, please look at the dedicated page for each resource.{}

Webhook error events

Sometimes while retrieving information from an institution, an error can occur. In this case, the webhook event's data object will contain the error information that occurred. For example:

{
    "webhook_id": "5b82fdf536da43039c69a4305ecb1ceb",
    "webhook_type": "ACCOUNTS",
    "webhook_code": "historical_update",
    "link_id": "c7ba4551-ed8d-46ee-9b67-c864a77d6381",
    "external_id": "your_external_id",
    "data": {
        "errors": [ // Details of the error that occurred
            {
              "code": "service_unavailable",
              "message": "Belvo is unable to process the request due to an internal system issue or to an unsupported response from an institution"
            }
        ]
    }
}

Retry Policy

If Belvo initially calls your server and does not receive a 2XX HTTP status code, we will retry five times using a linear backoff to allow your server to recover from any malfunction.

Webhook Best Practices

Respond to webhooks

As soon as you receive a webhook from Belvo, make sure that you respond with 2XX HTTP status code. If we do not receive a 2XX response from your server, we will retry five times using a linear backoff to allow the your server to recover from any malfunction.

Whitelist outbound IP addresses

Whitelist IP Addresses

We highly recommend you whitelist these IP addresses so that you can receive webhook events.

You can receive webhook events from the following IP addresses:

  • 3.130.254.46
  • 18.220.61.186
  • 18.223.45.212

Testing webhook events

You can trigger any webhook event type (including link events) from your Belvo Dashboard. Once triggered, you will receive a payload with dummy data. This is an excellent way to test if you can receive webhooks, that you have correctly set up your authentication (if necessary), and act upon the various event types.

To trigger an event:

  1. From the Environment Switcher in your Belvo dashboard, select the environment you want to test your webhook in.
  2. Select the Webhooks tab.
  3. Click on the drop-down menu next to the Sandbox webhook URL you want to test.
  4. Select the webhook event type you want. This sends the webhook.
  5. Expand the status box to see details of the webhook event.

accounts

Historical update

As soon as your banking link is created, we asynchronously load the accounts available for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of accounts found for the link.

In the webhook payload we include the number of accounts found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "ACCOUNTS",
  "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_accounts": 5 // Total number of accounts found.
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/accounts/?link=link_id' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

New accounts available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new accounts that have appeared for the given link since the last update.

Webhook CodeDescription
new_accounts_availableThe number of new accounts found in the institution since the last update.

In the webhook payload we include the number of new accounts found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "ACCOUNTS",
  "process_type": "recurrent_update",
  "webhook_code": "new_accounts_available",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "new_accounts": 1 // New accounts found for the link
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/accounts/?link={id}' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

bills

Historical update

As soon as your banking recurrent link is created, we asynchronously load the bills available for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of bills found for the link.

In the webhook payload we include the number of bills found for the link.

{
  "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 notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/bills/?link=link_id' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

New bills available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new bills that have appeared for the given link since the last update.

Webhook CodeDescription
new_bills_availableThe number of new bills found in the institution since the last update.

In the webhook payload we include the number of new bills found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "BILLS",
  "process_type": "recurrent_update",
  "webhook_code": "new_bills_available",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "new_bills": 1 // Number of new bills
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/bills/?link=link_id&created_at__range=date1,date2' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
created_at__rangeThe date range you want to receive employments for. We recommend that date1 is the date when you previously received a notification and date2 is the date when you receive the current notification (both in YYYY-MM-DD format).2024-05-01,2024-06-01

consents

Only available for recurrent links

You will only receive CONSENT webhook events for recurrent links.

Opt-in to receive consent about to expire webhooks

If you would like to receive webhooks for consents that are about to expire, please reach out to our support team.

You can receive an openfinance_consent_about_to_expire event when the consent for one of your OFDA links will expire within seven days of the recurrent link's refresh.

For example, if you have a monthly refresh rate for a link that renews on the second day of each month, and the link's consent expiry date is the sixth of that month, you will receive an openfinance_consent_about_to_expire event. However, if you have another link that renews on the second day of each month but the consent expiry date is the tenth of that month, you will not receive an event.

Prompt your user to renew consent

Once you receive this event, you can prompt your user to renew their consent using the My Belvo Portal.

{
  "webhook_id": "37a084ee0741437fa7a95393b5636f7b",
  "webhook_type": "CONSENT",
  "process_type": "recurrent_update",
  "webhook_code": "openfinance_consent_about_to_expire",
  "link_id": "da9822bb-5bd6-4a0a-b64d-0aefcc9e86b0",
  "external_id": null,
  "data": {
    "consent_id": "9e763d19-15a4-410c-a106-18c0f60ca5eb", // The consent ID.
    "consent_due_date": "2024-12-26T10:45:58.000Z", // ISO-8601 timestamp of when the consent will expire.
    "action": "renew", // An indication of what action you need to take. For openfinance_consent_about_to_expire webhooks, this is always set to renew.
    "institution": "ofmockbank_br_retail", // The institution that the user provided their consent for.
    "institution_display_name": "OF Mockbank", // The display name of the institution.
    "institution_icon_logo": "https://logo.com" // The URL to the institution's logo.
  }
}

You can receive a consent_expired event when the consent for one of your OFDA links has expired.

Prompt your user to renew consent

Once you receive this event, you can prompt your user to renew their consent using the My Belvo Portal.

{
  "webhook_id": "e6f08793f967445fb74ce16beae665bc",
  "webhook_type": "CONSENT",
  "process_type": "recurrent_update",
  "webhook_code": "openfinance_consent_expired",
  "link_id": "3d3364b7-0175-483d-a58b-b471f251e533", // The link ID associated with the consent.
  "external_id": null,
  "data": {
    "consent_id": "29a54e55-21f0-4d02-8e34-797ab7d43940", // The consent ID.
    "action": "renew", // An indication of what action you need to take. For openfinance_consent_expired webhooks, this is always set to renew.
    "institution": "ofmockbank_br_retail", // The institution that the user provided their consent for.
    "institution_display_name": "OF Mockbank", // The display name of the institution.
    "institution_icon_logo": "https://logo.com" // The URL to the institution's logo.
  }
}

Once you receive the notification, you can prompt your user to renew their consent using the My Belvo Portal.

You can receive an openfinance_consent_with_unrecoverable_resources event when a consent has been revoked due to the pre-existing resources being unavailable. An example of when you may receive this event is when a user has granted their consent to access several accounts and at a later date closed those accounts.

{
  "webhook_id": "e6f08793f967445fb74ce16beae665bc",
  "webhook_type": "CONSENT",
  "process_type": "recurrent_update",
  "webhook_code": "openfinance_consent_with_unrecoverable_resources",
  "link_id": "da9822bb-5bd6-4a0a-b64d-0aefcc9e86b0",
  "external_id": null,
  "data": {
    "consent_id": "29a54e55-21f0-4d02-8e34-797ab7d43940", // The consent ID.
    "institution": "ofmockbank_br_retail", // The institution that the user provided their consent for.
    "message": "The consent was revoked because it was unrecoverable" // Error message regarding the revoked consent.
  }
}

You can receive an openfinance_consent_with_temporarily_unavailable_resources event when a consent is temporarily unavailable due to the pre-existing resources being unavailable. An example of when this may occur is when the user granted their consent to access a given account, but has not used that account for a while (the number of days until an account is marked as inactive depends on each institution).

{
  "webhook_id": "745156bbbd0d47b0a33ff995d7b4e5d8",
  "webhook_type": "CONSENT",
  "process_type": "recurrent_update",
  "webhook_code": "openfinance_consent_with_temporarily_unavailable_resources",
  "link_id": "da9822bb-5bd6-4a0a-b64d-0aefcc9e86b0",
  "external_id": null,
  "data": {
    "consent_id": "29a54e55-21f0-4d02-8e34-797ab7d43940", // The consent ID.
    "institution": "ofmockbank_br_retail", // The institution that the user provided their consent for.
    "message": "The consent is temporarily unusable" // Error message regarding the temporarilt unavailable consent.
  }
}

employment-metrics

Historical update

As soon as your employment link is created (for SAT Mexico) and you have added EMPLOYMENT_METRICS to the list of resources in fetch_resources, we asynchronously calculate the employment metrics for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of employment metrics generated for the link.

In the webhook payload we include the number of employment metrics found for the link.

{
  "webhook_id": "03d1ca0d62db4f769488265d141047b7",
  "webhook_type": "EMPLOYMENT_METRICS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_employment_metrics": 1 // The total number of employment metric reports generated
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/employment-metrics/?link=link_id' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

employment-records

Historical update

As soon as your employment link is created (for SAT Mexico), we asynchronously calculate the employment metrics for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of employment records found for the link.

In the webhook payload we include the number of bills found for the link.

{
  "webhook_id": "03d1ca0d62db4f769488265d141047b7",
  "webhook_type": "EMPLOYMENT_RECORDS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_employment_record_profiles": 1 // The total number of employment record profiles found for the link
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/employment-records/?link=link_id' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

Employment status changes

Interested in accessing this new feature?

Reach out to our team, and they’ll help you get set up!

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new changes in employment that have appeared for the given link since the last update.

Webhook CodeDescription
employment_changesA list of employment changes that have occurred for the link.

In the webhook payload we include the employment changes identified for the link.

{
  "webhook_id": "03d1ca0d62db4f769488265d141047b7",
  "webhook_type": "EMPLOYMENT_RECORDS",
  "process_type": "recurrent_update",
  "webhook_code": "employment_changes",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "employment_changes": ["EMPLOYED", "SALARY_INCREASED"] // List of changes since the last check
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/employment-records/?link=link_id' \
-u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

Employment change options

At your given refresh frequency, Belvo will extract new employment information for your link and compare the employment status and salary information with the previous data extraction.

Recommended refresh frequency

We recommend a refresh frequency of a minimum of two months. However, reach out to our team and they'll be able to advise you better depending on your use case.

In the data.employment_changes array of the webhook, you can receive one or more of the following employment changes:

ChangeDescription
UNEMPLOYEDThe employee was employed but was dismissed or resigned from their employer.
EMPLOYEDThe employee was unemployed at the time of the last check and is now employed.
EMPLOYEE_CHANGED_JOBSThe employee changed jobs.
SALARY_INCREASEThe employee's salary has increased by at least 10% since the last check.
SALARY_DECREASEThe employee's salary has decreased by at least 10% since the last check.

You can receive more than one change in the data.employment_changes array, depending on the situation. For example, if a person changed jobs and is now receiving a higher salary, then in the data.employment_changes array you will receive:

{
  "data": {
    "employment_changes": ["EMPLOYEE_CHANGED_JOBS", "SALARY_INCREASE"]
  }
}

Scenarios with deleted or missing records

Belvo sends employment notifications after comparing the newly retrieved data against previously-retrieved data. However, there can be cases where we update an employment link that does not have any employment record data in Belvo's database. In these cases, you will still receive an employment_changes webhook. However, as Belvo checks the newly returned data against non-existing data in Belvo's database, in this case you will receive one of the following combinations of employment changes:

Case when updatedValues
User is employedEMPLOYED, EMPLOYEE_CHANGED_JOBS, SALARY_INCREASE
User is unemployedUNEMPLOYED

This can occur due to any of the following reasons:

When creating a link, you can optionally add the stale_in parameter to control how long Belvo stores user-derived data. The period is relative to the link’s last_updated_at (the last time that the user’s account was accessed) timestamp.

For example, if you set stale_in to 62 days when you created a link on 01.03.2024, the data is stored in Belvo's database for 62 days after this date. If then for the same link you accessed the data a month later (01.04.2024), then the count is reset and Belvo will delete the data 62 days after 01.04.2024

However, if you set a stale_in period to less than your refresh rate, Belvo will delete the data before the next refresh. As a result, the newly returned data will be compared against non-existent data, triggering an employment_changes webhook with the statuses mentioned above.

To avoid this, either:

  • Do not pass the stale_in parameter (which by default is 365 days).
  • Set a stale_in value that is greater than your refresh rate. For example, if you have a refresh period of 60 days, then your stale_in parameter should be set to at least 62 days.

When doing a POST Retrieve employment records, you set save_data to false.

When retrieving employment record data using the Retrieve employment record details, setting save_data to false prevents Belvo from storing the data. Consequently, any newly retrieved data will be compared against non-existent data, resulting in the employment_changes webhook mentioned above.

To avoid this, we recommend that you set save_data to true.

Deleted employment record data

If you delete employment record data using the Delete an employment record request, all data for that employment entry is removed from Belvo's database. During the next update, Belvo compares the new data against the deleted (non-existing) data, resulting in the employment_changes webhook mentioned above.

There was no data in the initial extraction of employment record data

In the case that a previous employment record retrieval was not successful as there was no data for the user in the institution (resulting in the API returning an empty response) or the employment institution was unresponsive, during the next update, Belvo compares the new data against the non-existing data, resulting in the employment_changes webhook mentioned above.

employments-brazil

Historical update

As soon as your banking recurrent link is created, we asynchronously load the employment information available for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of employments found for the link.

In the webhook payload we include the number of employments found for the link.

{
  "webhook_id": "03d1ca0d62db4f769488265d141047b7",
  "webhook_type": "EMPLOYMENTS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_employments": 1 // The total number of employment record profiles found for the link
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/br/employments/?link={id}' \
-u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

New employments available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new employments that have appeared for the given link since the last update.

Webhook CodeDescription
new_accounts_availableThe number of new employments found since the last update.

In the webhook payload we include the number of new employments found for the link.

{
  "webhook_id": "03d1ca0d62db4f769488265d141047b7",
  "webhook_type": "EMPLOYMENTS",
  "process_type": "recurrent_update",
  "webhook_code": "new_employments_available",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "new_employments": 1 // Number of new employments found since last event
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/br/employments/?link={id}&created_at__range=date1,date2' \
-u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
created_at__rangeThe date range you want to receive employments for. We recommend that date1 is the date when you previously received a notification and date2 is the date when you receive the current notification (both in YYYY-MM-DD format).2024-05-01,2024-06-01

financial-statements-mexico

Historical update

As soon as your fiscal link is created, we asynchronously load the last three years of financial statements and will send you the following webhook:

Webhook CodeDescription
historical_updateThe last three years of financial statements.

In the webhook payload we include the number of financial statements received.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "FINANCIAL_STATEMENTS",
  "webhook_code": "historical_update",
  "process_type": "historical_update",
  "link_id": "2f8ca7a1-c28f-46f2-bb41-21633099a280",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "COHORT_32_User_6790023X5",
  "data": {
    "new_financial_statements": 3
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/financial-statements/?link=link_id'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

New financial statements available

Only applicable for asynchronous POST calls

When you make an "ad hoc" request for financial statements (with the X-Belvo-Request-Mode: async header), Belvo will asynchronously retrieve the financial statement information and send you the following webhook:

Webhook CodeDescription
new_financial_statements_availableThe number of new financial statements found for the link.

In the webhook payload we include the number of new financial statements found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "FINANCIAL_STATEMENTS",
  "webhook_code": "new_financial_statements_available",
  "process_type": "async_post",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "COHORT_32_User_6790023X5",
  "data": {
    "new_financial_statements": 1
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/financial-statements/?link=link_id'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

Errors while extracting Financial Statements

In order to provide you greater visibility regarding the extraction of Financial Statement data, we have included a new error field in the response payload for each financial statement you will still receive.

If, for a given year where a financial statement is available, we are not able to retrieve data due to the institution not providing the information in the correct format, the error field will indicate the reason behind the unsuccessful extraction:

[
  {
    "id": "0d3ffb69-f83b-456e-ad8e-208d0998d71d",
    "link": "30cb4806-6e00-48a4-91c9-ca55968576c8",
    "collected_at": "2022-02-09T08:45:50.406032Z",
    "created_at": "2022-02-09T08:45:50.406032Z",
    "error": "Unable to validate if the user has an available financial statement for the specified year.",
    "year": 2020,
    "currency": "MXN",
    "balance_sheet": null,
    "income_statement": null
  }
]

The possible error messages are:

  • Unable to validate if the user has an available financial statement for the specified year.
  • No available financial statement found for the user for the specified year, preventing data extraction.
  • Unable to verify if the user has _conceptos vigentes_ for the specified year.
  • The fiscal institution provided the financial statement in an unrecognized format.

If you receive financial statement payloads with these errors, please contact our support team.

incomes

Historical update

As soon as your banking link is created and you have added INCOMES to the list of resources in fetch_resources, we asynchronously calculate the income data for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of incomes and incomes streams identified for the link.

In the webhook payload we include the number of incomes and income streams identified for the link.

{
  "webhook_id": "75f0c2ca92e64f228da04cc7f5039c03",
  "webhook_type": "INCOMES",
  "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_incomes": 1, // Always = 1, Indicates that the analysis is ready for retrieval.
    "number_of_income_streams": 5, // Total number of income stream identified.
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/employment-metrics/?link=link_id' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

investment-transactions

Historical update

As soon as your banking link is created, we asynchronously load the investment transactions available for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of investment transactions for the link for the past year.

In the webhook payload we include the number of investment transactions found for the link (including the number of inflow and outflow transactions) as well as the date range that the information applies to.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "INVESTMENT_TRANSACTIONS",
  "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_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": "2023-01-03", // First transaction date
    "last_transaction_date": "2024-01-03" // Last transaction date
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/br/investment-transactions/?link=link_id'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

You can add further filters to narrow down the results, for example:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/br/investment-transactions/?link=link_id&type=INFLOW'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
typeThe type of transaction. Can be either INFLOW or OUTFLOW.INFLOW

New transactions available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new investment transactions that have appeared for the given link since the last update.

We define new investment transactions as transactions found in the institution for a given link since the last update. For example, these could be new investment transactions from the last 24 hours or new investment transactions from a few days ago that were only just added by the institution

Webhook CodeDescription
new_investment_transactions_availableThe number of new investment transactions found in the institution since the last update.

In the webhook payload we include the number of new transactions found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "INVESTMENT_TRANSACTIONS",
  "process_type": "recurrent_update",
  "webhook_code": "new_investment_transactions_available",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "new_investment_transactions": 19 // Number of new transactions found since last event
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/br/investment-transactions/?link=link_id&type=INFLOW&created_at__range=date1,date2'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
created_at__rangeThe date range you want to receive transactions for. We recommend that date1 is the date when you previously received a notification and date2 is the date when you receive the current notification (both in YYYY-MM-DD format).2024-05-01,2024-06-01

investments-webhooks

Historical update

As soon as your banking link is created, we asynchronously load the investment accounts available for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of investment accounts found for the link.

In the webhook payload we include the number of investment accounts found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "INVESTMENTS",
  "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_investments": 5 // Total number of investment accounts found.
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/br/investments/?link=link_id' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

New investment available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new investment accounts that have appeared for the given link since the last update.

Webhook CodeDescription
new_investments_availableThe number of new accounts found in the institution since the last update.

In the webhook payload we include the number of new accounts found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "ACCOUNTS",
  "process_type": "recurrent_update",
  "webhook_code": "new_investments_available",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "new_investments": 1 // New investment accounts found for the link
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/br/investments/?link={id}' \
  -u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

invoices

Initial updates

As soon as your fiscal recurrent link is created, we asynchronously load the last 30 days of invoice history. You will receive two notifications via a webhook whenever the last 30 days of invoices are available for you to access.

Webhook CodeDescription
initial_inflow_updateThe last 30 days of INFLOW (received) invoices.
initial_outflow_updateThe last 30 days of OUTFLOW (sent) invoices.

We include the number of invoices found during this period for the invoice type, as well as the dates for the first and last invoice in the range.

{
  "webhook_id": "ccc9c589bfcb44bc99ce749229ccf142",
  "webhook_type": "INVOICES",
  "process_type": "historical_update",
  "webhook_code": "initial_inflow_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_invoices": 3456,
    "first_invoice_date": "2021-04-05",
    "last_invoice_date": "2021-05-05"
  }
}
{
  "webhook_id": "ccc9c589bfcb44bc99ce749229ccf578",
  "webhook_type": "INVOICES",
  "process_type": "historical_update",
  "webhook_code": "initial_outflow_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "data": {
    "total_invoices": 3456,
    "first_invoice_date": "2021-04-05",
    "last_invoice_date": "2021-05-05"
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/invoices/?type=INFLOW&link=link_id&invoice_date__range=first_invoice_date,last_invoice_date'
curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/invoices/?type=OUTFLOW&link=link_id&invoice_date__range=first_invoice_date,last_invoice_date'
Query ParameterDescriptionExample
typeThe type of invoice. Can be either INFLOW or OUTFLOW. If you receive a initial_inflow_update webhook, this should be set to INFLOW. If you receive a initial_outflow_update webhook, this should be set to OUTFLOW.INFLOW
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
invoice_date__rangeThe date range that you want to get invoices for. This should be the first_invoice_date and last_invoice_date you received in the webhook notification.2017-07-31,2018-07-31

Historical updates

As soon as your fiscal recurrent link is created, we asynchronously load the last three years of INFLOW and OUTFLOW invoice history for SAT. You will receive up to 6 notifications via a webhook whenever the history of invoices is available for you to access. For each year Belvo extracts data for, you will receive the following webhooks:

Webhook CodeDescription
historical_inflow_updateThe last 1 year of INFLOW (received) invoices.
historical_outflow_updateThe last 1 year of OUTFLOW (sent) invoices.

In the webhook payload we include the number of invoices found during this period for the invoice type, as well as the dates for the first and last invoice in the range.

{
  "webhook_id": "ccc9c589bfcb44bc99ce749229ccf142",
  "webhook_type": "INVOICES",
  "process_type": "historical_update",
  "webhook_code": "historical_inflow_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_invoices": 5333, // Total number of invoices found
    "first_invoice_date": "2017-07-31", // First inflow invoice found
    "last_invoice_date": "2018-07-31" // Last inflow invoice found
  }
}
{
  "webhook_id": "1ac2917cb25f4e38af9260c0782d3408",
  "webhook_type": "INVOICES",
  "process_type": "historical_update",
  "webhook_code": "historical_outflow_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "data": {
    "total_invoices": 1000,
    "first_invoice_date": "2017-07-31",
    "last_invoice_date": "2018-07-31"
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/invoices/?type=INFLOW&link=link_id&invoice_date__range=first_invoice_date,last_invoice_date'
curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/invoices/?type=OUTFLOW&link=link_id&invoice_date__range=first_invoice_date,last_invoice_date'
Query ParameterDescriptionExample
typeThe type of invoice. Can be either INFLOW or OUTFLOW. If you receive a historical_inflow_update webhook, this should be set to INFLOW. If you receive a historical_outflow_update webhook, this should be set to OUTFLOW.INFLOW
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
invoice_date__rangeThe date range that you want to get invoices for. This should be the first_invoice_date and last_invoice_date you received in the webhook notification.2017-07-31,2018-07-31

New invoices available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new invoices that have appeared in the SAT system for a given link since the last update.

Webhook CodeDescription
new_invoices_availableA list of new invoices that were retrieved since the last update.

You can receive a new_invoices_available notification whenever new invoices are available for a fiscal recurrent link. You can receive more than one webhook event for a link at a time, depending on the type of invoices found. For example, you might receive a webhook event for INFLOW invoices and a separate one for OUTFLOW invoices.

We define new invoices as all new invoices found in the institution for this link since our last update. For example, if you have a daily refresh rate, it could be the new invoices from the last 24 hours or invoices added by the institution in the past 24 hours for previous days

In the webhook payload we include the number of invoices found since the last refresh, the type of invoices (INFLOW or OUTFLOW), as well as an array of invoice ids.

{
  "webhook_id": "28364bef400f4374a80872b61ba204289",
  "webhook_type": "INVOICES",
  "process_type": "recurrent_update",
  "webhook_code": "new_invoices_available",
  "link_id": "0284557b-df47-450a-po09e-7875195c2259",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "count": 5,
    "type": "INFLOW",
    "new_invoices": [
      // An array of invoice IDs
      "7d0afe4c-373d-490c-90e4-06xx4cdd4a17",
      "a53759bc-ca02-46f0-b1d5-31xxcd54db41",
      "64ecc7df-f322-4934-82f5-3b3ae675ef4a",
      "0452ae0d-ax2f-4093-888c-bb2ae826xa0b",
      "9c266fff-ee3d-4389-adb3-1c5690d3c032"
    ]
  }
}

Once you receive the notification, you can get further details for the new invoices by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/invoices/?link=link_id&id__in=invoice_id_1,invoice_id_2,invoice_id_3'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
id__inThe list of invoice ids you received in the data.new_invoices of the webhook notification.24ccab1d-3a86-4136-a6eb-e04bf52b356f,beb2b197-3cf7-428d-bef3-f415c0d57509

Cancelled invoices

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any cancelled invoices that have appeared in the SAT system for a given link since the last update.

Webhook CodeDescription
invoices_cancelledA list of cancelled invoices that were retrieved since the last update.

We define canceled invoices as all existing invoices with a new "canceled" status in the institution for this link

In the webhook payload we include the type of cancelled invoices (INFLOW or OUTFLOW) as well as an array of invoice ids.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "INVOICES",
  "process_type": "recurrent_update",
  "webhook_code": "invoices_cancelled",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "type": "INFLOW",
    "cancelled_invoices": [
      // An array of invoice IDs
      "0a362860-c92f-4414-a731-a772e88ab54b",
      "0a376126-c23r-2131-b745-a876d77cd76c"
    ]
  }
}

Once you receive the notification, you can get further details for the cancelled invoices by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/invoices/?link=link_id&id__in=invoice_id_1,invoice_id_2,invoice_id_3'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
id__inThe list of invoice ids you received in the data.cancelled_invoices of the webhook notification.24ccab1d-3a86-4136-a6eb-e04bf52b356f,beb2b197-3cf7-428d-bef3-f415c0d57509
Widget Update Mode

We really recommend that you use our Connect Widget with Update Mode after your receive a Link webhook event to handle the credentials or token update.

Invalid credentials

You can receive an invalid_credentials notification whenever a user's credentials are no longer valid to update a recurrent link. This can happen when a user changes their bank credentials.

Once you receive this notification, you can ask your user to update their new password using the Connect widget in Update Mode. As soon as the credentials are correct, the recurrent link is refreshed.

If you are not using the Connect Widget, you can ask your user to send you their new password and then perform a Link Update request to save the new password. For example, if you receive the following webhook:

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "LINK",
  "process_type": "recurrent_update",
  "webhook_code": "invalid_credentials",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "error_code": "login_error", // Webhook event error
    "error_message": "Invalid credentials provided to login to the institution", // Descriptive message of the error
    "status": 400
  }
}

Once you receive the required credentials from your user, make a PUT request to our Links endpoint with the updated details:

curl -X PUT https://api.belvo.com/api/links/{id} \
  -H 'Content-Type: application/json' \
  -H 'Host: api.belvo.com' \
  -H 'cache-control: no-cache' \
  -d '{
      "password": "{user_provided_password}"
  }' \
  -u [Secret Key ID]:[Secret Key PASSWORD]

Where:

  • {id} is the link_id your receive in the webhook notification.
  • {user_provided_password} is the updated password you receive from your user.

Token required

You can receive a token_required notification whenever a new MFA token is required by the institution to keep the recurrent link working.

Once you receive this notification, you can ask your user to provide a new token using the Connect widget in update mode. As soon as the token is provided, the recurrent link is refreshed.

Please note that until the link is updated, Belvo will not send any webhook relating to this link.

If you are not using the Connect Widget, you can ask your user to send you their new password and then perform a Link Update request to provide the new MFA token. For example, if you receive the following webhook:

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "LINK",
  "process_type": "recurrent_update",
  "webhook_code": "token_required",
  "link_id": "30cb4806-6e00-48a4-91c9-ca55968576c8",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "error_code": "token_required", // Webhook event error
    "error_message": "MFA token was required by the institution", // Descriptive message of the error
    "status": 428,
    "session": "2675b703b9d4451f8d4861a3eee54449",
    "expiry": 9600,
    "token_generation_data": {
      "instructions": "Use this code to generate the token",
      "type": "numeric",
      "value": "12345"
    }
  }
}

Once you receive the required token credentials from your user, make a PATCH request to our Links endpoint with the updated token:

curl -X PATCH https://api.belvo.com/api/links/ \
  -H 'Content-Type: application/json' \
  -H 'Host: api.belvo.com' \
  -H 'cache-control: no-cache' \
  -d '{
    "session": "{sessionId}",
    "token": "{userToken}",
    "link": "{linkId}"
}' \
  -u [Secret Key ID]:[Secret Key PASSWORD]

Where:

  • {sessionId} is the session you receive in the webhook notification.
  • {userToken} is the new token you receive from your user.
  • {linkId} is the link_id your receive in the webhook notification.

owners

Historical update

As soon as your banking link is created, we asynchronously load the owner information available for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of owners found for the link.

In the webhook payload we include the number of owners found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "OWNERS",
  "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_owners": 2 // Total number of owners
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/owners/?link=link_id' \
-u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

New owners available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new accounts that have appeared for the given link since the last update.

Webhook CodeDescription
new_owners_availableThe number of new owners found since the last update.

In the webhook payload we include the number of new owners found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "OWNERS",
  "process_type": "recurrent_update",
  "webhook_code": "new_owners_available",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "new_owners": 1 // Number of new owners
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/owners/?link=link_id' \
-u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

recurring-expenses

Historical update

As soon as your banking link is created and you have added RECURRING_EXPENSES to the list of resources in fetch_resources, we asynchronously calculate the recurring expense data for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of recurring expenses identified for the link.

In the webhook payload we include the number of recurring expenses identified for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "RECURRING_EXPENSES",
  "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_recurring_expenses": 23 // Count of identified recurring expenses.
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/recurring-expenses/?link=link_id' \
-u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

risk-insights

Historical update

As soon as your banking link is created and you have added RISK_INSIGHTS to the list of resources in fetch_resources, we asynchronously generate the risk insights for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of risk insights identified for the link.

In the webhook payload we include the number of risk insights identified for the link.

{
  "webhook_id": "58577409546a4247848055e1e11bbc71",
  "webhook_type": "RISK_INSIGHTS",
  "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_risk_insights": 1 // Always = 1, Indicates that the analysis is ready for retrieval.
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/risk-insights/?link=link_id' \
-u [Secret Key ID]:[Secret Key PASSWORD]
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

tax-compliance-status

Historical update

As soon as your fiscal link is created, we asynchronously retrieve the Tax Compliance Status (Opinión de Cumplimiento de Obligaciones Fiscales) document and will send you the following webhook:

Webhook CodeDescription
historical_updateThe current Tax Compliance Status for the user.

In the webhook payload you will receive the total number of Tax Compliance Status documents.

{
  "webhook_id": "03d1ca0d62db4f769488265d141047b7",
  "webhook_type": "TAX_COMPLIANCE_STATUS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_tax_compliance_status": 1 // The total number of tax compliance statement documents
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/tax-compliance-status/?link=link_id'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

tax-declarations

Historical update

As soon as your fiscal link for Colombia is created, we asynchronously load the last year of tax declaration information for the link. You will receive a historical_update notification whenever the tax declaration history is available for you to access.

{
  "webhook_id": "80fa38b7cad34950b210626abd86bfe9",
  "webhook_type": "TAX_DECLARATIONS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_tax_returns": 2, // Total number of tax declarations found
    "first_tax_declaration_date": 2021, // Date of the first tax declaration found
    "last_tax_declaration_date": 2022 // Date of the last tax declaration found
  }
}
{
  "webhook_id": "80fa38b7cad34950b210626abd866549",
  "webhook_type": "TAX_RETURNS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "data": {
    "type": "monthly", // either yearly or monthly
    "total_tax_returns": 7, // Total number of tax returns found
    "first_tax_return_year": 2017, // First filed tax return
    "last_tax_return_year": 2018 // Last filed tax return
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET 'https://api.belvo.com/api/tax-declarations/?link={id}' \
-u [Secret Key ID]:[Secret Key PASSWORD]

Where:

  • {id} is the link_id you receive in your historical_update notification.

tax-retentions

Historical update

As soon as your fiscal link is created, we asynchronously load the last one year of tax retentions and will send you the following webhook:

Webhook CodeDescription
historical_updateThe last one year of Tax Retentions.

In the webhook payload we include the total number of tax retentions found for the last year, along with the date range that we retrieved data for.

{
  "webhook_id": "03d1ca0d62db4f769488265d141047b7",
  "webhook_type": "TAX_RETENTIONS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_tax_retentions": 1, // The total number of tax retentions
    "first_tax_retention_date": "2023-06-01", // The date of the first tax retention found
    "last_tax_retention_date": "2023-08-20" // The date of the last tax retention found
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/tax-retentions/?link=link_id'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

tax-returns

Historical update

As soon as your fiscal link is created, we asynchronously load the last five years of yearly tax returns as well as the 12 months of monthly tax returns. You will receive a historical_update notification for each type of tax return (yearly and monthly) whenever the tax return history is available for you to access.

Webhook CodeDescription
historical_updateThe last 5 years of yearly tax returns.
historical_updateThe last 12 months of monthly tax returns.

In the webhook payload we include the type of tax returns, total number of tax returns found, as well as the first and last year of the retrieved tax returns.

{
  "webhook_id": "80fa38b7cad34950b210626abd86bfe9",
  "webhook_type": "TAX_RETURNS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "type": "yearly", // either yearly or monthly
    "total_tax_returns": 2, // Total number of tax returns found
    "first_tax_return_year": 2017, // First filed tax return
    "last_tax_return_year": 2018 // Last filed tax return
  }
}
{
  "webhook_id": "80fa38b7cad34950b210626abd866549",
  "webhook_type": "TAX_RETURNS",
  "process_type": "historical_update",
  "webhook_code": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "type": "monthly", // either yearly or monthly
    "total_tax_returns": 7, // Total number of tax returns found
    "first_tax_return_year": 2017, // First filed tax return
    "last_tax_return_year": 2018 // Last filed tax return
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/tax-returns/?link=link_id&ejercicio__range=first_tax_return_year,last_tax_return_year'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
ejercicio__rangeThe date range that you want to get tax returns for. This should be the first_tax_return_year and last_tax_return_year you received in the webhook notification.2017,2020

New tax returns available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new tax returns that have appeared in the SAT system for a given link since the last update.

Webhook CodeDescription
new_tax_returns_availableA count of new tax returns since the last update.

You can receive a new_tax_returns_available notification whenever new tax returns are available for a fiscal recurrent link. You can receive more than one webhook event for a link at a time, depending on the type of tax returns found. For example, you might receive a webhook event for monthly tax returns and a separate one for yearly tax returns.

We define new tax returns as all new tax returns found in the institution for this link since our last update. It could be new tax returns from the last year or also tax returns that were added by the institution for previous years or months

In the webhook payload we include the the type of tax returns (monthly or yearly) as well as the number of tax returns found since the last refresh.

{
  "webhook_id": "351610c401e34e728900495fda5b970a",
  "webhook_type": "TAX_RETURNS",
  "process_type": "recurrent_update",
  "webhook_code": "new_tax_returns_available",
  "link_id": "331ba983-0cfa-4186-93fc-936f3946cca3",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "type": "yearly", // can be either yearly or monthly
    "new_tax_returns": 1 // Total number of new tax returns found
  }
}
{
  "webhook_id": "351610c401e34e728900495fda5b970a",
  "webhook_type": "TAX_RETURNS",
  "process_type": "recurrent_update",
  "webhook_code": "new_tax_returns_available",
  "link_id": "331ba983-0cfa-4186-93fc-936f3946cca3",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "type": "monthly", // can be either yearly or monthly
    "new_tax_returns": 1 // Total number of new tax returns found
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/tax-returns/?link=link_id&created_at__range=date1,date2'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
created_at__rangeThe date range you want to receive tax returns for. We recommend that date1 is the date when you previously received a notification and date2 is the date when you receive the current notification (both in YYYY-MM-DD format).2024-05-01,2024-06-01

tax-status

Historical update

As soon as your fiscal link is created, we asynchronously retrieve the Tax Status (Constancia de Situación Fiscal) document and will send you the following webhook:

Webhook CodeDescription
historical_updateThe latest Tax Status for the user.

In the webhook payload you will receive the total number of Tax Status documents for the user along with the last date that the Tax Status was updated.

{
  "webhook_id": "03d1ca0d62db4f769488265d141047b7",
  "webhook_type": "TAX_STATUS",
  "webhook_code": "historical_update",
  "process_type": "historical_update",
  "link_id": "2f5d361d-dad6-45d4-a0bf-26d479766067",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "total_tax_status": 1, // Number of tax statuses
    "last_status_change_date": "1995-08-01" // Year when the tax status was last changed
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/tax-status/?link=link_id'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

transactions

Historical update

As soon as your banking link is created, we asynchronously load the transactions available for the link and will send you the following webhook:

Webhook CodeDescription
historical_updateThe total number of transactions for the link for the past year.

In the webhook payload we include the number of transactions found for the link (including the number of inflow and outflow transactions) as well as the date range that the information applies to.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "TRANSACTIONS",
  "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_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": "2023-01-03", // First transaction date
    "last_transaction_date": "2024-01-03" // Last transaction date
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/transactions/?link=link_id'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067

You can add further filters to narrow down the results, for example:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/transactions/?link=link_id&type=INFLOW&value_date__range=first_transaction_date,last_transaction_date'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
typeThe type of transaction. Can be either INFLOW or OUTFLOW.INFLOW
value_date__rangeThe date range that you want to get transactions for. This should be the first_transaction_date and last_transaction_date you received in the webhook notification.2023-01-03,2024-01-03

New transactions available

According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new transactions that have appeared for the given link since the last update.

We define new transactions as transactions found in the institution for a given link since the last update. For example, these could be new transactions from the last 24 hours or new transactions from a few days ago that were only just added by the institution

Webhook CodeDescription
new_transactions_availableThe number of new transactions found in the institution since the last update.

In the webhook payload we include the number of new transactions found for the link.

{
  "webhook_id": "aadf41a1fc8e4f79a49f7f04027ac999",
  "webhook_type": "TRANSACTIONS",
  "process_type": "recurrent_update",
  "webhook_code": "new_transactions_available",
  "link_id": "16f68516-bcbc-4cf7-b815-c500d4204e28",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "new_transactions": 19 // Number of new transactions found since last event
  }
}

Once you receive the notification, you can get further details by making the following request:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/transactions/?link=link_id&type=INFLOW&created_at__range=date1,date2'
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
created_at__rangeThe date range you want to receive transactions for. We recommend that date1 is the date when you previously received a notification and date2 is the date when you receive the current notification (both in YYYY-MM-DD format).2024-05-01,2024-06-01

Transaction updated

This webhook is available for both single and recurrent links

Whenever Belvo identifies that a transaction has been updated in the institution (for example, a change to the description field or the value date), and will send you the following webhook:

Webhook CodeDescription
transactions_updatedThe number of transactions updated along with the list of transaction IDs.

In the webhook payload we include the number of transactions that were updated along with a list of Belvo transaction IDs.

{
  "webhook_id": "28364bef400f4374a80872b61ba204289",
  "webhook_type": "TRANSACTIONS",
  "process_type": "recurrent_update",
  "webhook_code": "transactions_updated",
  "link_id": "0284557b-df47-450a-po09e-7875195c2259",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "count": 5, // Total number of transactions updated.
    "updated_transactions": [
      "7d0afe4c-373d-490c-90e4-06xx4cdd4a17", // The ID of the updated transaction.
      "a53759bc-ca02-46f0-b1d5-31xxcd54db41",
      "64ecc7df-f322-4934-82f5-3b3ae675ef4a",
      "0452ae0d-ax2f-4093-888c-bb2ae826xa0b",
      "9c266fff-ee3d-4389-adb3-1c5690d3c032"
    ]
  }
}

Once you receive the notification, you can pull the complete list of transactions for that link using the following call:

curl --request GET \
-u [Secret Key ID]:[Secret Key PASSWORD] \
'https://api.belvo.com/api/transactions/?link=link_id&id__in=transaction1,transaction2,transaction3
Query ParameterDescriptionExample
linkThe link_id you received in the webhook notification.2f5d361d-dad6-45d4-a0bf-26d479766067
id__inThe list of transaction ids you received in the data.updated_transactions of the webhook notification.7d0afe4c-373d-490c-90e4-06xx4cdd4a17,53759bc-ca02-46f0-b1d5-31xxcd54db41,64ecc7df-f322-4934-82f5-3b3ae675ef4a

Changes that trigger a transactions_updated webhook

Belvo monitors the following fields for all transactions and when it detects a change between the last time it retrieved data and now, it will send you a transactions_updated webhook:

  • amount
  • currency
  • description
  • value_date
  • internal_identification
  • type
  • status
  • credit_card_data.bill_internal_identification (OFDA only)
  • credit_card_data.credit_card_bill.id (OFDA only)

Transaction deleted

This webhook is available for both single and recurrent links

Belvo regularly monitors and cleans transactional data in its database to improve the consistency of the data you receive. When a transaction is identified to be duplicated (which can occur, for example, due to POST calls made in quick succession to the API for the same link), it is removed from the database. In this case, you will receive a transactions_deleted webhook with a list of the transactions that have been deleted.

{
  "webhook_id": "28364bef400f4374a80872b61ba204289",
  "webhook_type": "TRANSACTIONS",
  "process_type": "recurrent_update",
  "webhook_code": "transactions_deleted",
  "link_id": "0284557b-df47-450a-po09e-7875195c2259",
  "request_id": "4363b08b-51eb-4350-9c74-5df5ac92a7f6",
  "external_id": "your_external_id",
  "data": {
    "count": 5, // Total number of transactions deleted.
    "deleted_transactions": [
      "7d0afe4c-373d-490c-90e4-06xx4cdd4a17", // The ID of the deleted transaction.
      "a53759bc-ca02-46f0-b1d5-31xxcd54db41",
      "64ecc7df-f322-4934-82f5-3b3ae675ef4a",
      "0452ae0d-ax2f-4093-888c-bb2ae826xa0b",
      "9c266fff-ee3d-4389-adb3-1c5690d3c032"
    ]
  }
}

webhook-institution-status-webhook

Set up the webhook

To subscribe to the Institution Status webhook:

  1. Go to the Belvo Institution Status page.

  2. Click Subscribe to Updates.

  3. In the top navigation, click the <> icon.

  4. In the webhooks tab, provide the required information and click Subscribe.
    4.1 URL where you want to receive the webhook
    4.2 An email address to confirm the webhook URL.

  1. In the dialog, choose which institutions you want to receive updates about and click Save.

✳️Done! Now just confirm your email addr

$1
ess and you will start receiving webhook status events for the institutions you selected. But we hope that doesn't happen often 😉.

Webhook payload

In the webhook payload that you receive from statuspage.io, the key fields you should parse are:

FieldDescription
incident.nameIndicates the nature of the problem with the institution.
incident.statusThe current status of the incident is at the time of the webhook. Can be either: investigating identified monitoring resolved
components.statusThe severity of the institution's outage. Can be either: operational (everything is working) partial_outage (certain functionalities are unavailable) major_outage (institution is completely unavailable)
components.nameThe name of the institution that's affected.

The payload you receive is quite large, as you can see from the code sample below. However, if you parse the fields mentioned above, you'll have all the relevant information you need regarding the incident.

{
   "meta":{
      "unsubscribe":"http://institutions.belvo.com/?unsubscribe=73cj0w1mm121",
      "documentation":"https://help.statuspage.io/knowledge_base/topics/webhook-notifications",
      "generated_at":"2021-04-19T14:46:37.135Z"
   },
   "page":{
      "id":"3h4nklhdf7jr",
      "status_indicator":"major",
      "status_description":"Partial System Outage"
   },
   "incident":{
      "name":"bancoppel_mx_retail: Link creation and existing links operations are showing high error rates", // important
      "status":"investigating", // important
      "created_at":"2021-04-19T14:46:34.737Z",
      "updated_at":"2021-04-19T14:46:34.844Z",
      "monitoring_at":"None",
      "resolved_at":"None",
      "impact":"critical",
      "shortlink":"https://stspg.io/74hxzgnrmjnt",
      "scheduled_for":"None",
      "scheduled_until":"None",
      "scheduled_remind_prior":false,
      "scheduled_reminded_at":"None",
      "impact_override":"None",
      "scheduled_auto_in_progress":false,
      "scheduled_auto_completed":false,
      "metadata":{
      },
      "started_at":"2021-04-19T14:46:34.731Z",
      "id":"p3b3zhn5p0pz",
      "page_id":"3h4nklhdf7jr",
      "incident_updates":[
         {
            "status":"investigating",
            "body":"We are currently investigating this issue related to both link creation and POST calls.",
            "created_at":"2021-04-19T14:46:34.841Z",
            "wants_twitter_update":false,
            "twitter_updated_at":"None",
            "updated_at":"2021-04-19T14:46:34.841Z",
            "display_at":"2021-04-19T14:46:34.841Z",
            "deliver_notifications":true,
            "tweet_id":"None",
            "id":"m9dcv76z7jwf",
            "incident_id":"p3b3zhn5p0pz",
            "custom_tweet":"None",
            "affected_components":[
               {
                  "code":"1f4dxgqr6pkg",
                  "name":"🇲🇽 Retail banking - bancoppel_mx_retail",
                  "old_status":"operational",
                  "new_status":"major_outage"
               }
            ]
         }
      ],
      "postmortem_body":"None",
      "postmortem_body_last_updated_at":"None",
      "postmortem_ignored":false,
      "postmortem_published_at":"None",
      "postmortem_notified_subscribers":false,
      "postmortem_notified_twitter":false,
      "components":[
         {
            "status":"major_outage", // important
            "name":"bancoppel_mx_retail", // important
            "created_at":"2021-04-13T09:50:24.288Z",
            "updated_at":"2021-04-19T14:46:34.768Z",
            "position":5,
            "description":"None",
            "showcase":true,
            "start_date":"2021-04-13T00:00:00.000Z",
            "id":"1f4dxgqr6pkg",
            "page_id":"3h4nklhdf7jr",
            "group_id":"bqcwjbwjhvjt"
         }
      ]
   }
}