> ## Documentation Index
> Fetch the complete documentation index at: https://docs.filexpress.app/llms.txt
> Use this file to discover all available pages before exploring further.

# API Introduction

> Connect your system to FileXpress: authentication, permissions, response format and errors

The FileXpress External API lets third-party systems (POS, ERP, online stores, biometric clocks, payroll or BI systems) integrate with a FileXpress business to:

* **Billing**: issue sales, record purchases and manage customers, suppliers and products.
* **Human Resources**: query employees and payrolls, send attendance punches, configure labor rules, schedules and holidays, check schedule compliance and create leave requests.
* **Accounting**: query the chart of accounts and financial statements (also by cost center), manage cost centers and create draft journal entries.
* **Inventory**: query stock, movements, lots and alerts, record adjustments and transfer between branches.
* **Projects**: query projects with their financial summary, create them and link documents to them.
* **Accounts receivable and payable**: query outstanding balances, record or reverse customer collections and supplier payments, and create banks, petty cash funds and checkbooks.
* **Pricing and promotions**: query and sync price lists, and calculate promotions on a cart.
* **Cash register**: open and close the register with a cash count, record income and expenses, and query closings.

## Base URL

```
https://api.filexpress.app/api/external/v1
```

The paths in this documentation are relative to that URL, except those in the [API v2](https://docs.filexpress.app/en/docs/api/v2/introduccion.md) section, which use `https://api.filexpress.app/api/external/v2`. Request and response bodies are JSON (`Content-Type: application/json`).

If your integration still uses the unversioned path, migrating only requires changing the base URL: endpoints, bodies, responses, permissions and API Key do not change.

## Versioning

The External API is published by major version in the path prefix:

| Base URL | Status |
| - | - |
| `/api/external/v1` | Current version. Contains all the endpoints in this documentation. |
| `/api/external` (unversioned) | Legacy alias of v1, with the same endpoints. **It will be retired on January 1, 2027.** |
| `/api/external/v2` | Available. Exposes only the endpoints that change: currencies and exchange rates (`GET /currencies`, `GET /exchange-rates`, `GET /exchange-rates/resolve`), countries and capabilities (`GET /countries/{code}`), sales (`POST /sales`, `GET /sales/{id}`), purchases (`POST /expenses`, `GET /expenses/{id}`) and `GET /health`. Everything else stays in v1. See [API v2](https://docs.filexpress.app/en/docs/api/v2/introduccion.md). |

Within a version, only endpoints or optional fields are added; a breaking change (removing or renaming fields or paths, changing their meaning) is published in a new version and announced in advance. Your integration must ignore response fields it does not recognize.

## Migrate to v2

> [!WARNING]
>
> We **suggest** migrating to the available v2 paths (sales, purchases and currencies) **before March 30, 2027**. This is a recommendation, not a retirement: v1 keeps working. The only thing being retired is the **unversioned** path (`/api/external`), on **January 1, 2027**; those integrations must move at least to `/api/external/v1`.

v2 adds multi-currency, taxes by id and errors with a stable code. It only changes the endpoints listed below; the rest of your integration stays on `/api/external/v1` and you can use both versions with the same API Key.

| v1 | v2 | Differences |
| - | - | - |
| `POST /sales` | `POST /sales` | Accepts `currency_code` and `exchange_rate` (amounts in the document currency). `products[].tax_ids` is required (it can be `[]`). Taxes are validated in strict mode: an amount that differs from the recalculated one returns `422` `tax_invalid`. The response adds `currency_code`, `exchange_rate`, `foreign_total` and `base_currency_code`. |
| `GET /sales/{id}` | `GET /sales/{id}` | Adds the same currency fields. |
| `POST /expenses` | `POST /expenses` | Accepts `currency_code` and `exchange_rate`. `products[].tax_ids` is required and the ids must exist. The response adds the currency fields. |
| `GET /expenses/{id}` | `GET /expenses/{id}` | Adds the same currency fields. |
| Does not exist | `GET /currencies` | Base currency and active currencies. Requires the `currencies` permission. |
| Does not exist | `GET /exchange-rates` | The business's exchange rates. Requires `currencies`. |
| Does not exist | `GET /exchange-rates/resolve` | The rate that would be applied to a document. Requires `currencies`. |
| Does not exist | `GET /countries/{code}` | Documents, taxes, payment methods and capabilities of a country. Requires the `countries` permission. See [Countries and capabilities](https://docs.filexpress.app/en/docs/api/v2/paises.md). |
| `GET /health` | `GET /health` | No changes. |
| Any other endpoint | No equivalent in v2 | Stays in v1. |

To migrate a client that already issues sales and purchases:

1. Change the base URL of those endpoints to `https://api.filexpress.app/api/external/v2`.
2. Add `tax_ids` to each `products` line (use `[]` if no tax applies).
3. In sales, calculate taxes, withholdings and income tax exactly: v2 rejects anything that does not match the server's recalculation. See [Taxes by id](https://docs.filexpress.app/en/docs/api/v2/ventas.md#taxes-by-id).
4. If you will issue in a foreign currency, send `currency_code` (and `exchange_rate` if you set your own rate). To query the active currencies and their rates before issuing, the integration also needs the `currencies` permission; issuing only requires `sales` or `expenses`.
5. Handle errors by `code` instead of the `message` text. See [errors and codes](https://docs.filexpress.app/en/docs/api/v2/introduccion.md#errors-and-codes).

> [!NOTE]
>
> v1 **does not accept currency**: it ignores `currency_code` and `exchange_rate`, and its amounts are always in the business's base currency. [Accounts receivable](https://docs.filexpress.app/en/docs/api/cuentas-por-cobrar.md) and [accounts payable](https://docs.filexpress.app/en/docs/api/cuentas-por-pagar.md) (v1) now return the document's currency reference (`currency_code`, `base_currency_code`, `exchange_rate`, `foreign_total`, `foreign_balance`) without changing their amounts, which remain in the base currency.

## Try the API

Each endpoint has a page in the **Interactive reference** with a *playground*: you enter your API Key, fill in the parameters and run the real request from the browser. Each page includes code examples (cURL, JavaScript, Python and PHP) and examples of successful and error responses.

> [!WARNING]
>
> The playground sends **real** requests to your API Key's business. Use an integration from the [test environment](#test-environment) to experiment, never the production one.

## Postman collection

If you prefer Postman, download the collection with all the endpoints (grouped by module, with sample bodies and saved responses) and its environment:

* [Collection: FileXpress-API-Externa.postman\_collection.json](https://docs.filexpress.app/api-reference/postman/FileXpress-API-Externa.postman_collection.json)
* [Environment: FileXpress-API-Externa.postman\_environment.json](https://docs.filexpress.app/api-reference/postman/FileXpress-API-Externa.postman_environment.json)

Import both files into Postman (**Import**), select the **FileXpress API Externa** environment and fill in the `api_key` variable. Authentication is defined once in the collection and all requests inherit it. Requests are real: use an integration from the [test environment](#test-environment).

## Test environment

FileXpress does not use a different URL for testing: the environment is defined by the **business** the integration belongs to.

| Environment | Use | Electronic documents |
| - | - | - |
| **Testing** (`00`) | Development and integration | Transmitted to the Ministry of Finance (Hacienda) test environment. **They have no tax validity.** |
| **Production** (`01`) | Real operation | Transmitted to the Ministry of Finance (Hacienda) with tax validity. |

To develop your integration:

**1. Ask support for a business in the test environment**

Write to [soporte@filexpress.app](mailto:soporte@filexpress.app) with the name of your integration and the modules you will use.

**2. Create an integration in that business and use its API Key in your development and in the playground**

**3. When going to production, create the integration in the real business**

Only the API Key changes: the URL and endpoints are the same.

> [!TIP]
>
> A business's current environment is shown in **Support → Company Information → Environment**.

## Authentication

Every request must include the integration's **API Key** in the `X-API-Key` header:

```bash theme={null}
curl https://api.filexpress.app/api/external/v1/branches \
  -H "X-API-Key: fx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"
```

The API Key is obtained when you create the integration in FileXpress (**Integrations → New Integration**), where you also assign its permissions. See [External Integrations](https://docs.filexpress.app/en/docs/gestion/integraciones.md).

> [!WARNING]
>
> Store the API Key as a secret: anyone who has it can operate with the integration's permissions. If it is exposed, regenerate it from FileXpress; the previous one stops working immediately.

## Data scope

An integration belongs to **one business**. All queries and writes are automatically limited to that business: an ID from another business returns `404`, just like a nonexistent one.

### Get the branches (`branch_id`)

Many endpoints require the branch's `branch_id`. This endpoint requires no permissions:

```http theme={null}
GET /branches
```

```json theme={null}
{
  "status": true,
  "data": [
    {
      "id": "9d1c5a3e-...",
      "name": "Casa Matriz",
      "code": "M001P001",
      "establishment_code": "M001",
      "points_of_sale": [
        { "id": "7c20...", "code": "P001", "name": "Caja principal", "is_default": true, "is_active": true }
      ]
    }
  ]
}
```

Each branch includes its establishment code and its points of sale. See [Branches and points of sale](https://docs.filexpress.app/en/docs/api/puntos-de-venta.md).

## Permissions

Each integration can only use the endpoint groups assigned to it. If it calls one without permission, it receives `403` with the required permission:

```json theme={null}
{
  "status": false,
  "message": "This integration does not have the 'hr.employees' permission.",
  "required_scope": "hr.employees"
}
```

| Module | Permission | Endpoints |
| - | - | - |
| Billing | `sales` | [Sales](https://docs.filexpress.app/en/docs/api/facturacion/ventas.md) (issue, query and list) and [Sales v2](https://docs.filexpress.app/en/docs/api/v2/ventas.md) |
| Billing | `expenses` | [Purchases](https://docs.filexpress.app/en/docs/api/facturacion/compras.md) and [Purchases v2](https://docs.filexpress.app/en/docs/api/v2/compras.md) |
| Billing | `currencies` | [Currencies and exchange rates](https://docs.filexpress.app/en/docs/api/v2/monedas-y-tasas.md) (v2 only) |
| Billing | `customers` | [Customers](https://docs.filexpress.app/en/docs/api/facturacion/clientes.md) |
| Billing | `providers` | [Suppliers](https://docs.filexpress.app/en/docs/api/facturacion/proveedores.md) |
| Billing | `products` | [Products](https://docs.filexpress.app/en/docs/api/facturacion/productos.md) |
| Billing | `branches.write` | [Points of sale](https://docs.filexpress.app/en/docs/api/puntos-de-venta.md#create-point-of-sale) (create and edit) |
| HR | `hr.employees` | [Employees](https://docs.filexpress.app/en/docs/api/rrhh/empleados.md) (query and positions) |
| HR | `hr.employees.write` | [Employees](https://docs.filexpress.app/en/docs/api/rrhh/empleados.md#create-employee) (create and edit) |
| HR | `hr.attendances` | [Attendance](https://docs.filexpress.app/en/docs/api/rrhh/asistencia.md) |
| HR | `hr.labor_rules` | [Labor rules](https://docs.filexpress.app/en/docs/api/rrhh/reglas-laborales.md) (query and templates) |
| HR | `hr.labor_rules.write` | [Labor rules](https://docs.filexpress.app/en/docs/api/rrhh/reglas-laborales.md#create-rules) (configuration) |
| HR | `hr.schedules` | [Schedules](https://docs.filexpress.app/en/docs/api/rrhh/horarios.md) (query and assignments) |
| HR | `hr.schedules.write` | [Schedules](https://docs.filexpress.app/en/docs/api/rrhh/horarios.md#create-a-schedule) (configuration and bulk assignment) |
| HR | `hr.holidays` | [Holidays](https://docs.filexpress.app/en/docs/api/rrhh/feriados.md) |
| HR | `hr.holidays.write` | [Holidays](https://docs.filexpress.app/en/docs/api/rrhh/feriados.md#create-a-day-off) (holidays and exclusions) |
| HR | `hr.attendance_results` | [Attendance results](https://docs.filexpress.app/en/docs/api/rrhh/resultados-asistencia.md) (includes querying overtime approvals) |
| HR | `hr.overtime.approve` | [Overtime approval](https://docs.filexpress.app/en/docs/api/rrhh/resultados-asistencia.md#overtime-approval) (approve fully or partially or reject, individually or in bulk) |
| HR | `hr.leave_requests` | [Leave and vacations](https://docs.filexpress.app/en/docs/api/rrhh/permisos.md) |
| HR | `hr.payrolls` | [Payrolls](https://docs.filexpress.app/en/docs/api/rrhh/planillas.md) |
| HR | `hr.payrolls.write` | [Payrolls](https://docs.filexpress.app/en/docs/api/rrhh/planillas.md#assign-cost-center) (payroll and per-employee cost center) |
| Accounting | `accounting.accounts` | [Chart of accounts and periods](https://docs.filexpress.app/en/docs/api/contabilidad/catalogo.md) |
| Accounting | `accounting.journal_entries` | [Journal entries](https://docs.filexpress.app/en/docs/api/contabilidad/partidas.md) and querying [entry types](https://docs.filexpress.app/en/docs/api/contabilidad/partidas.md#journal-entry-types) |
| Accounting | `accounting.entry_types.write` | [Entry types](https://docs.filexpress.app/en/docs/api/contabilidad/partidas.md#create-entry-type) (create, edit and delete or deactivate) |
| Accounting | `accounting.reports` | [Financial statements](https://docs.filexpress.app/en/docs/api/contabilidad/reportes.md) (includes cost center reports, in JSON, PDF or Excel) |
| Accounting | `accounting.cost_centers` | [Cost centers](https://docs.filexpress.app/en/docs/api/contabilidad/centros-de-costo.md) and [distributions](https://docs.filexpress.app/en/docs/api/contabilidad/centros-de-costo.md#distributions) (query) |
| Accounting | `accounting.cost_centers.write` | [Cost centers](https://docs.filexpress.app/en/docs/api/contabilidad/centros-de-costo.md#create-cost-center) and [distributions](https://docs.filexpress.app/en/docs/api/contabilidad/centros-de-costo.md#create-distribution) (create, edit and delete) |
| Accounting | `accounting.budgets` | [Budgets](https://docs.filexpress.app/en/docs/api/contabilidad/presupuestos.md) and budget vs actual report (query) |
| Accounting | `accounting.budgets.write` | [Budgets](https://docs.filexpress.app/en/docs/api/contabilidad/presupuestos.md#create-budget) (create, edit, monthly lines, status and delete) |
| Inventory | `inventory.read` | [Inventory](https://docs.filexpress.app/en/docs/api/inventario.md) (queries) |
| Inventory | `inventory.adjustments` | [Inventory adjustments](https://docs.filexpress.app/en/docs/api/inventario.md#register-an-adjustment) |
| Inventory | `inventory.transfers` | [Transfers](https://docs.filexpress.app/en/docs/api/inventario.md#create-a-transfer) (create, complete, cancel) |
| Projects | `projects` | [Projects](https://docs.filexpress.app/en/docs/api/proyectos.md) (query and summary) |
| Projects | `projects.write` | [Projects](https://docs.filexpress.app/en/docs/api/proyectos.md#create-project) (create, edit and link) |
| Accounts receivable and payable | `receivables` | [Accounts receivable](https://docs.filexpress.app/en/docs/api/cuentas-por-cobrar.md) (query) |
| Accounts receivable and payable | `receivables.payments` | [Record collections](https://docs.filexpress.app/en/docs/api/cuentas-por-cobrar.md#register-payment) and [reverse them](https://docs.filexpress.app/en/docs/api/cuentas-por-cobrar.md#reverse-payment) |
| Accounts receivable and payable | `payables` | [Accounts payable](https://docs.filexpress.app/en/docs/api/cuentas-por-pagar.md) (query) |
| Accounts receivable and payable | `payables.payments` | [Record payments](https://docs.filexpress.app/en/docs/api/cuentas-por-pagar.md#register-payment) and [reverse them](https://docs.filexpress.app/en/docs/api/cuentas-por-pagar.md#reverse-payment) |
| Accounts receivable and payable | `treasury` | [Banks, petty cash funds and checkbooks](https://docs.filexpress.app/en/docs/api/tesoreria.md) (query) |
| Accounts receivable and payable | `treasury.write` | [Create and edit banks, petty cash funds and checkbooks](https://docs.filexpress.app/en/docs/api/tesoreria-alta.md) |
| Pricing and promotions | `pricing` | [Pricing and promotions](https://docs.filexpress.app/en/docs/api/precios-promociones.md) (query and promotion calculation) |
| Pricing and promotions | `pricing.write` | [Update prices](https://docs.filexpress.app/en/docs/api/precios-promociones.md#update-prices) |
| Cash register | `cash_register` | [Cash register](https://docs.filexpress.app/en/docs/api/caja.md) (open register and closings) |
| Cash register | `cash_register.operate` | [Operate the register](https://docs.filexpress.app/en/docs/api/caja.md#open-a-cash-register) (open, movements and closing) |
| — | No permission | `GET /branches` and [catalogs](https://docs.filexpress.app/en/docs/api/facturacion/catalogos.md) |

> [!NOTE]
>
> The `branches.write` permission and those for HR, Accounting, Inventory, Projects, Accounts receivable/payable, Pricing and promotions and Cash register expose personal, salary and financial data, or move balances and stock. They are never granted by default, not even to existing integrations with full access: the business administrator must enable them one by one in **External integrations**.

## Response format

The **HR, Accounting, Inventory, Projects, Accounts receivable and payable** modules and the **sales, purchases and branches** endpoints respond:

```json theme={null}
// Éxito
{ "status": true, "data": { } }

// Error
{ "status": false, "message": "Validation errors", "errors": { "start_date": ["The start date field is required."] } }
```

The **customers, suppliers, products and catalogs** endpoints use the legacy format:

```json theme={null}
// Éxito
{ "success": true, "data": { }, "message": "Data retrieved successfully." }

// Error de validación (código 404)
{ "success": false, "message": "Validation Error.", "data": { "email": ["The email field is required."] } }
```

**v2** paths add a stable `code` to errors: `{ "status": false, "code": "currency_not_enabled", "message": "...", "errors": { } }`. See [v2 errors and codes](https://docs.filexpress.app/en/docs/api/v2/introduccion.md#errors-and-codes).

### Paginated lists

The lists of employees, journal entries, stock, movements, lots, transfers and projects are paginated (`per_page`; `page` to navigate) and return:

```json theme={null}
{
  "status": true,
  "data": {
    "data": [ ],
    "pagination": { "current_page": 1, "last_page": 4, "per_page": 50, "total": 187 }
  }
}
```

### Dates and amounts

* Dates: `YYYY-MM-DD`. Times: `HH:MM` in 24-hour format.
* Amounts: decimal numbers with 2 places, in the business's base currency. In v2, documents can be sent in another active currency (`currency_code`); see [API v2](https://docs.filexpress.app/en/docs/api/v2/introduccion.md#how-currency-works).

## Status codes

| Code | Meaning |
| - | - |
| `200` / `201` | Success (`201` when a resource is created) |
| `401` | The `X-API-Key` header is missing or the key is not valid |
| `403` | The integration is disabled or does not have the endpoint's permission |
| `404` | Resource does not exist or belongs to another business |
| `409` | Conflict (for example, a leave request that overlaps an existing one, or a reused [`Idempotency-Key`](#idempotency)) |
| `422` | Validation error: check `errors` |
| `429` | Rate limit exceeded |
| `500` | Internal error: report it to support with the time of the request |

## Idempotency

Writes that move money or stock (collections, payments and their reversals, inventory adjustments and transfers, project creation, register opening, movements and closing) accept the optional `Idempotency-Key` header. **We recommend always sending it** on those `POST` requests: if the network fails and you retry, the operation is not applied twice.

```bash theme={null}
curl -X POST https://api.filexpress.app/api/external/v1/receivables/payments   -H "X-API-Key: fx_xxxxxxxx"   -H "Idempotency-Key: cobro-2026-10-06-000123"   -H "Content-Type: application/json"   -d '{ ... }'
```

| Situation | Result |
| - | - |
| First request with the key | Runs normally. If it responds `2xx`, the response is stored for **24 hours**. |
| Retry with the same key and the same body | Returns the original response without running the operation again, with the `Idempotent-Replayed: true` header. |
| Same key with a different body or endpoint | `409` — `This Idempotency-Key was already used with a different request.` |
| Two simultaneous requests with the same key | The second responds `409` — `A request with this Idempotency-Key is already being processed.` |
| The original request failed (`4xx`/`5xx`) | It is not stored: you can fix it and retry with the same key. |

* The key is per integration and allows up to 100 characters (longer responds `422`). Use a unique value per operation, for example a UUID or the document's ID in your system.
* Without the header, every request always runs.

## Rate limit

Each integration has a requests-per-minute limit defined by FileXpress (100 by default). When exceeded, the API responds `429`:

```json theme={null}
{ "status": false, "message": "Rate limit exceeded. Please try again later.", "rate_limit": 100 }
```

Wait a few seconds and retry with exponential *backoff*. If your use case needs a higher limit, request it from [support](mailto:soporte@filexpress.app).

## Call log

Every call is recorded in FileXpress (endpoint, method, response code, duration and errors). The business administrator can review it in **Integrations → Logs / Statistics**, which makes it easier to diagnose integration problems.

## Check the connection

```http theme={null}
GET /health
```

Responds `Working` without requiring authentication. It also exists in v2 (`GET /api/external/v2/health`).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.