Convenciones de la API
Esta página describe las convenciones que se aplican a todos los endpoints de TPVReady. Conocerlas evita sorpresas.
Identificadores: tokens UUID
Todos los recursos se exponen mediante un token UUID, no IDs numéricos:
✅ GET /api/clientes/8f4a9e2b-1c3d-4e5f-9a8b-7c6d5e4f3a2b
❌ GET /api/clientes/142
Por qué: los IDs internos son secuenciales y permitirían adivinar la cantidad de registros o atacar por enumeración. Los tokens UUID son aleatorios.
Excepción: las relaciones a tablas maestras (proveedor_id, almacen_id, tipo_iva_id, forma_pago_id) usan IDs numéricos porque son catálogos cerrados y compartidos, no recursos accesibles individualmente.
Fechas y horas
Formato ISO 8601 en UTC:
2026-05-25T14:30:00Z
Para fechas sin hora:
2026-05-25
Filtros de rango (cuando un endpoint los acepta):
?desde=2026-01-01&hasta=2026-03-31
desde y hasta son inclusivos.
Codificación
- Petición y respuesta: JSON UTF-8.
- Cabecera:
Content-Type: application/jsonen peticiones con cuerpo. - Caracteres especiales: tildes, ñ y emojis se manejan sin escape.
Multitenancy
Cada credencial está vinculada a una empresa. La API filtra automáticamente por la empresa correspondiente. No envíes empresa_id en las peticiones: se ignora.
Si tu aplicación trabaja con varias empresas, mantén un mapa empresa_cliente → credencial y usa la credencial correcta en cada petición.
Paginación
Los endpoints de listado aceptan:
| Parámetro | Tipo | Por defecto | Máximo |
|---|---|---|---|
page | int | 1 | — |
page_size | int | 50 | 200 |
Y devuelven:
{
"items": [ /* ... */ ],
"total": 1234,
"page": 1,
"page_size": 50
}
Para iterar todos los resultados:
page = 1
while True:
resp = requests.get(
f"{API_BASE}/clientes",
headers=auth_headers,
params={"page": page, "page_size": 100},
).json()
for item in resp["items"]:
procesar(item)
if page * resp["page_size"] >= resp["total"]:
break
page += 1
Filtrado y búsqueda
Los endpoints de listado aceptan parámetros de query opcionales. Los más comunes:
| Parámetro | Significado |
|---|---|
q | Búsqueda textual (nombre, código, email, teléfono…) |
activo | true / false |
desde, hasta | Rango de fechas (campo varía por endpoint) |
Los parámetros disponibles varían por endpoint — consulta la referencia interactiva para los detalles de cada uno.
Estructura de respuesta
Respuesta exitosa
Si la operación es correcta:
HTTP/1.1 200 OK
Content-Type: application/json
{ /* datos del recurso o lista paginada */ }
Para creación:
HTTP/1.1 201 Created
Para borrado u operaciones sin cuerpo:
HTTP/1.1 200 OK
{ "ok": true, "mensaje": "..." }
Respuesta de error
Todos los errores siguen este formato:
{
"detail": "Mensaje descriptivo del error"
}
Para errores de validación (422), detail es una lista con el detalle de cada campo:
{
"detail": [
{
"loc": ["body", "email"],
"msg": "value is not a valid email address",
"type": "value_error.email"
}
]
}
Ver Códigos de error para detalles.
Cabeceras adicionales recomendadas
User-Agent
Aunque no es obligatorio, ayuda al soporte si surge un problema:
User-Agent: MiIntegracion/1.4.2 (+contacto@miempresa.com)
Accept-Language
Solo afecta a algunos endpoints (mensajes de error, plantillas). Por defecto es-ES.
Idempotency-Key
En desarrollo. En endpoints de escritura idempotentes (POST de recursos con CIF/email único), incluir esta cabecera evitará duplicados si tu petición falla con timeout y se reintenta.
Limitaciones técnicas actuales
- Sin rate limiting activo en producción. Te pedimos respeto: no hagas polling agresivo. Ver Buenas prácticas.
- Timeout recomendado en cliente: 20-30 segundos. Algunas listas grandes pueden tardar.
- Tamaño máximo de payload en POST/PUT: 10 MB.