Gastos
Un gasto (expense) registra un egreso operativo de una sucursal —servicios, alquiler, suministros, etc.— que no aumenta el inventario. Opcionalmente puede asociarse a un proveedor y a un método de pago.
La URL base de producción es https://api-pos.zelta.dev/public/v1 y todas las rutas se expresan relativas a ella. Todas las peticiones deben hacerse sobre HTTPS e incluir tu API key. Consulta .
Registrar un gasto
POST /expenses| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
branchId | string (cuid2) | No | Sucursal del gasto. Por defecto, la sucursal de la API key. |
category | string (≤100) | Sí | Categoría del gasto (ej. "Servicios", "Alquiler"). |
description | string (≤500) | No | Descripción del gasto. |
amount | number (≥0) | Sí | Monto base del gasto, en B/. |
taxAmount | number (≥0) | No | Impuesto del gasto, en B/. |
supplierId | string (cuid2) | No | Proveedor asociado. |
paymentMethod | string (cuid2) | No | Método de pago. Si se envía, el gasto se registra como movimiento de efectivo en la sesión de caja. |
INFO
Cuando incluyes paymentMethod, Zelta POS asienta el gasto como un movimiento de salida de efectivo en la sesión de caja activa de la sucursal. Si lo omites, el gasto se registra sin afectar la caja.
curl -X POST "https://api-pos.zelta.dev/public/v1/expenses" \
-H "Authorization: Bearer zpk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"category": "Servicios",
"description": "Factura de energía eléctrica - enero",
"amount": 142.50,
"taxAmount": 9.98,
"supplierId": "pr8h3k6m9p2q5v8r1n4t7w0y",
"paymentMethod": "pm3b8n5k2j7h9g4f1d6s0a8q"
}'Ejemplo JS
const res = await fetch('https://api-pos.zelta.dev/public/v1/expenses', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.ZELTA_POS_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
category: 'Servicios',
description: 'Factura de energía eléctrica - enero',
amount: 142.50,
taxAmount: 9.98,
supplierId: 'pr8h3k6m9p2q5v8r1n4t7w0y',
paymentMethod: 'pm3b8n5k2j7h9g4f1d6s0a8q'
})
});
const data = await res.json();Ejemplo Py
import requests
res = requests.post(
'https://api-pos.zelta.dev/public/v1/expenses',
headers={'Authorization': 'Bearer zpk_live_xxx', 'Content-Type': 'application/json'},
json={
'category': 'Servicios',
'description': 'Factura de energía eléctrica - enero',
'amount': 142.50,
'taxAmount': 9.98,
'supplierId': 'pr8h3k6m9p2q5v8r1n4t7w0y',
'paymentMethod': 'pm3b8n5k2j7h9g4f1d6s0a8q'
}
)
data = res.json()Respuesta 201 Created:
{
"id": "ex2k5m8p1q4v7r0n3t6w9y2z",
"branchId": "br3b8n5k2j7h9g4f1d6s0a8q",
"supplierId": "pr8h3k6m9p2q5v8r1n4t7w0y",
"paymentMethodId": "pm3b8n5k2j7h9g4f1d6s0a8q",
"category": "Servicios",
"description": "Factura de energía eléctrica - enero",
"amount": 142.50,
"taxAmount": 9.98,
"total": 152.48,
"date": "2026-01-31T20:15:00.000Z",
"createdAt": "2026-01-31T20:15:00.000Z",
"updatedAt": "2026-01-31T20:15:00.000Z"
}Los campos supplierId, paymentMethodId y description pueden ser null.
Problemas comunes
| Código | HTTP | Causa |
|---|---|---|
validation_error | 400 | Falta category, amount negativo o tipos inválidos. |
unauthorized | 401 | API key ausente o inválida. |
not_found | 404 | La branchId, el supplierId o el paymentMethod no existen. |
conflict | 409 | Se envió paymentMethod pero no hay una sesión de caja abierta. |
Listar gastos
GET /expensesAcepta los parámetros de : start, limit, updatedSince, from, to y metadata.
curl "https://api-pos.zelta.dev/public/v1/expenses?from=2026-01-01&to=2026-01-31&metadata=true" \
-H "Authorization: Bearer zpk_live_xxx"Ejemplo JS
const res = await fetch('https://api-pos.zelta.dev/public/v1/expenses?from=2026-01-01&to=2026-01-31&metadata=true', {
headers: { 'Authorization': `Bearer ${process.env.ZELTA_POS_API_KEY}` }
});
const data = await res.json();Ejemplo Py
import requests
res = requests.get(
'https://api-pos.zelta.dev/public/v1/expenses',
headers={'Authorization': 'Bearer zpk_live_xxx'},
params={'from': '2026-01-01', 'to': '2026-01-31', 'metadata': 'true'}
)
data = res.json()Respuesta 200 OK:
{
"data": [
{
"id": "ex2k5m8p1q4v7r0n3t6w9y2z",
"branchId": "br3b8n5k2j7h9g4f1d6s0a8q",
"supplierId": "pr8h3k6m9p2q5v8r1n4t7w0y",
"paymentMethodId": "pm3b8n5k2j7h9g4f1d6s0a8q",
"category": "Servicios",
"description": "Factura de energía eléctrica - enero",
"amount": 142.50,
"taxAmount": 9.98,
"total": 152.48,
"date": "2026-01-31T20:15:00.000Z",
"createdAt": "2026-01-31T20:15:00.000Z",
"updatedAt": "2026-01-31T20:15:00.000Z"
}
],
"metadata": { "total": 87 }
}Obtener un gasto
GET /expenses/{id}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
id | string (cuid2) | Sí | Identificador del gasto. |
Devuelve el objeto del gasto directamente (sin envoltorio). Si no existe, responde 404 not_found.
Actualizar un gasto
PUT /expenses/{id}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
category | string (≤100) | No | Nueva categoría. |
description | string o null | No | Nueva descripción. |
amount | number (≥0) | No | Nuevo monto base. |
taxAmount | number (≥0) | No | Nuevo impuesto. |
supplierId | string (cuid2) o null | No | Cambia o elimina el proveedor. |
paymentMethod | string (cuid2) o null | No | Cambia o elimina el método de pago. |
WARNING
Debes enviar al menos uno de los campos anteriores. Una petición con el cuerpo vacío devuelve validation_error.
curl -X PUT "https://api-pos.zelta.dev/public/v1/expenses/ex2k5m8p1q4v7r0n3t6w9y2z" \
-H "Authorization: Bearer zpk_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "amount": 150.00, "description": "Factura de energía eléctrica - enero (corregida)" }'Ejemplo JS
const res = await fetch('https://api-pos.zelta.dev/public/v1/expenses/ex2k5m8p1q4v7r0n3t6w9y2z', {
method: 'PUT',
headers: { 'Authorization': `Bearer ${process.env.ZELTA_POS_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: 150.00, description: 'Factura de energía eléctrica - enero (corregida)' })
});
const data = await res.json();Ejemplo Py
import requests
res = requests.put(
'https://api-pos.zelta.dev/public/v1/expenses/ex2k5m8p1q4v7r0n3t6w9y2z',
headers={'Authorization': 'Bearer zpk_live_xxx', 'Content-Type': 'application/json'},
json={ 'amount': 150.00, 'description': 'Factura de energía eléctrica - enero (corregida)' }
)
data = res.json()Respuesta 200 OK: devuelve el objeto del gasto actualizado. Si no existe, responde 404 not_found.
Problemas comunes
| Código | HTTP | Causa |
|---|---|---|
validation_error | 400 | Cuerpo vacío o tipos inválidos. |
unauthorized | 401 | API key ausente o inválida. |
not_found | 404 | El gasto, el supplierId o el paymentMethod no existen. |
Siguientes pasos
- — registra egresos que sí aumentan inventario.
- — gestiona cobros y abonos.
- — descubre métodos de pago, sucursales y proveedores.
- — paginación, sincronización y códigos de error.