API de Flow

Catálogo, existencias, terceros, ventas, facturas, cuentas por pagar, pagos y webhooks.

Base: https://flow.eel.software/api/public/v1

La app de finanzas y operaciones. Todo POST que crea o registra algo exige el encabezado Idempotency-Key, con una excepción: las dos rutas de gestión de webhooks al final de esta página. Ver las reglas compartidas para paginación, errores y ritmo, una sola vez para las cuatro apps.

Catálogo y existencias

Método Ruta Permiso
GET /products flow:catalog:read
GET /products/{upid} flow:catalog:read
PATCH /products/{upid} flow:catalog:write
GET /products/{upid}/stock flow:stock:read
GET /warehouses flow:catalog:read
GET /financial-accounts flow:sales:write

GET /products pagina con cursor y filtra con q (nombre o SKU), active, o updated_since (fecha ISO). Cada fila trae su UPID, el id que toma cualquier otra ruta de producto: sku, name, active, list_price, currency, tax y uom.

PATCH /products/{upid} edita name, list_price (string decimal, null la borra), tax_code (null lo borra) o active. sku y uom son deliberadamente inmutables por la API.

GET /products/{upid}/stock devuelve on_hand y disponible-para-vender por bodega (available = on_hand menos las reservas activas), opcionalmente filtrado a una warehouse. Es eventualmente consistente con el checkout.

GET /warehouses lista todas las bodegas activas (CENTRAL y STORE) con el warehouse_id que toman las ventas y las lecturas de existencias; las filas STORE traen además el partner_id del tercero que representa esa tienda.

GET /financial-accounts lista cuentas activas CASH / BANK / PROCESSOR con su currency, solo identidad, sin saldos. Es la fuente del financial_account_id que toma una venta o un pago.

Terceros

Método Ruta Permiso
GET /partners flow:partners:write
GET /partners/{id} flow:partners:write
POST /partners flow:partners:write

No hay un permiso de lectura dedicado para terceros: leer y buscar van los dos sobre flow:partners:write, la misma asimetría que el catálogo de permisos señala para las notas y recordatorios de Wrap.

GET /partners?q= busca por nombre (contiene) o prefijo de identificación tributaria. POST /partners hace upsert de un tercero (cliente/proveedor) por identificación tributaria (tax_id_type + tax_id_number) o email: devuelve el registro existente cuando hay coincidencia, así que también sirve para buscar por NIT. El dígito de verificación del NIT se valida, o se calcula si se omite.

Campo Tipo Notas
name string, 1 a 200 caracteres Obligatorio.
tax_id_type NIT\ CC\
tax_id_number string, hasta 40 caracteres Opcional.
verification_digit string, hasta 2 caracteres El DV del NIT. Se calcula si se omite.
email string Opcional.
roles string[] P. ej. CUSTOMER, SUPPLIER, EMPLOYEE.

Ventas

Método Ruta Permiso
POST /sales flow:sales:write
GET /sales/{id} flow:sales:write

POST /sales es la venta de una sola llamada: descuenta existencias de una bodega, factura al cliente y opcionalmente registra el pago.

Campo Tipo Notas
external_ref string, hasta 200 caracteres Tu propio id de orden. También el ancla de deduplicación.
warehouse_id uuid Obligatorio.
customer `{ partner_id? \ name/tax_id/email }`
lines { upid, qty, unit_price? }[], mínimo 1 unit_price sobreescribe el precio de lista resuelto si se envía.
payment { method, financial_account_id?, processor_ref?, amount? } method es CASH o PROCESSOR.
emit_einvoice boolean
notes string, hasta 2000 caracteres

GET /sales/{id} devuelve el número y estado de la factura, la referencia de salida, y dian_status (estado de la facturación electrónica ante la DIAN).

Facturas y cuentas por pagar

Método Ruta Permiso
GET /invoices flow:documents:read
GET /bills/list flow:documents:read
POST /bills flow:bills:write

GET /invoices recorre documentos de cartera por cobrar (facturas de venta) por fecha de emisión más reciente primero, con cursor: la vista "ingresos este mes". GET /bills/list es la misma forma para documentos de cartera por pagar (facturas de proveedor), más supplier_number y PENDING_APPROVAL como estado extra. flow_list_open_items (abajo) solo muestra el subconjunto sin pagar de cualquiera de las dos.

Ambas filtran por status, partner_id, o una ventana issued_from/ issued_to (fechas ISO), y ambas devuelven el number formateado (null mientras está DRAFT), partner_id/nombre, dinero como string y el remaining consciente de retenciones.

Superficie Estados
Facturas de venta DRAFT, OPEN, PARTIAL, PAID, VOID
Cuentas por pagar DRAFT, OPEN, PARTIAL, PAID, VOID, PENDING_APPROVAL

POST /bills crea una factura de compra en DRAFT; una persona la contabiliza dentro de Flow. Referencia al proveedor por partner_id o pasa un objeto partner en línea (con upsert por identificación tributaria o email). Un par (partner, supplier_number) duplicado se rechaza con conflict y el bill_id existente en los detalles del error.

Campo Tipo Notas
partner_id uuid, opcional
partner objeto, opcional Proveedor en línea: name, tax_id_type, tax_id_number, email.
supplier_number string, 1 a 60 caracteres El número de factura propio del proveedor.
issue_date fecha ISO Obligatorio.
due_date fecha ISO, opcional
currency string, 3 caracteres, opcional
notes string, hasta 2000 caracteres, opcional
lines { description, qty, unit_price, tax_code?, product_upid? }[], mínimo 1 Dinero como números, no strings.

Pagos

Método Ruta Permiso
POST /invoices/{id}/payments flow:payments:write
POST /bills/{id}/payments flow:payments:write

Las dos registran un pago (un recaudo contra una factura de venta, o un desembolso contra una cuenta por pagar), con las mismas reglas: amount es un string decimal en la moneda propia del documento, y financial_account_id debe coincidir con esa moneda. Se rechaza cuando el documento está DRAFT/VOID/ya PAID, el monto excede lo que resta, o el mes fiscal está cerrado.

Campo Tipo Notas
financial_account_id uuid De GET /financial-accounts.
amount string decimal P. ej. "150000.00", en la moneda del documento.
date fecha ISO Obligatorio.
reference string, hasta 120 caracteres, opcional

Un pago contra una cuenta por pagar en o por encima del umbral de aprobación del espacio solo pasa cuando quien llama es administrador del espacio. Las dos rutas devuelven el pago más el remaining y status del documento tras el pago.

Cartera (items abiertos)

Método Ruta Permiso
GET /open-items flow:open-items:read

Documentos abiertos (sin pagar) con su saldo pendiente: side=AP para cuentas por pagar a proveedores, side=AR para facturas de venta que nos deben. Filtra por partner_nit o una fecha as_of. Es la ruta detrás de "qué le debemos a X", "quién nos debe", y preguntas de cartera en general.

Webhooks

Método Ruta Permiso
GET /webhooks flow:webhooks:manage
POST /webhooks flow:webhooks:manage
DELETE /webhooks/{id} flow:webhooks:manage
GET /webhook-deliveries flow:webhooks:manage
POST /webhook-deliveries/{id}/redeliver flow:webhooks:manage

Estas dos rutas POST son la excepción a la regla de idempotencia de arriba: POST /webhooks y POST /webhook-deliveries/{id}/redeliver ni exigen ni miran Idempotency-Key.

POST /webhooks toma url (hasta 2000 caracteres) y events (al menos uno de invoice.posted, invoice.paid, bill.posted, payment.created, stock.changed). La respuesta incluye el secreto de firma una sola vez, al crear, nunca después. GET /webhook-deliveries?webhook= lista entregas recientes, opcionalmente filtradas a un webhook; POST /webhook-deliveries/{id}/redeliver reencola una para el siguiente drenaje.

La entrega es al menos una vez: quien consume un webhook debe ser idempotente por su cuenta, usando el cuerpo del evento como clave, no el número de entregas.