Saltar al contenido principal

API: usuarios y códigos

Contrato general en Cómo funciona la API. Es la parte de la API que más se integra: sincronizar la nómina del cliente con los consumidores de INSSACS.

Usuarios consumidores

POST /consumers
GET /consumers
GET /consumers/summary
GET /consumers/:id
PATCH /consumers/:id
PATCH /consumers/:id/active
DELETE /consumers/:id
GET /consumers/:id/entitlements

Crear — 201

CampoTipoObligatorioNotas
namestring
identificationstringúnico dentro de la cuenta
tags{ key, value }[]nokey debe existir en las etiquetas de la cuenta
accountIdstringnose ignora: manda la cuenta de la key
initialCodeobjetonocrea el primer código en la misma llamada
curl -X POST https://api.inssacs.com/consumers \
-H 'x-api-key: ics_…' -H 'content-type: application/json' \
-d '{
"name": "Juan Pérez",
"identification": "1023456789",
"tags": [{ "key": "departamento", "value": "Producción" }],
"initialCode": { "codeId": "1023456789", "codeType": "QR", "operationId": "665f…c7" }
}'

Respuesta: el consumidor con sus códigos.

{
"id": "665f…e1",
"clientId": "665f…c5",
"accountId": "665f…c6",
"name": "Juan Pérez",
"identification": "1023456789",
"isActive": true,
"tags": [{ "key": "departamento", "value": "Producción" }],
"codes": [
{
"codeId": "1023456789",
"codeType": "QR",
"operationId": "665f…c7",
"isActive": true,
"vendingProfileId": null,
"easProfileId": null,
"vendingBalance": 0,
"vendingRecharge": 0
}
],
"createdAt": "2026-08-11T14:03:00.000Z"
}

Editar y estado

  • PATCH /consumers/:idname, identification, tags (opcionales). 200.
  • PATCH /consumers/:id/active con { "active": false } → desactiva al usuario y con él todos sus códigos. 200.
  • DELETE /consumers/:id204; borra códigos, etiquetas y productos EAS asignados. Las entregas históricas se conservan.

Consultar

  • GET /consumers — query: operationId, isActive, search (nombre, identificación o código), page, pageSize (máx. 1000).
  • GET /consumers/summary — conteos de usuarios y códigos, activos e inactivos.
  • GET /consumers/:id/entitlements — lo que ese usuario puede sacar hoy: útil para mostrar cupos en un portal propio.

Errores: 409 consumers.identification_exists, 404 consumers.not_found, 400 consumers.unknown_tag_key, 400 consumers.too_many_tags.

Códigos

POST /consumers/:id/codes
PATCH /consumers/:id/codes/:codeId
DELETE /consumers/:id/codes/:codeId
PATCH /consumers/:id/codes/:codeId/active
PUT /consumers/:id/codes/:codeId/profile
DELETE /consumers/:id/codes/:codeId/profile/:businessLine

Agregar un código — 201

CampoTipoObligatorioNotas
codeIdstringel valor que lee la máquina
codeTypestringQR, NFC, FINGERPRINT, CODE128, CODE39, PDF417, EAN13, UPCA, MAXICODE, MRZ
operationIdstringnoomitir = código de cuenta: mismo valor, saldo y cupo en todas las operaciones
vending.balanceenteronosaldo inicial en unidades menores

El código nace sin perfiles: sus líneas se definen asignándolos.

Asignar y quitar perfil

PUT /consumers/:id/codes/:codeId/profile { "profileId": "665f…d1" }
DELETE /consumers/:id/codes/:codeId/profile/vending
DELETE /consumers/:id/codes/:codeId/profile/eas

La línea sale del perfil: si el perfil es vending, ocupa la ranura vending. El perfil debe ser de la cuenta del usuario (400 consumers.profile_not_for_this_account) y el código debe conservar al menos un perfil (409 consumers.code_requires_profile).

Editar un código

PATCH /consumers/:id/codes/:codeId:

CampoTipoNotas
newCodeIdstringcambia el valor; se revalida su unicidad
codeTypestringcambiar desde FINGERPRINT borra las huellas
vendingBalanceenterofija el saldo de subsidio
operationIdstring | nullmueve de nivel; null = pasa a nivel cuenta. Conserva saldo y perfiles
lineProfilesobjetofija los dos perfiles de una vez

Conflictos de valor al mover de nivel: 409 consumers.code_value_taken_in_operation y 409 consumers.code_value_taken_at_account.

Estado y baja

  • PATCH …/active con { "active": false } → deshabilita solo ese código.
  • DELETE …204. El histórico se conserva.

Huellas

GET /consumers/:consumerId/codes/:codeId/fingerprints
POST /consumers/:consumerId/codes/:codeId/fingerprints
DELETE /consumers/:consumerId/codes/:codeId/fingerprints/:fingerId

Solo en códigos FINGERPRINT. El POST espera el dedo y sus muestras ya capturadas por el lector:

CampoTipoObligatorioNotas
fingerIdentero 0–9qué dedo
fingerLabelstringnoÍndice derecho
fingerprintsobjeto[]las muestras (template en base64)

Errores: 422 consumers.no_fingerprint_template, 409 consumers.fingerprint_already_enrolled, 409 consumers.too_many_fingerprints, 400 consumers.code_not_fingerprint.

El template lo produce el lector

La API no captura huellas: recibe los templates que genera el agente local del lector. Sin ese agente no hay enrolamiento posible.

Cargas en lote

POST /consumers/bulk { "items": [ … ] }
POST /consumers/codes/bulk { "items": [ … ] }

Cada item lleva su campo op y los datos de esa operación:

EndpointValores de op
/consumers/bulkcreate, update, delete, upsert
/consumers/codes/bulkcreate, update, delete
{
"items": [
{ "op": "create", "name": "Juan Pérez", "identification": "1023456789" },
{ "op": "update", "identification": "1010087922", "name": "Ana Ruiz" }
]
}

La respuesta es 201 con el resultado por fila: una fila inválida no aborta el lote.

{
"summary": { "created": 1, "updated": 1, "deleted": 0, "failed": 0 },
"results": [{ "index": 0, "op": "create", "status": "created", "id": "665f…e9" }]
}

Es el camino recomendado para sincronizar nóminas: una llamada en vez de N.

Permiso del lote

Como el lote es multi-op, no exige una acción concreta sino al menos una de create, update o delete sobre el recurso (consumers para el primero, codes para el segundo). Sin ninguna, responde 403. Después, cada fila se autoriza por su propia operación: con solo create las filas update o delete fallan individualmente y el resto del lote sigue.