# Extract Fiscal Information in Mexico (API)
In this guide, we walk you through everything you need to extract fiscal data about your users using our API. This includes:
- A general overview of the data flow
- Creating a link using our API
- Getting fiscal information:
- Historical updates (all links)
- Recurrent updates (recurrent links only)
## Prerequisites
Before you proceed with your integration, make sure that you have Gone through our getting started guide. In the getting started guide, you will 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 where possible.
## General flow of data
Belvo uses *asynchronous workflows* to improve your data flow (check the diagram below).
Whenever you create a link, Belvo automatically extracts all the fiscal data for you in the background, and once we have all the data, we notify you via a webhook that the data is ready to be retrieved.
```mermaid
sequenceDiagram
participant App as Application
participant Belvo as Belvo
participant Institution as Fiscal Institution
App->>Belvo: POST /links/
Note over App,Belvo: fetch_resources=[INVOICES, TAX_RETURNS ...]
Belvo->>Institution: Connect and confirm the provided credentials
Belvo-->>App: 201 - Link Created + Link ID
Belvo->>Institution: Belvo retrieves historical information for the Link ID
Note over App,Institution: For each resource listed in fetch_resources, you will
receive a historical_update webhook.
Belvo->>App: WEBHOOK: historical_update (INVOICES)
App->>Belvo: GET /invoices/?link={id}
Belvo-->>App: 200 + Invoice Details
Note over App,Institution: If using recurrent links, at the scheduled refresh frequency
you will receive a new_{resource}_available webhook.
Belvo->>App: WEBHOOK: new_tax_returns_available
App->>Belvo: GET /tax-returns/?link={link.id}
Belvo-->>App: 200 + Tax Return Details
```
## Create a link
What's a link?
A link is Belvo's term for a connection between your user (RFC) and the fiscal institution (SAT). Whenever you want to extract information from a new user, you will need to create a link.
To create a link, you just need to make the following **POST Register a new link** request:
Sandbox
```curl Sandbox Request URL
curl --location 'https://sandbox.belvo.com/api/links/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic BASE64(SECRET_ID:SECRET_PASSWORD)' \
--data '{see_example_below}'
```
```json Sandbox Request Body
{
"institution": "tatooine_mx_fiscal",
"username": "PFIS010101000",
"password": "individual",
"access_mode": "single",
"credentials_storage": "store",
"stale_in": "300d",
"external_id": "HJLSI-897809",
"fetch_resources": [
"FINANCIAL_STATEMENTS",
"INVOICES",
"TAX_RETENTIONS",
"TAX_RETURNS",
"TAX_STATUS",
"TAX_COMPLIANCE_STATUS"
]
}
```
Production
```curl Production Request URL
curl --location 'https://api.belvo.com/api/links/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic BASE64(SECRET_ID:SECRET_PASSWORD)' \
--data '{see_example_below}'
```
```json Production Request Body
{
"institution": "sat_mx_fiscal",
"username": "username",
"password": "password",
"access_mode": "single",
"credentials_storage": "store",
"stale_in": "300d",
"external_id": "HJLSI-897809",
"fetch_resources": [
"FINANCIAL_STATEMENTS",
"INVOICES",
"TAX_RETENTIONS",
"TAX_RETURNS",
"TAX_STATUS",
"TAX_COMPLIANCE_STATUS"
]
}
```
| Parameter | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `institution` | string | true | The institution where you want to create the link. You can choose either:- `tatooine_mx_fiscal` for Sandbox
- `sat_mx_fiscal` for Production
| `tatooine_mx_fiscal` |
| `username` | string | true | The username of the individual or business. If you're testing out in our Sandbox environment, you can use the following credentials to mock data:- **individuals**:`PFIS010101000`
- **businesses**:`PMO010101000`
| `PFIS010101000` |
| `password` | string | true | The password of the individual or business. If you're testing out in our Sandbox environment, you can use the following credentials to mock data:- **individuals**: `individual`
- **businesses**: `business`
| `individual` |
| `access_mode` | string | true | The type of link to create (`single` or `recurrent`). For fiscal data, we recommend using `recurrent` links as you will receive updates regarding any new invoices or | `recurrent` |
| `credentials_storage` | string | false | The `credentials_storage` parameter allows you to control for how long Belvo stores the encrypted login credentials. For more information, check out the credentials_storage section of our Data retention controls article. | `store` |
| `stale_in` | string | false | The `stale_in` parameter allows you to control for how long Belvo stores user-derived data. For more information, check out the stale_in section of our Data retention controls article. | `300d` |
| `external_id` | string | highly recommended | Your internal reference for this user. This is extremely useful as you can the data that Belvo retrieves for this user in your system. | `COHORT_32_User_6790023X5` |
| `fetch_resources` | array | true | The resources you want Belvo to retrieve. For fiscal institutions, we recommend: `["FINANCIAL_STATEMENTS", "INVOICES", "TAX_RETENTIONS", "TAX_RETURNS", "TAX_STATUS", "TAX_COMPLIANCE_STATUS"]` | `["FINANCIAL_STATEMENTS", "INVOICES", "TAX_RETENTIONS", "TAX_RETURNS", "TAX_STATUS", "TAX_COMPLIANCE_STATUS"]` |
Once you create a link, you will need to save the `id` of the link that your receive in the response:
```json Example Link Response
{
"id": "2f8ca7a1-c28f-46f2-bb41-21633099a280", // <-- Save this ID.
"institution": "tatooine_mx_fiscal",
"access_mode": "single",
"status": "valid",
"refresh_rate": null,
"created_by": "6e9be884-4781-4143-b673-aca02475ee8c",
"last_accessed_at": "2024-06-26T16:25:54.344113Z",
"external_id": "HJLSI-897809",
"created_at": "2024-06-26T16:25:54.334413Z",
"institution_user_id": "BidIxnZkKvQx0_F0oSYVx6Jnsh4Zmoat2ot2iOoG018=",
"credentials_storage": "store",
"stale_in": null,
"fetch_resources": [
"FINANCIAL_STATEMENTS",
"INVOICES",
"TAX_RETENTIONS",
"TAX_RETURNS",
"TAX_STATUS",
"TAX_COMPLIANCE_STATUS"
]
}
```
**Done**! Belvo will now connect to the institution and asynchronously load the data for the resources your requested in `fetch_resources`. We will send you a webhook once we have retrieved the data for the given link, and you can then extract it with a **GET** request
## Wait for webhooks to get historical fiscal data
As soon as you create your fiscal link, Below will asynchronously retrieve historical data for each resource you added in the `fetch_resources` array. As soon as Belvo retrieves the data, you will receive a webhook indicating that the data is ready to be retrieved:
| Resource | Number of Webhooks | Webhook Code |
| --- | --- | --- |
| `FINANCIAL_STATEMENTS` | 1 | `historical_update` |
| `INVOICES` | 4-8 | `initial_inflow_update`, `initial_outflow_update`, `historical_inflow_update`, `historical_outflow_update` |
| `TAX_RETENTIONS` | 1 | `historical_update` |
| `TAX_RETURNS` | 2 | `historical_update` |
| `TAX_STATUS` | 1 | `historical_update` |
| `TAX_COMPLIANCE_STATUS` | 1 | `historical_update` |
### Financial Statements
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 Code | Description |
| --- | --- |
| historical_update | The last three years of financial statements. |
In the webhook payload we include the number of financial statements received.
```json Financial Statements Historical Update Example
{
"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:
```shell Financial Statements Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
'https://api.belvo.com/api/financial-statements/?link=link_id'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `link` | The `link_id` you received in the webhook notification. | `2f8ca7a1-c28f-46f2-bb41-21633099a280` |
### Invoices
Due to the number of invoices an individual or business may have, and to optimize the extraction process, you will receive several different types of Invoice webhooks after you create the link.
#### Last 30 days of data
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 Code | Description |
| --- | --- |
| `initial_inflow_update` | The last 30 days of INFLOW (received) invoices. |
| `initial_outflow_update` | The 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.
Invoices Initial Inflow Update Example
```json Invoices Initial Inflow Update Example
{
"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"
}
}
```
Invoices Initial Outflow Update Example
```json Invoices Initial Outflow Update Example
{
"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 Invoices Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
# Request Inflow Invoices
'https://api.belvo.com/api/invoices/?type=INFLOW&link=link_id&invoice_date__range=first_invoice_date,last_invoice_date'
# Request Outflow Invoices
'https://api.belvo.com/api/invoices/?type=OUTFLOW&link=link_id&invoice_date__range=first_invoice_date,last_invoice_date'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `type` | The 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` |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
| `invoice_date__range` | The 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` |
#### Last 3 years of data
As soon as your fiscal recurrent link is created, we asynchronously load the last three years of INFLOW and OUTFLOW invoice history from SAT. After the initial 30 days, for each of the last three years, you will receive up to two webhook notifications: one for inflow invoices (`historical_inflow_update`) and one for outflow invoices (`historical_outflow_update`). This means you could receive up to 6 additional webhook notifications for the historical data.
**For each year Belvo extracts data for**, you will receive the following webhooks:
| Webhook Code | Description |
| --- | --- |
| `historical_inflow_update` | The last 1 year of INFLOW (received) invoices. |
| `historical_outflow_update` | The 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.
Invoices Historical Inflow Update Example
```json Invoices Historical Inflow Update Example
{
"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
}
}
```
Invoices Historical Outflow Update Example
```json Invoices Historical Outflow Update Example
{
"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 Invoices Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
# Request Inflow Invoices
'https://api.belvo.com/api/invoices/?type=INFLOW&link=link_id&invoice_date__range=first_invoice_date,last_invoice_date'
# Request Outflow Invoices
'https://api.belvo.com/api/invoices/?type=OUTFLOW&link=link_id&invoice_date__range=first_invoice_date,last_invoice_date'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `type` | The 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` |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
| `invoice_date__range` | The 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` |
### Tax Retentions
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 Code | Description |
| --- | --- |
| `historical_update` | The 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.
```json Tax Retentions Historical Update
{
"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:
```shell Tax Retentions Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
'https://api.belvo.com/api/tax-retentions/?link=link_id'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
### Tax Returns
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 Code | Description |
| --- | --- |
| `historical_update` | The last 5 years of yearly tax returns. |
| `historical_update` | The 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.
Tax Returns Yearly Historical Update
```json Tax Returns Yearly Historical Update
{
"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 yearly tax returns found
"first_tax_return_year": 2017, // First filed yearly tax return
"last_tax_return_year": 2018 // Last filed yearly tax return
}
}
```
Tax Returns Monthly Historical Update
```json Tax Returns Monthly Historical Update
{
"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 monthly tax returns found
"first_tax_return_year": 2017, // First filed monthly tax return
"last_tax_return_year": 2017 // Last filed monthly tax return
}
}
```
Once you receive the notification, you can get further details by making the following request:
```shell Tax Returns Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
'https://api.belvo.com/api/tax-returns/?link=link_id&ejercicio__range=first_tax_return_year,last_tax_return_year'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
| `ejercicio__range` | The 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` |
### Tax Status
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 Code | Description |
| --- | --- |
| `historical_update` | The 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.
```json Tax Status Historical Update
{
"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 status documents
"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:
```shell Tax Status Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
'https://api.belvo.com/api/tax-status/?link=link_id'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
### Tax Compliance Status
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 Code | Description |
| --- | --- |
| `historical_update` | The current Tax Compliance Status for the user. |
In the webhook payload you will receive the total number of Tax Compliance Status documents.
```json Tax Compliance Status Historical Update
{
"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:
```shell Tax Compliance Status Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
'https://api.belvo.com/api/tax-compliance-status/?link=link_id'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
## Recurring updates
If you created a recurrent link (using `access_mode: recurrent`), you will receive webhooks for updated resources based on the refresh rate you established with Belvo (see the diagram in the General flow of data section).
The following webhooks are available for recurrent links:
| Resource | Number of Webhooks | Webhook Code |
| --- | --- | --- |
| `INVOICES` | 2-4 | `new_invoices_available`, `invoices_cancelled` |
| `TAX_RETURNS` | 2 | `new_tax_returns_available` |
### Invoices
According to your chosen refresh rate, Belvo will asynchronously retrieve data about any new or cancelled invoices that have appeared in the SAT system for a given link since the last update.
#### New Invoices
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 Code | Description |
| --- | --- |
| `new_invoices_available` | A 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 `id`s.
```json New Invoices Recurrent Update
{
"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:
```shell Invoices Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
'https://api.belvo.com/api/invoices/?link=link_id&id__in=invoice_id_1,invoice_id_2,invoice_id_3'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
| `id__in` | The list of invoice `id`s 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 Code | Description |
| --- | --- |
| `invoices_cancelled` | A 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 `id`s.
```json Cancelled Invoices Recurrent Update
{
"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:
```shell Invoices Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
'https://api.belvo.com/api/invoices/?link=link_id&id__in=invoice_id_1,invoice_id_2,invoice_id_3'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
| `id__in` | The list of invoice `id`s you received in the `data.cancelled_invoices` of the webhook notification. | `24ccab1d-3a86-4136-a6eb-e04bf52b356f,beb2b197-3cf7-428d-bef3-f415c0d57509` |
### Tax Returns
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 Code | Description |
| --- | --- |
| `new_tax_returns_available` | A 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.
New Yearly Tax Returns Update
```json New Yearly Tax Returns Update
{
"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
}
}
```
New Monthly Tax Returns Update
```json New Monthly Tax Returns Update
{
"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:
```shell Tax Returns Get Request
curl --request GET \
-u SECRET_ID:SECRET_PASSWORD \
'https://api.belvo.com/api/tax-returns/?link=link_id&created_at__range=date1,date2'
```
| Query Parameter | Description | Example |
| --- | --- | --- |
| `link` | The `link_id` you received in the webhook notification. | `2f5d361d-dad6-45d4-a0bf-26d479766067` |
| `created_at__range` | The 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` |
## 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:
```json
[
{
"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.