Saltar a contenido

API

Aquí aprendes a autenticarte y a consumir la API que usa la propia aplicación, para integrar Agapanto con otros sistemas. La API vive en /api/v1 y su documentación interactiva (OpenAPI, generada con Django Ninja) está en /api/v1/docs.

Permiso

La API no tiene permisos propios: cada token representa un rol y hereda sus permisos. Un rol sin ACCESO_INVENTARIO recibe 403 permiso_denegado en /api/v1/inventario/…, igual que en la aplicación. El plan de la empresa debe incluir acceso a la API (Profesional o Empresarial; ver Planes y límites).

Un vistazo

/api/v1/docs
apiPOS API 1.0.0lock Authorize 1
POST
/api/v1/auth/loginauth · usuario + contraseña → roles
2
POST
/api/v1/auth/tokenauth · elige rol → access + refresh
POST
/api/v1/auth/refreshauth · renueva el par
GET
/api/v1/caja/diariacaja
3
GET
/api/v1/inventario/movimientosinventario
POST
/api/v1/procesos/…procesos
La documentación agrupa las operaciones por router. Con Authorize pegas el access y puedes probar desde el navegador.
  1. 1 Todas las operaciones (salvo /auth/*) exigen la cabecera Authorization: Bearer <access>.
  2. 2 El login devuelve la lista de roles del usuario; si tiene uno solo, ya trae los tokens.
  3. 3 Cada router corresponde a un módulo de la aplicación y respeta sus permisos.

Autenticación por rol

sequenceDiagram
    participant C as Tu sistema
    participant A as /api/v1/auth
    C->>A: POST /login {username, password}
    A-->>C: roles[] (+ access/refresh si hay un solo rol)
    C->>A: POST /token {username, password, rol_id}
    A-->>C: {access, refresh, empresa}
    C->>A: POST /refresh {refresh}
    A-->>C: nuevo {access, refresh}
  • Los tokens se emiten por rol: llevan las claims rol_id y empresa_id. Cambiar de empresa es pedir otro par con otro rol_id.
  • rol_id acepta el entero o el rol_uuid que devuelve el login.
  • /refresh rota el par: el refresh anterior deja de servir.
  • Si la empresa tiene la suscripción vencida, cualquier llamada responde 402 con trial_vencido o suscripcion_vencida. Si el rol tiene ACCESO_SOLO_RED_POS y no estás en la red del POS, 403 con pos_network_required.

Con verificación en dos pasos (2FA)

Si el usuario tiene 2FA activo, /login y /token responden 401 {"detail": "otp_required"} hasta que envíes el código:

  1. Repite /login agregando "otp_code": "123456".
  2. Si el usuario tiene varios roles, la respuesta incluye un otp_token (válido 2 minutos). Envíalo en /token como "otp_token" en lugar de repetir el código: un código TOTP no se puede reutilizar.

Routers

Router Prefijo Para qué
auth /api/v1/auth Login, selección de rol, refresh, cierre de sesión.
pos /api/v1/pos Pantalla de ventas: catálogo, carrito/prefacturas, guardar factura.
caja /api/v1/caja Caja diaria, cierres, reimpresión.
cocina /api/v1/cocina Recetas, ingredientes y conversiones.
facturacion /api/v1/facturacion Cartera, pedidos, cotizaciones, facturas recurrentes, formatos.
inventario /api/v1/inventario Productos, precios, ajustes, movimientos, familias.
contabilidad /api/v1/contabilidad Asientos, cuentas, periodos, cierre.
activos /api/v1/activos Activos fijos y depreciación.
config /api/v1/config Secciones del panel de configuración (impresoras, tokens, credenciales…).
mercadolibre /api/v1/mercadolibre Conexión, publicaciones, órdenes, preguntas y mensajes.
reports /api/v1/reports Reportes contables (panel, PyG, flujo de caja, cartera vencida).
util /api/v1/util Exportar CSV y operaciones de billetera.
equipo /api/v1/equipo Miembros, roles e invitaciones (exige GESTIONAR_EQUIPO).
nomina /api/v1/nomina Empleados, periodos, documentos de nómina.
procesos /api/v1/procesos Flujos, órdenes, items y transiciones de procesos internos.

La lista exacta de operaciones y sus parámetros está en /api/v1/docs.

Ejemplos

curl -s -X POST https://agapanto.com.co/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "ana.restrepo", "password": "••••••••"}'
{
  "username": "ana.restrepo",
  "roles": [
    {"rol_id": 41, "rol_uuid": "0192e7a3-…", "rol_nombre": "Propietario",
     "empresa_id": 53, "empresa_nombre": "Panadería Los Manjares"},
    {"rol_id": 58, "rol_uuid": "0192f100-…", "rol_nombre": "Contador",
     "empresa_id": 61, "empresa_nombre": "Café La Esquina"}
  ]
}
curl -s -X POST https://agapanto.com.co/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"username": "ana.restrepo", "password": "••••••••", "rol_id": 41}'
{"access": "eyJhbGciOi…", "refresh": "eyJhbGciOi…",
 "empresa": {"id": 53, "nombre": "Panadería Los Manjares"}}
curl -s https://agapanto.com.co/api/v1/caja/diaria \
  -H "Authorization: Bearer eyJhbGciOi…"

Cuando el access expire (respuesta 401), renueva sin pedir la contraseña:

curl -s -X POST https://agapanto.com.co/api/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{"refresh": "eyJhbGciOi…"}'

Cuotas del plan

El plan define si la empresa tiene acceso a la API y un cupo diario de solicitudes: 10.000 en Profesional y 50.000 en Empresarial. El plan Básico no incluye API. Diseña tu integración para no consultar en bucle: usa refresh en vez de repetir el login y consulta listas con filtros.

Misma lógica que la aplicación

Cada operación ejecuta la misma lógica de negocio que la pantalla correspondiente: una factura creada por API descuenta inventario, registra el asiento y aparece en la caja diaria igual que una hecha en el POS.

¿Problemas?
  • 401 Credenciales inválidas. Usuario o contraseña incorrectos, o el usuario está inactivo.
  • 401 otp_required. El usuario tiene 2FA; envía otp_code (ver arriba).
  • 401 Rol inválido. El rol_id no pertenece a ese usuario. Usa uno de los que devolvió /login.
  • 402 suscripcion_vencida / trial_vencido. La empresa está bloqueada por pago. Ver Planes y límites.
  • 403 permiso_denegado. El rol no tiene el permiso del router. Ver Roles y permisos.
  • 403 pos_network_required. El rol está limitado a la red del POS. Ver Seguridad.

Siguiente: Bots e IA.