# Manual API oficinaPro.co

Guía en Markdown con el mismo contenido funcional del manual HTML, preparada para lectura y descarga por agentes o flujos automatizados.

- Base URL: `https://data.oficinapro-mail.com`
- Método: `GET`
- Ruta pública: `/api/v1/tables/{table_name}`
- Autenticación: `Authorization: Bearer <token>`
- Paginación efectiva: `1000`

## 1. Conceptos base

### Ruta pública única

Todo se consulta con:

```http
GET /api/v1/tables/{table_name}
```

### Fila puntual

Para traer una fila específica se usa `row_id`.

```http
GET /api/v1/tables/invoices?row_id=787816&created_at_from=2026-02-11&created_at_to=2026-02-11
```

### Relaciones

Se piden con `include` cuando la API las soporta.

```http
GET /api/v1/tables/invoices?include=items&created_at_from=2026-02-11&created_at_to=2026-02-11
```

```http
GET /api/v1/tables/remissions?include=items&created_at_from=2026-02-11&created_at_to=2026-02-11
```

### Agrupación

Algunas tablas soportan devolver resultados agrupados.

```http
GET /api/v1/tables/inventory_transfers?group_by=batch_id
```

### Paginación

La paginación es fija de `1000` filas por página.

## 2. Autenticación

Enviar:

```http
Authorization: Bearer <token>
```

Ejemplo:

```bash
curl -H "Authorization: Bearer dummy-token" \
  "https://data.oficinapro-mail.com/api/v1/tables/accounts?page=1"
```

## 3. Contrato HTTP y formato de respuesta

La respuesta sigue este orden:

```json
{
  "pagination": { "page": 1, "page_size": 1000, "total": 52, "total_pages": 1 },
  "request": {
    "table": "accounts",
    "sort": "id",
    "order": "desc",
    "returned_records": 0,
    "applied_filters": {}
  },
  "data": []
}
```

`request.returned_records` indica cuántos registros fueron entregados efectivamente en `data`.

## 4. Reglas de filtros y ordenamiento

- `campo=valor`: filtro exacto
- `campo_contains=texto`: búsqueda parcial
- `campo_gte=valor` y `campo_lte=valor`: rangos numéricos
- `created_at_from` y `created_at_to`: rango de fecha
- `updated_at_from` / `updated_at_to`: auditoría cuando aplique
- `deposited_at_from` / `deposited_at_to`: depósito cuando aplique
- `sort` y `order=asc|desc`: ordenamiento

Si se envía solo fecha:

- `created_at_from=2026-02-11` -> `2026-02-11 00:00:00`
- `created_at_to=2026-02-11` -> `2026-02-11 23:59:59`

Tablas con rango obligatorio de `created_at`:

- `inventory_movements`
- `invoice_items`
- `invoice_expenses`
- `invoices`
- `credit_notes`
- `remissions`
- `outgoing_payments`
- `payments`
- `provider_invoice_items`
- `provider_invoices`
- `quotations`
- `quotation_items`

Tablas de inventario disponibles para traslados y trazabilidad:

- `inventories`
- `inventory_transfers`
- `inventory_movements`

## 5. Relaciones soportadas por la API

### Facturas de venta con items

```http
GET /api/v1/tables/invoices?include=items&created_at_from=2026-02-11&created_at_to=2026-02-11
```

### Notas de crédito con factura e items

`credit_notes` exige siempre el filtro `type`: `1` devolución, `2` anulación y `3` ajuste de precio. Use `include=items` para recibir la factura relacionada. En anulaciones, `items` contiene las líneas vigentes de la factura indicada por `invoice_id`. En devoluciones y ajustes, `items` es el detalle decodificado del JSON `payload` de la propia nota; la propiedad cruda `payload` no se devuelve.

```http
GET /api/v1/tables/credit_notes?type=2&include=items&created_at_from=2026-02-01&created_at_to=2026-02-28
```

### Cotizaciones con items

```http
GET /api/v1/tables/quotations?include=items&created_at_from=2026-09-01&created_at_to=2026-09-02
```

### Facturas de compra con detalle

```http
GET /api/v1/tables/provider_invoices?is_invoice=1&include=details&created_at_from=2026-02-01&created_at_to=2026-02-28
```

### Gastos con detalle

```http
GET /api/v1/tables/provider_invoices?is_invoice=5&include=details&created_at_from=2026-02-01&created_at_to=2026-02-28
```

### Producto con inventario

```http
GET /api/v1/tables/new_products?include=inventory&row_id=2550
```

## 6. Facturas de ventas

Endpoint: `/api/v1/tables/invoices`

Qué contiene:
Cabecera de documentos de venta: cliente, oficina, totales, impuestos, estado, datos de despacho, metadatos de factura electrónica y referencias contables.

Sentido de negocio:
Es la tabla maestra de ventas.

Reglas de negocio clave:

- `status=2` significa anulada y se excluye por defecto
- `is_invoice=2` y `is_invoice=3` se documentan por separado en `remissions`
- `is_pos=1` ventas POS
- `payment_history` solo aparece con `show_payments=1`

Filtros disponible:

- `created_at_from`, `created_at_to`
- `id`
- `invoice_number`
- `cdc`
- `code`, `code_contains`
- `status`
- `is_pos`
- `office_id`
- `user_id`
- `account_id`
- `total_gte`, `total_lte`
- `updated_at_from`, `updated_at_to`
- `deposited_at_from`, `deposited_at_to`

Caso de negocio:
Finanzas quiere consultar las facturas del día para revisar el cierre de ventas.

```http
GET /api/v1/tables/invoices?created_at_from=2026-02-11&created_at_to=2026-02-11&sort=created_at&order=desc
```

Relación:

```http
GET /api/v1/tables/invoices?include=items&created_at_from=2026-02-11&created_at_to=2026-02-11
```

## 6A. Remisiones

Endpoint: `/api/v1/tables/remissions`

Qué contiene:
Cabecera de remisiones comerciales expuesta desde la misma tabla física `invoices`.

Sentido de negocio:
Separa remisiones del flujo de facturas legales para evitar mezclar tipos documentales en consultas de ventas.

Reglas de negocio clave:

- por defecto no muestra remisiones que ya fueron convertidas a factura
- si el request incluye `converted_to_invoice=1`, devuelve esas remisiones convertidas
- `status=2` se excluye por defecto
- `is_invoice` no es un filtro público en este endpoint
- `payment_history` solo aparece con `show_payments=1`

Filtros disponible:

- `created_at_from`, `created_at_to`
- `id`
- `invoice_number`
- `cdc`
- `code`, `code_contains`
- `status`
- `is_pos`
- `office_id`
- `user_id`
- `account_id`
- `total_gte`, `total_lte`
- `updated_at_from`, `updated_at_to`
- `deposited_at_from`, `deposited_at_to`
- `converted_to_invoice`

Caso de negocio:
Operaciones quiere listar remisiones del día sin mezclar facturas legales.

```http
GET /api/v1/tables/remissions?created_at_from=2026-02-11&created_at_to=2026-02-11
```

Remisiones convertidas en factura:

```http
GET /api/v1/tables/remissions?created_at_from=2026-02-11&created_at_to=2026-02-11&converted_to_invoice=1
```

Relación:

```http
GET /api/v1/tables/remissions?include=items&created_at_from=2026-02-11&created_at_to=2026-02-11
```

## 7. Ítems de facturas de venta

Endpoint: `/api/v1/tables/invoice_items`

Qué contiene:
Líneas de venta por factura: producto, cantidad, descuentos, impuestos, costo, comisión, vendedor, cliente, oficina, serial y SKU.

Sentido de negocio:
Análisis fino de ventas por línea, producto, vendedor y oficina.

Filtros disponible:

- `created_at_from`, `created_at_to`
- `id`
- `invoice_id`
- `product_id`
- `category_id`
- `sold_by`
- `user_id`
- `office`
- `sold_in`
- `flaid`, `flaid_contains`
- `name`, `name_contains`
- `brand`, `brand_contains`
- `nulled`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Ventas quiere saber qué artículos vendió un asesor en una sede específica durante un día.

```http
GET /api/v1/tables/invoice_items?created_at_from=2026-02-11&created_at_to=2026-02-11&sold_by=30275&sold_in=3
```

Filtrar por categoría:

```http
GET /api/v1/tables/invoice_items?created_at_from=2026-02-11&created_at_to=2026-02-11&category_id=12
```

La API resuelve `category_id` internamente hacia `flaid`, incluyendo variaciones si el producto base no tiene SKU propio.

## 8. Facturas de compra

Endpoint: `/api/v1/tables/provider_invoices?is_invoice=1`

Qué contiene:
Cabecera de cuentas por pagar de proveedor cuando el documento representa compra de inventario o mercancía.

Sentido de negocio:
Concentra proveedor, moneda, totales, impuestos, estado y trazabilidad de carga a inventario.

Filtros disponible:

- `created_at_from`, `created_at_to`
- `is_invoice=1`
- `id`
- `user_id`
- `office_id`
- `updated_by`
- `cdc`
- `number`
- `invoice_number`, `invoice_number_contains`
- `status`
- `pushed`
- `currency`
- `total_gte`, `total_lte`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Compras quiere revisar facturas de proveedor del mes para validar qué documentos deben entrar a inventario.

```http
GET /api/v1/tables/provider_invoices?is_invoice=1&created_at_from=2026-02-01&created_at_to=2026-02-28&status=0
```

Relación:

```http
GET /api/v1/tables/provider_invoices?is_invoice=1&include=details&created_at_from=2026-02-01&created_at_to=2026-02-28
```

## 9. Productos en facturas de compra

Endpoint: `/api/v1/tables/provider_invoice_items`

Qué contiene:
Líneas de compra de facturas de proveedor cuando `provider_invoices.is_invoice=1`.

Sentido de negocio:
Permite analizar cantidades, costos, impuestos y SKU recibidos.

Filtros disponible:

- `created_at_from`, `created_at_to`
- `id`
- `invoice_id`
- `provider_id`
- `category_id`
- `updated_by`
- `flaid`, `flaid_contains`
- `name`, `name_contains`
- `invoice_canceled`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Compras necesita ver qué SKUs llegaron en una factura concreta.

```http
GET /api/v1/tables/provider_invoice_items?created_at_from=2026-02-01&created_at_to=2026-02-28&invoice_id=12345
```

Filtrar por categoría:

```http
GET /api/v1/tables/provider_invoice_items?created_at_from=2026-02-01&created_at_to=2026-02-28&category_id=12
```

La API resuelve `category_id` internamente hacia `flaid`, incluyendo variaciones desde `product_extensions` cuando aplica.

## 10. Cotizaciones

Endpoint: `/api/v1/tables/quotations`

Qué contiene:
Cabeceras de cotizaciones comerciales con cliente (`user_id`), sede (`office`), vencimiento (`expires_on`), descuentos, impuestos y total.

Relación disponible:
Usa `include=items` para recibir las líneas de `quotation_items` en la propiedad `items`, igual que en facturas.

Filtros principales:

- `id`, `user_id`, `office`, `updated_by`
- `status`, `expires_on`
- `total_gte`, `total_lte`, `subtotal_gte`, `subtotal_lte`
- `created_at_from`, `created_at_to` (obligatorios)
- `updated_at_from`, `updated_at_to`

```http
GET /api/v1/tables/quotations?include=items&created_at_from=2026-09-01&created_at_to=2026-09-02
```

Ítems de cotización:
`/api/v1/tables/quotation_items` expone `quotation_id`, `product_id`, `qty`, `flaid`, `name`, precios, descuentos, IVA e importes netos y brutos. Sus consultas de lista también requieren `created_at_from` y `created_at_to`.

## 11. Productos

Endpoint: `/api/v1/tables/new_products`

Qué contiene:
Catálogo maestro de productos y servicios con impuestos, precios, comportamiento de inventario, serialización, proveedor y datos de clasificación.

Sentido de negocio:
Define cómo se vende, compra y controla cada ítem.

Regla de variaciones:
Cuando `new_products.flaid` es `NULL`, la API agrega `variations` con registros de `product_extensions` relacionados por `product_id` y con `flaid` válido. Esto pasa incluso sin `include`.

Fallback de búsqueda por SKU:
Si el filtro `flaid` no encuentra registros en `new_products`, la API busca ese valor en `product_extensions.flaid` y devuelve las variaciones encontradas. Cada variación incluye `unit_measure` del `new_products` que la agrupa; `unit_measure` guarda la ubicación del producto. El `name` de una variación concatena primero el nombre de su producto padre y luego el nombre propio de la variación.

Regla de inventario en variaciones:
Si usas `include=inventory`, cada objeto dentro de `variations` también recibe su propio `inventory` resuelto por el `flaid` de la variación.

Regla de descripción:
`new_products.description` no se devuelve por defecto. Solo aparece si envías `show_description=1`.

Filtros disponible:

- `id`
- `provider_id`
- `category_id`
- `extension_id`
- `created_by`
- `updated_by`
- `flaid`, `flaid_contains`
- `name`, `name_contains`
- `barcode`, `barcode_contains`
- `status`
- `is_service`
- `saleable`
- `adds_to_inventory`
- `with_serial`
- `check_inventory`
- `created_at_from`, `created_at_to`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Catálogo quiere listar productos activos que afectan inventario y manejan serial.

```http
GET /api/v1/tables/new_products?status=1&adds_to_inventory=1&with_serial=1
```

Filtrar por categoría:

```http
GET /api/v1/tables/new_products?category_id=12&status=1
```

La API resuelve `category_id` internamente usando la relación producto-categoría y devuelve solo los productos asociados.

Ejemplo con variaciones:

```http
GET /api/v1/tables/new_products?row_id=69
```

```http
GET /api/v1/tables/new_products?row_id=69&show_description=1
```

Relación:

```http
GET /api/v1/tables/new_products?include=inventory&row_id=2550
```

```http
GET /api/v1/tables/new_products?include=inventory&row_id=69
```

## 11. Inventario actual

Endpoint: `/api/v1/tables/inventories`

Qué contiene:
Saldo de inventario actual por SKU, costo estándar y columnas dinámicas por oficina.

Sentido de negocio:
Responde cuánto stock hay hoy por referencia y en qué sedes.

Filtros disponible:

- `id`
- `flaid`, `flaid_contains`
- `cost_gte`, `cost_lte`
- `is_service`
- `updated_by`
- `created_at_from`, `created_at_to`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Operaciones quiere revisar el costo y el saldo actual de un SKU específico.

```http
GET /api/v1/tables/inventories?flaid=2059
```

## 12. Movimientos de inventario

Endpoint: `/api/v1/tables/inventory_movements`

Qué contiene:
Libro mayor de movimientos de inventario con SKU, cantidad movida, oficina, saldo posterior, documento origen y origen operativo.

Sentido de negocio:
Sirve para auditar entradas, salidas, ajustes y transferencias de stock.

Filtros disponible:

- `created_at_from`, `created_at_to`
- `id`
- `office_id`
- `updated_by`
- `inventory_adjustment_id`
- `flaid`, `flaid_contains`
- `reference`, `reference_contains`
- `type`
- `qty_gte`, `qty_lte`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Inventarios necesita revisar qué movimientos tuvo un SKU en un día y en qué oficina.

```http
GET /api/v1/tables/inventory_movements?created_at_from=2026-02-11&created_at_to=2026-02-11&flaid=0297&office_id=3
```

## 13. Traslados de inventario

Endpoint: `/api/v1/tables/inventory_transfers`

Qué contiene:
Líneas de traslados de inventario entre oficinas. Cada fila representa un SKU o referencia dentro de un traslado, y `batch_id` agrupa todas las líneas del mismo movimiento.

Costos calculados por línea:

- `cost`: valor actual de `inventories.cost` resuelto con `inventories.flaid = inventory_transfers.flaid`.
- `total_cost`: `cost * qty`.

No interpretar estos valores como costo histórico del traslado: se calculan al consultar con el costo estándar actual. Si no hay inventario o costo para el `flaid`, ambos valores son `null`.

Sentido de negocio:
Permite auditar solicitudes, aprobaciones, tránsito y consolidación de stock entre sedes.

Agrupación disponible:
Si el request incluye `group_by=batch_id`, la API devuelve un registro por traslado en vez de una fila por SKU. La cabecera usa los datos de la primera línea del lote, agrega `total_cost` como suma del `total_cost` de todos los `items`, y `items` contiene todas las líneas individuales, incluida la primera. El `total_cost` de cabecera es `null` si cualquier línea carece de costo calculable.

Significado de estados:

- `0`: borrador. Traslado en preparación; no mueve inventario.
- `1`: solicitado. La sede destino lo solicitó; todavía no mueve inventario.
- `2`: aprobado y en tránsito. El inventario ya salió de la sede origen, pero aún no entra a la sede destino.
- `3`: consolidado. La sede destino recibió el traslado; el inventario ya quedó sumado en destino.
- `4`: reversado. Revierte un traslado consolidado y deshace su efecto en inventario.

Filtros disponible:

- `id`
- `batch_id`
- `user_id`
- `from_office_id`
- `to_office_id`
- `updated_by`
- `approved_by`
- `flaid`, `flaid_contains`
- `status`
- `qty_gte`, `qty_lte`
- `suggested_gte`, `suggested_lte`
- `created_at_from`, `created_at_to`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Operaciones quiere revisar todas las líneas del traslado `1847` y validar si ya fue aprobado y consolidado.

```http
GET /api/v1/tables/inventory_transfers?batch_id=1847&sort=created_at&order=asc
```

```http
GET /api/v1/tables/inventory_transfers?group_by=batch_id&sort=created_at&order=desc
```

Ejemplo para traer todos los traslados en tránsito:

```http
GET /api/v1/tables/inventory_transfers?status=2&group_by=batch_id&sort=created_at&order=desc
```

## 14. Pagos salientes

Endpoint: `/api/v1/tables/outgoing_payments`

Qué contiene:
Pagos realizados por la empresa a proveedores, nómina u otros documentos.

Sentido de negocio:
Es la tabla central de egresos monetarios.

Filtros disponible:

- `created_at_from`, `created_at_to`
- `id`
- `user_id`
- `office_id`
- `account_id`
- `created_by`
- `updated_by`
- `approved_by`
- `confirmed_by`
- `number`
- `status`
- `currency`
- `is_transfer`
- `is_wage`
- `amount_gte`, `amount_lte`
- `updated_at_from`, `updated_at_to`
- `deposited_at_from`, `deposited_at_to`

Caso de negocio:
Tesorería quiere ver pagos salientes de nómina realizados en un rango de fechas.

```http
GET /api/v1/tables/outgoing_payments?created_at_from=2026-02-01&created_at_to=2026-02-28&is_wage=1
```

## 14. Pagos recibidos

Endpoint: `/api/v1/tables/payments`

Qué contiene:
Pagos recibidos o aplicados a facturas y notas crédito.

Sentido de negocio:
Es la fuente transaccional de recaudo.

Filtros disponible:

- `created_at_from`, `created_at_to`
- `id`
- `user_id`
- `office_id`
- `account_id`
- `created_by`
- `updated_by`
- `confirmed_by`
- `number`
- `status`
- `is_transfer`
- `un_identified`
- `voucher_ref`, `voucher_ref_contains`
- `amount_gte`, `amount_lte`
- `updated_at_from`, `updated_at_to`
- `deposited_at_from`, `deposited_at_to`

Caso de negocio:
Cartera quiere revisar pagos confirmados depositados durante un período.

```http
GET /api/v1/tables/payments?created_at_from=2026-02-01&created_at_to=2026-02-28&status=1
```

## 15. Gastos

Endpoint: `/api/v1/tables/provider_invoices?is_invoice=5`

Qué contiene:
Cabecera de documentos de proveedor cuando el registro representa un gasto y no una compra de inventario.

Sentido de negocio:
Control de cuentas por pagar por servicios, honorarios, arrendamientos, impuestos u otros egresos operativos.

Filtros disponible:

- `created_at_from`, `created_at_to`
- `is_invoice=5`
- `id`
- `user_id`
- `office_id`
- `updated_by`
- `cdc`
- `number`
- `invoice_number`, `invoice_number_contains`
- `status`
- `pushed`
- `currency`
- `total_gte`, `total_lte`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Contabilidad quiere revisar los gastos de proveedor causados en el mes.

```http
GET /api/v1/tables/provider_invoices?is_invoice=5&created_at_from=2026-02-01&created_at_to=2026-02-28&status=0
```

Relación:

```http
GET /api/v1/tables/provider_invoices?is_invoice=5&include=details&created_at_from=2026-02-01&created_at_to=2026-02-28
```

## 16. Detalles de gastos

Endpoint: `/api/v1/tables/invoice_expenses`

Qué contiene:
Líneas de gasto asociadas a documentos de proveedor cuando `provider_invoices.is_invoice=5`.

Sentido de negocio:
Descompone gastos en subtotal, impuestos, retenciones y total final por línea.

Filtros disponible:

- `created_at_from`, `created_at_to`
- `id`
- `invoice_id`
- `expense_id`
- `updated_by`
- `name`, `name_contains`
- `subtotal_gte`, `subtotal_lte`
- `total_gte`, `total_lte`
- `updated_at_from`, `updated_at_to`

Caso de negocio:
Contabilidad quiere revisar los conceptos que componen una cuenta por pagar de tipo gasto.

```http
GET /api/v1/tables/invoice_expenses?created_at_from=2026-02-01&created_at_to=2026-02-28&invoice_id=50362
```

## Tablas auxiliares

Estas tablas complementan ventas, compras, pagos e inventario.

### 17. Cuentas

Endpoint: `/api/v1/tables/accounts`

Qué contiene:
Catálogo de cuentas usado para traducir `account_id` a un nombre legible.

Caso de negocio:
Tesorería quiere encontrar el nombre exacto de la cuenta usada en cobros y pagos.

```http
GET /api/v1/tables/accounts?name_contains=Banco
```

### 18. Categorías

Endpoint: `/api/v1/tables/categories`

Qué contiene:
Catálogo maestro de categorías para clasificar productos.

Caso de negocio:
Usuario comercial quiere localizar la categoría “Brazaletes”.

```http
GET /api/v1/tables/categories?name_contains=Brazal
```

La relación producto-categoría no se expone como endpoint público.  
Para filtrar productos por categoría se debe usar `new_products?category_id=...`.

### 20. Oficinas

Endpoint: `/api/v1/tables/offices`

Qué contiene:
Catálogo de sedes o ubicaciones.

Caso de negocio:
Operaciones necesita saber el nombre exacto de la oficina asociada a una venta.

```http
GET /api/v1/tables/offices?name_contains=Carta
```

### 21. Usuarios, clientes y proveedores

Endpoint: `/api/v1/tables/users`

Qué contiene:
Catálogo maestro de personas y entidades.

Campo adicional:
`verified_token` se devuelve como token de verificación asociado a la entidad. Es solo de lectura y no es filtrable ni ordenable.

Caso de negocio:
Cartera quiere identificar clientes con crédito habilitado y documento conocido.

```http
GET /api/v1/tables/users?has_credit=1&personal_id_contains=900
```

### 22. Garantías

Cómo funciona:

- `new_products.warranty` guarda la configuración de garantía del producto en el catálogo maestro.
- cuando se factura, ese valor queda copiado en `invoice_items.warranty`.
- esto permite conservar los días de garantía exactamente como estaban al momento de la venta, aunque después cambie la configuración del producto.

Sentido de negocio:

- `new_products` responde la garantía vigente hoy en el catálogo.
- `invoice_items` responde la garantía histórica con la que realmente se vendió el producto.

Ejemplo práctico:

- si un producto tenía `warranty = 365` cuando se emitió la factura, esa línea queda grabada con `invoice_items.warranty = 365`.
- si después el producto cambia a `warranty = 180` en `new_products`, la factura anterior sigue conservando `invoice_items.warranty = 365`.

Consultas útiles:

```http
GET /api/v1/tables/new_products?row_id=2550
```

```http
GET /api/v1/tables/invoice_items?created_at_from=2026-02-11&created_at_to=2026-02-11&invoice_id=787816
```

## Resumen operativo

Forma práctica de usar la API:

```http
GET https://data.oficinapro-mail.com/api/v1/tables/{table_name}
```

- usar `Authorization: Bearer <token>`
- enviar filtros simples por query string
- usar `row_id` para una fila puntual
- usar `include` solo cuando la tabla lo soporte
- para `invoices`, agregar `show_payments=1` solo si se necesita `payment_history`
