> ## 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.

# Branches and points of sale

> Establishment codes, points of sale and their DTE numbering

| Permission | Endpoints |
| - | - |
| No permission | `GET /branches` |
| `branches.write` | `POST /branches/{id}/points-of-sale`, `PUT /points-of-sale/{id}` |

> [!NOTE]
>
> `branches.write` is an **explicit** permission: it must be checked in **External integrations**; existing integrations do not receive it automatically.

Each branch has an **establishment code** (`M001` for the head office, `S001`, `S002`… for the others) and one or more **points of sale** (`P001`, `P002`…). Each point of sale keeps its own numbering of electronic documents. In **El Salvador**, the DTE control number is built from both codes:

```text theme={null}
DTE-01-M001P002-000000000000015
       └──┘└──┘
   establecimiento + punto de venta
```

In other countries the document number is defined by the tax authority (for example, series and authorization number in Guatemala, prefix and sequence of the DIAN resolution in Colombia, or the 20-digit sequence with branch and terminal in Costa Rica). See [Points of sale](https://docs.filexpress.app/en/docs/caja/puntos-de-venta.md). The `M001`/`P001` formats in the examples are those of El Salvador.

* Every branch always has **a default point of sale** (`P001` at the start). Sales that do not specify a point of sale and do not belong to a cash register session are issued with it.
* The default one cannot be deactivated.
* The establishment code and the default point of sale are managed from FileXpress (**Billing → Settings → Points of sale**). See [Points of sale](https://docs.filexpress.app/en/docs/caja/puntos-de-venta.md).

> [!WARNING]
>
> Establishment and point of sale codes must match those registered with the Ministry of Finance (Hacienda). Verify them before issuing from a new point of sale.

## List branches

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

No permission required. Returns the business's branches with their points of sale (the default first, then by code):

```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 },
        { "id": "7c31...", "code": "P002", "name": "Caja 2", "is_default": false, "is_active": true }
      ]
    },
    {
      "id": "9d1c5a40-...",
      "name": "Sucursal Santa Ana",
      "code": "S001P001",
      "establishment_code": "S001",
      "points_of_sale": [
        { "id": "7c42...", "code": "P001", "name": "Caja principal", "is_default": true, "is_active": true }
      ]
    }
  ]
}
```

| Field | Description |
| - | - |
| `establishment_code` | Establishment code registered with Hacienda. |
| `code` | Read-only: establishment code + default point of sale code. Kept for compatibility; to issue documents use `points_of_sale`. |
| `points_of_sale[].is_default` | Point of sale used when a sale does not specify another one. |
| `points_of_sale[].is_active` | Inactive ones cannot issue documents or open a cash register. |

## Create point of sale

```http theme={null}
POST /branches/{id}/points-of-sale
```

| Field | Type | Required | Description |
| - | - | - | - |
| `code` | string | Yes | Format `P` + 3 digits (`P002`). Unique within the branch. |
| `name` | string | Yes | Display name. Max. 100. |

```bash theme={null}
curl -X POST https://api.filexpress.app/api/external/v1/branches/9d1c5a3e-.../points-of-sale \
  -H "X-API-Key: fx_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"code":"P002","name":"Caja 2"}'
```

**Response `201`**

```json theme={null}
{
  "status": true,
  "data": {
    "id": "7c31...",
    "business_id": "5a10...",
    "branch_id": "9d1c5a3e-...",
    "code": "P002",
    "name": "Caja 2",
    "is_default": false,
    "is_active": true,
    "created_at": "2026-10-08T15:00:00.000000Z",
    "updated_at": "2026-10-08T15:00:00.000000Z",
    "current_session": null,
    "last_session": null
  }
}
```

When it is created, FileXpress generates its own numbering for each document type of the current year, starting at 1.

**Errors**

| Code | Cause |
| - | - |
| `404` | `Branch not found for this integration.` (nonexistent or belongs to another business). |
| `422` | `code`: `El código del punto de venta debe tener el formato P001.` / `Ya existe un punto de venta con ese código en la sucursal.` / validation. |

## Edit point of sale

```http theme={null}
PUT /points-of-sale/{id}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `name` | string | No | New name. Max. 100. |
| `is_active` | boolean | No | `false` to deactivate it. |

The code cannot be changed. Renaming a point of sale does not affect documents that were already issued.

```bash theme={null}
curl -X PUT https://api.filexpress.app/api/external/v1/points-of-sale/7c31... \
  -H "X-API-Key: fx_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"is_active":false}'
```

**Response `200`**: the point of sale with the same fields as when it was created.

| Field | Description |
| - | - |
| `current_session` | Cash register session open at the point of sale (`id`, `opening_date`, `opening_amount`, `opened_by_user`) or `null`. |
| `last_session` | Most recent session, open or closed (`id`, `status`, `opening_date`, `closing_date`, `opened_by_user`, `closed_by_user`) or `null`. |

**Errors**

| Code | Cause |
| - | - |
| `404` | `Point of sale not found.` (nonexistent or belongs to another business). |
| `422` | `is_active`: `No se puede desactivar el punto de venta predeterminado.` / `El punto de venta tiene un turno de caja abierto.` / validation. |

## Use the point of sale

* [Create sale](https://docs.filexpress.app/en/docs/api/facturacion/ventas.md#create-sale): optional field `point_of_sale_id`.
* [Open cash register](https://docs.filexpress.app/en/docs/api/caja.md#open-a-cash-register): `point_of_sale_id`, mandatory if the branch has more than one active point of sale.

## Errors

| Code | When |
| - | - |
| `401` | Missing or invalid API key. |
| `403` | The integration does not have the `branches.write` permission. |
| `404` | Branch or point of sale nonexistent or belonging to another business. |
| `422` | Validation or business rule (duplicate or badly formatted code, deactivating the default one or one with an open session). |


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