Requisitos de API para POS y ERP
Beliberi lee el catálogo, los precios y las existencias del comercio desde una API REST de solo lectura expuesta por su POS o ERP. Este documento fija lo que esa API debe entregar para que la web y la app del comercio vendan con datos al día.
1. Alcance
Beliberi consulta la API del comercio cada 15 minutos y reconstruye su catálogo completo: productos, precios, existencias por sede, categorías y fotos. El comercio no instala nada: expone la API, entrega una credencial y Beliberi la conecta desde su consola con el conector "API REST genérica".
| Dato | Obligatorio | Para qué lo usa Beliberi |
|---|---|---|
| Productos con SKU, nombre y precio | Sí | Ficha, búsqueda y carrito en la web y la app |
| Existencias por sede o almacén | Sí | Vender solo lo que hay en la sede que atiende al cliente |
| Categoría y subcategoría | Recomendado | Navegación del catálogo y orden de la tienda |
| Código de barras (EAN/UPC) | Recomendado | El picker escanea el producto al recogerlo |
| IVA por producto | Recomendado | Totales y facturación |
| URL de la foto | Recomendado | Ficha del producto; sin foto se muestra un marcador |
| Marca | Opcional | Filtros y búsqueda |
| Modificadores (tamaños, extras) | Opcional | Solo comercios con menú (restaurantes) |
La API es de solo lectura desde el punto de vista del POS: Beliberi lee, nunca escribe en el inventario. El envío de pedidos hacia el POS es opcional y se describe en la sección de endpoints opcionales.
Un ERP que ya expone una API estructurada (Odoo, Revel, KLK) se conecta con su conector propio; este documento cubre el caso general de un sistema que aún no tiene integración con Beliberi.
2. Autenticación y transporte
La API se sirve por HTTPS con certificado válido, en JSON codificado en UTF-8, y acepta una credencial propia por comercio que el comercio puede revocar sin afectar a otros clientes de su sistema.
| Modo | Cómo viaja la credencial | Cuándo conviene |
|---|---|---|
| Bearer token (recomendado) | Cabecera Authorization: Bearer <token> | Token largo, sin caducidad corta |
| API key en cabecera | Cabecera con el nombre que indique el comercio, p. ej. X-API-KEY: <valor> | Sistemas con claves fijas |
| Usuario y contraseña (Basic) | Authorization: Basic <base64 usuario:contraseña> | ERPs clásicos |
| Parámetro en la URL | ?api_key=<valor> | Solo si el sistema no admite cabeceras |
- La credencial la guarda Beliberi en su gestor de secretos; nunca aparece en la consola ni en registros. El comercio entrega el valor una vez, por un canal seguro, y puede rotarlo cuando quiera.
- Un token con caducidad corta (menos de 24 horas) o que exija renovarse con un flujo OAuth no es compatible con el conector genérico; en ese caso se acuerda un token de servicio de larga duración.
- Si la API restringe por IP, Beliberi comunica las direcciones de salida de su plataforma antes de la puesta en marcha.
- Las peticiones llevan
Accept: application/jsonyUser-Agent: Beliberi-Catalog-Sync/1. Las respuestas deben serContent-Type: application/json. - Sin credencial válida la API responde
401; con credencial válida pero sin permiso,403. Beliberi muestra ambos como "credencial rechazada" en la consola del comercio.
3. Catálogo de productos
Un endpoint GET /productos devuelve todos los productos vendibles con estos campos por ítem. Los nombres de los campos y su ubicación en el JSON pueden ser los del sistema del comercio: Beliberi los mapea desde la consola con rutas por puntos (precio.usd, categoria.codigo). Lo que no puede faltar es el dato.
| Campo (nombre sugerido) | Tipo | Obligatorio | Regla | Ejemplo |
|---|---|---|---|---|
sku | texto | Sí | Identificador estable del producto en el POS; no cambia con el precio ni el stock | "A-10493" |
nombre | texto | Sí | Nombre comercial, con presentación | "Aceite de oliva 500 ml" |
precio | número | Sí | Precio de venta unitario en la moneda del catálogo, sin IVA, punto decimal | 6.50 |
stock | entero | Sí | Existencia vendible en la sede o almacén consultado; 0 deja el producto agotado, no lo oculta | 12 |
codigo_barras | texto | Recomendado | EAN/UPC del empaque; si falta se usa el SKU para el escáner | "7591234567890" |
categoria_codigo | texto | Recomendado | Código estable de la categoría | "ACE" |
categoria_nombre | texto | Recomendado | Nombre visible de la categoría | "Aceites y vinagres" |
subcategoria_codigo | texto | Opcional | Código de la subcategoría | "ACE-OLI" |
subcategoria_nombre | texto | Opcional | Nombre visible de la subcategoría | "Aceite de oliva" |
marca | texto | Opcional | Marca | "Marca de ejemplo" |
iva | número | Recomendado | Porcentaje de IVA aplicable; 0 para exentos | 16 |
imagen_url | texto (URL) | Recomendado | URL pública o firmada de la foto principal, HTTPS, JPG/PNG/WebP, máximo 5 MB | "https://cdn.comercio.com/a10493.jpg" |
activo | booleano | Recomendado | false retira el producto del catálogo sin borrarlo | true |
descripcion | texto | Opcional | Descripción larga para la ficha (máximo 2.000 caracteres) | "Aceite de oliva extra virgen..." |
unidad | texto | Opcional | Unidad de venta: unidad, kg, g, l, ml | "unidad" |
peso_gramos | entero | Opcional | Peso aproximado, para el reparto | 520 |
actualizado_en | fecha-hora ISO 8601 | Recomendado | Última modificación del producto, precio o stock; habilita la sincronización incremental | "2026-09-24T13:05:00-04:00" |
Reglas del catálogo
- Un SKU aparece una sola vez por sede. Si el POS maneja variantes (talla, color), cada variante es un producto con su propio SKU y su código de barras.
- El precio es el vigente para venta al detal en la sede consultada. Los descuentos por promoción se reflejan en el precio o en el campo opcional
precio_descuento(número, precio final ya rebajado). - La moneda del catálogo es una sola para todo el comercio y se declara en la puesta en marcha (USD o VES). Beliberi convierte a bolívares con la tasa del día.
- Los productos con
stocken0oactivoenfalsedeben seguir apareciendo en la respuesta durante al menos 30 días; si un SKU desaparece de la lista, Beliberi lo marca como no disponible. - Las fotos se descargan una vez y se vuelven a pedir solo si cambia la URL; una URL que cambia con cada consulta (firmas con caducidad) hace que se descarguen en cada sincronización.
4. Existencias por sede o almacén
Cada sede de Beliberi vende el stock de un almacén del POS, así que la API tiene que poder responder por almacén. Se acepta cualquiera de estas tres formas, de la más simple a la más completa.
| Forma | Cómo se pide | Cuándo usarla |
|---|---|---|
| Un endpoint por almacén | GET /productos?almacen=ALM-01 (o una URL distinta por almacén) | Comercios con pocas sedes; Beliberi guarda una URL o un código de almacén por sede |
| Stock por almacén dentro de cada producto | "existencias": [{"almacen": "ALM-01", "stock": 12}, {"almacen": "ALM-02", "stock": 0}] | Una sola llamada para todo el comercio |
| Endpoint de existencias aparte | GET /existencias?almacen=ALM-01 con sku y stock | Catálogos grandes donde el stock cambia mucho más que la ficha |
- El código de almacén es estable y lo define el comercio; Beliberi lo asigna a cada sede en la consola. Varios almacenes pueden sumar existencias para una misma sede.
- El stock es la cantidad vendible ahora (descontadas reservas y mermas), no el físico. Si el POS reserva al vender en tienda, la cifra debe reflejarlo.
- Un producto sin fila de existencias para un almacén se toma como stock
0en esa sede. - Si el precio varía por sede, la forma 1 o la forma 3 (con
precioen la fila) lo resuelven; la forma 2 asume un precio único.
5. Paginación y cambios incrementales
Hasta 2.000 productos la respuesta puede venir completa en una sola página. Por encima, la API pagina con uno de estos modos, todos soportados por el conector.
| Modo | Parámetros de la petición | Cómo termina |
|---|---|---|
| Número de página (recomendado) | ?page=1&per_page=500 | Una página con menos ítems que per_page es la última |
| Offset y límite | ?offset=0&limit=500 | Igual: página corta = última |
| Cursor o URL siguiente | La respuesta trae meta.next con el cursor o la URL de la página siguiente | meta.next vacío o nulo |
Beliberi lee como máximo 500 páginas o 10 minutos por sincronización; un catálogo que no cabe en eso se acuerda con paginación de 1.000 ítems o con un endpoint de existencias aparte.
?actualizado_desde=2026-09-24T13:00:00Z devuelve solo los productos modificados desde esa fecha, incluidos los desactivados. Con este filtro Beliberi sincroniza cada 15 minutos solo lo que cambió y hace una lectura completa una vez al día para cuadrar. Sin el filtro, cada sincronización es completa.6. Formato de respuesta y errores
La respuesta es un objeto JSON con la lista de productos y, si hay paginación, un bloque meta. La lista puede estar en la raíz o en cualquier ruta (data.productos); Beliberi la indica al configurar la conexión.
{
"data": [
{
"sku": "A-10493",
"nombre": "Aceite de oliva 500 ml",
"precio": 6.50,
"precio_descuento": null,
"iva": 16,
"stock": 12,
"codigo_barras": "7591234567890",
"categoria_codigo": "ACE",
"categoria_nombre": "Aceites y vinagres",
"subcategoria_codigo": "ACE-OLI",
"subcategoria_nombre": "Aceite de oliva",
"marca": "Marca de ejemplo",
"imagen_url": "https://cdn.comercio.com/a10493.jpg",
"activo": true,
"unidad": "unidad",
"peso_gramos": 520,
"actualizado_en": "2026-09-24T13:05:00-04:00"
}
],
"meta": {
"page": 1,
"per_page": 500,
"total": 1834,
"next": "https://api.comercio.com/productos?page=2&per_page=500"
}
}
| Código HTTP | Significado | Qué hace Beliberi |
|---|---|---|
200 | Respuesta correcta, aunque la lista venga vacía | Sincroniza |
304 | Sin cambios desde actualizado_desde (opcional) | No toca el catálogo |
400 | Parámetro inválido | Registra el error y avisa en la consola |
401 / 403 | Credencial rechazada | Marca la conexión en error; el comercio la ve en "Conexión de datos" |
429 | Límite de peticiones | Espera lo que diga Retry-After y reintenta hasta 3 veces |
5xx o sin respuesta en 120 s | Sistema caído | Conserva el último catálogo bueno y reintenta en la siguiente sincronización |
Los errores llevan cuerpo JSON {"error": {"code": "...", "message": "..."}} con un mensaje legible: se muestra tal cual al personal del comercio.
Reglas de formato
- Números como números JSON (
6.50), no como texto con coma ("6,50"). Si el sistema solo puede devolver texto, se acuerda y Beliberi lo convierte. - Fechas en ISO 8601 con zona horaria.
- Campos ausentes o
nullcuentan como vacíos; no hace falta enviar los opcionales que no se usan. - Codificación UTF-8 sin BOM; acentos y eñes correctos en nombres y categorías.
7. Endpoints opcionales
Con el endpoint de productos basta para vender. Estos endpoints mejoran la experiencia o cubren casos concretos; se activan uno a uno en la consola.
| Endpoint | Qué entrega | Cuándo hace falta |
|---|---|---|
GET /categorias | Árbol de categorías con codigo, nombre, padre (código o nulo) y orden | Cuando el orden y los nombres de las categorías los decide el POS y no la consola de Beliberi |
GET /productos/{sku}/imagenes o campo imagenes[] | Varias fotos por producto, en orden, con url y principal | Fichas con galería |
GET /modificadores | Grupos de opciones con codigo, nombre, minimo, maximo, opciones[] (codigo, nombre, recargo, disponible) y productos[] (SKUs a los que aplica) | Solo comercios con menú: tamaños, extras, sin cebolla |
GET /sedes | Sedes con codigo, nombre, direccion, latitud, longitud, almacen, horario[] | Cuando el comercio quiere que las sedes y horarios salgan del POS |
POST /pedidos (Beliberi → POS) | Beliberi envía cada pedido pagado con sus líneas (sku, cantidad, precio), cliente, sede y número de pedido Beliberi; el POS responde con su número o factura | Comercios que facturan o descuentan inventario en el POS por cada venta en línea |
POST de aviso (POS → Beliberi) | El POS avisa a Beliberi cuando cambia stock o precio, con sku y el nuevo valor | Comercios con stock muy rotativo que no quieren esperar 15 minutos |
Envío de pedidos al POS, si se activa
- Beliberi lo llama al aprobarse el pago (o al aceptar el pedido, en comercios que preparan ellos mismos) y reintenta hasta 5 veces con espera creciente si el POS no responde.
- La petición lleva una clave de idempotencia (
Idempotency-Key, el número de pedido de Beliberi): el mismo pedido enviado dos veces no debe crear dos ventas. - El POS responde
201con{"pedido_pos": "F-000123"}; ese número se muestra en la consola y en la app del picker. - Los cambios posteriores (línea sin stock, sustitución aceptada, cancelación) se envían como
PATCH /pedidos/{pedido_pos}con el estado y las líneas finales.
Avisos del POS a Beliberi, si se activan
Llevan una firma HMAC en la cabecera X-Beliberi-Signature con un secreto compartido, y Beliberi responde 202 y aplica el cambio en menos de un minuto. Un aviso no sustituye a la sincronización periódica, que sigue cuadrando todo.
8. Requisitos no funcionales
| Aspecto | Requisito |
|---|---|
| Disponibilidad | 99 % mensual en horario de la tienda; una caída deja el catálogo congelado en su último estado bueno, no vacío |
| Tiempo de respuesta | Menos de 5 s por página de 500 productos; Beliberi corta la petición a los 120 s |
| Tamaño de página | Entre 100 y 1.000 ítems; recomendado 500 |
| Frecuencia de lectura | Una sincronización cada 15 minutos por sede, más las que el comercio lance a mano desde la consola |
| Límite de peticiones | Al menos 60 peticiones por minuto por credencial; si hay límite, responder 429 con Retry-After |
| Fotos | HTTPS, JPG/PNG/WebP, hasta 5 MB y 2.000 px por lado; URL estable mientras la foto no cambie |
| Cambios en la API | Versión en la URL (/v1/productos) o cabecera; cambios que rompen el formato con 30 días de aviso y la versión anterior activa mientras tanto |
| Datos personales | La API de catálogo no expone datos de clientes; el envío de pedidos al POS lleva solo nombre, teléfono y dirección de entrega del comprador |
| Registro | El comercio guarda un registro de las peticiones de Beliberi (fecha, endpoint, código) durante 30 días para diagnóstico |
| Entorno de pruebas | Una URL y credencial de pruebas con datos de ejemplo, o la misma API con un almacén de pruebas, antes de conectar producción |
9. Puesta en marcha
El comercio entrega cuatro cosas y Beliberi conecta en la consola sin desarrollo adicional.
- URL base de la API (pruebas y producción) y la ruta del endpoint de productos.
- Credencial por un canal seguro y el modo de autenticación (Bearer, cabecera, Basic o parámetro).
- Un ejemplo real de respuesta (una página completa) para preparar el mapeo de campos.
- Lista de sedes con el código de almacén de cada una y la moneda del catálogo.
En la consola de Beliberi, en Comercios › Conexión de datos, se elige "API REST genérica", se pegan la URL y el nombre del secreto, se mapea cada campo canónico a su ruta en el JSON, se indica la paginación y se pulsa "Probar conexión": Beliberi lee la primera página y muestra los productos tal como los entiende. Cada sede recibe su almacén en la pestaña "Por sede".
Checklist de aceptación
- La primera página responde en menos de 5 s con credencial válida y
401sin ella. - Todos los productos vendibles tienen SKU, nombre, precio y stock; ningún SKU se repite en la misma sede.
- El stock de una sede coincide con el del POS para 10 productos elegidos al azar.
- Un cambio de precio o de stock en el POS se ve en Beliberi en la siguiente sincronización (máximo 15 minutos).
- Un producto desactivado en el POS deja de venderse en Beliberi sin borrar su historial.
- Las fotos abren desde una red externa (no solo desde la red del comercio).
- La paginación recorre el catálogo completo: el total de productos leídos coincide con el del POS.
- Si se activa el envío de pedidos, un pedido de prueba llega al POS una sola vez aunque Beliberi lo reintente.
El historial de cada sincronización (productos leídos, creados, actualizados, errores) queda en Catálogo › Sincronizaciones de la consola, al alcance del comercio y de Beliberi.
10. Mapeo a Beliberi
Estos son los campos canónicos que el conector de Beliberi rellena a partir de la respuesta del POS. En la consola, cada uno recibe la ruta donde vive en el JSON del comercio; los nombres sugeridos en este documento son solo eso, una sugerencia.
| Campo en Beliberi | Nombre sugerido en la API | Obligatorio | Si falta |
|---|---|---|---|
Codigo | sku | Sí | El producto no se importa |
NombreProducto | nombre | Sí | El producto no se importa |
Precio | precio | Sí | Se importa con precio 0 y no se vende |
stock | stock (o existencias[].stock por almacén) | Sí | Se importa agotado |
Barra | codigo_barras | No | Se usa el SKU para el escáner |
Marca | marca | No | Sin marca |
Categoria | categoria_codigo | No | Se deriva del nombre de categoría |
Descripcion | categoria_nombre | No | Se usa el código |
Subcategoria | subcategoria_codigo | No | Se usa la subcategoría por nombre |
Descripcion_categoria | subcategoria_nombre | No | Se usa la categoría |
Iva | iva | No | 0 % |
Imagen | imagen_url | No | Marcador de imagen |
El resto de campos sugeridos (activo, descripcion, unidad, peso_gramos, actualizado_en, precio_descuento, modificadores, sedes) no los lee todavía el conector genérico: quedan documentados para que el comercio los exponga desde el principio y no haya que cambiar su API cuando Beliberi los use. Mientras tanto, un producto desactivado se retira dejándolo con stock 0 o quitándolo de la lista.
Preguntas abiertas para cerrar con cada comercio
- Moneda del catálogo y si el precio incluye IVA.
- Si el precio o el stock varían por sede.
- Si la API admite
actualizado_desdeo solo lectura completa. - Si quieren recibir los pedidos en el POS y quién factura.
