Capítulo 7: API REST de EPCIS 2.0
Por qué una API REST estándar
EPCIS 1.x no definía una API de comunicación estándar. Cada proveedor (SAP, IBM, rfXcel, TraceLink) implementaba su propia API propietaria. Esto significaba que integrar dos repositorios EPCIS requería adapters custom para cada combinación de proveedores.
EPCIS 2.0 resuelve esto definiendo una API REST con especificación OpenAPI oficial, publicada en el GitHub de GS1. Cualquier repositorio que implemente esta API es interoperable con cualquier cliente que la consuma.
Estructura general de la API
La API se divide en dos módulos:
| Módulo | Propósito | Endpoints principales |
|---|---|---|
| Capture API | Enviar eventos al repositorio | POST /capture |
| Query API | Consultar eventos almacenados | GET /events, GET /epcs |
EPCIS Capture API
POST /capture
Envía un batch de eventos al repositorio. La captura puede ser síncrona (respuesta inmediata) o asíncrona (respuesta con ID de job para consultar estado).
POST /capture HTTP/1.1
Host: epcis.ejemplo.com
Content-Type: application/ld+json; profile="https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"
GS1-EPCIS-Version: 2.0.0
GS1-CBV-Version: 2.0.0
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
{
"@context": "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld",
"type": "EPCISDocument",
"schemaVersion": "2.0",
"creationDate": "2026-03-21T10:00:00Z",
"epcisBody": {
"eventList": [
{
"type": "ObjectEvent",
"eventTime": "2026-03-21T09:00:00Z",
"eventTimeZoneOffset": "-03:00",
"epcList": ["urn:epc:id:sgtin:0614141.107340.2026001"],
"action": "OBSERVE",
"bizStep": "shipping",
"disposition": "in_transit",
"readPoint": { "id": "urn:epc:id:sgln:0614141.07346.1234" }
}
]
}
}
Respuesta síncrona (captura exitosa):
HTTP/1.1 201 Created
Location: /capture/abc123-def456
Respuesta asíncrona (captura en proceso):
HTTP/1.1 202 Accepted
Location: /capture/abc123-def456
GET /capture/{captureID}
Consulta el estado de un job de captura asíncrono:
GET /capture/abc123-def456 HTTP/1.1
Host: epcis.ejemplo.com
Authorization: Bearer {token}
Respuesta:
{
"captureID": "abc123-def456",
"running": false,
"success": true,
"capturedAt": "2026-03-21T10:00:05Z",
"errors": []
}
Límites de captura
El estándar recomienda que un repositorio acepte hasta 4000 eventos por request de captura. Para volúmenes mayores, se deben enviar múltiples requests.
EPCIS Query API
GET /events
Consulta eventos con filtros. Es el endpoint más usado:
GET /events?eventType=ObjectEvent&EQ_bizStep=shipping&GE_eventTime=2026-03-01T00:00:00Z HTTP/1.1
Host: epcis.ejemplo.com
Accept: application/ld+json
Authorization: Bearer {token}
Respuesta:
{
"@context": "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld",
"type": "EPCISQueryDocument",
"schemaVersion": "2.0",
"epcisBody": {
"queryResults": {
"resultsBody": {
"eventList": [
{
"type": "ObjectEvent",
"eventTime": "2026-03-21T09:00:00Z",
"eventTimeZoneOffset": "-03:00",
"epcList": ["urn:epc:id:sgtin:0614141.107340.2026001"],
"action": "OBSERVE",
"bizStep": "shipping",
"disposition": "in_transit"
}
]
}
}
}
}
Parámetros de filtro
Los parámetros usan prefijos que indican el tipo de comparación:
| Prefijo | Significado | Ejemplo |
|---|---|---|
EQ_ | Igual a | EQ_bizStep=shipping |
GE_ | Mayor o igual | GE_eventTime=2026-03-01T00:00:00Z |
LT_ | Menor que | LT_eventTime=2026-04-01T00:00:00Z |
MATCH_ | Match de patrón EPC | MATCH_epc=urn:epc:id:sgtin:0614141.* |
WD_ | With descendants | WD_bizLocation=urn:epc:id:sgln:0614141.07346.0 |
HASATTR_ | Tiene atributo | HASATTR_sensorReport |
Filtros más comunes:
| Parámetro | Descripción | Ejemplo |
|---|---|---|
eventType | Tipo de evento | ObjectEvent |
GE_eventTime | Desde fecha | 2026-03-01T00:00:00Z |
LT_eventTime | Hasta fecha | 2026-04-01T00:00:00Z |
EQ_bizStep | Por paso de negocio | shipping |
EQ_bizLocation | Por ubicación | urn:epc:id:sgln:0614141.07346.0 |
EQ_disposition | Por estado | in_transit |
MATCH_epc | Por EPC exacto | urn:epc:id:sgtin:0614141.107340.2026001 |
MATCH_epcClass | Por clase de EPC | urn:epc:class:lgtin:0614141.107340.* |
EQ_action | Por acción | OBSERVE |
GET /events/{eventID}
Obtener un evento específico por su ID (hash del evento):
GET /events/ni:///sha-256;abc123...?format=application/ld+json HTTP/1.1
Host: epcis.ejemplo.com
Authorization: Bearer {token}
GET /epcs/{epc}/events
Todos los eventos de un EPC específico. Es el endpoint más útil para trazabilidad end-to-end:
GET /epcs/urn:epc:id:sgtin:0614141.107340.2026001/events HTTP/1.1
Host: epcis.ejemplo.com
Authorization: Bearer {token}
Retorna la historia completa de ese producto: desde commissioning hasta la venta o destrucción.
Endpoints de vocabulario
| Endpoint | Descripción |
|---|---|
GET /bizSteps | Valores bizStep disponibles en el repositorio |
GET /dispositions | Valores disposition disponibles |
GET /bizLocations | Ubicaciones conocidas |
GET /readPoints | Puntos de lectura conocidos |
GET /eventTypes | Tipos de evento disponibles |
Headers GS1 estándar
La API define headers custom con prefijo GS1-:
| Header | Descripción | Ejemplo |
|---|---|---|
GS1-EPCIS-Version | Versión de EPCIS | 2.0.0 |
GS1-CBV-Version | Versión del CBV | 2.0.0 |
GS1-Extensions | Extensiones soportadas | Custom |
GS1-EPCIS-Min | Versión mínima soportada | 2.0.0 |
GS1-EPCIS-Max | Versión máxima soportada | 2.0.0 |
GS1-Capture-Error-Behaviour | Comportamiento ante errores | rollback o proceed |
Paginación
Para resultados grandes, la API usa paginación basada en tokens:
GET /events?perPage=100 HTTP/1.1
Respuesta con siguiente página:
HTTP/1.1 200 OK
Link: </events?perPage=100&nextPageToken=abc123>; rel="next"
GS1-Next-Page-Token-Expires: 2026-03-21T11:00:00Z
Para obtener la siguiente página:
GET /events?perPage=100&nextPageToken=abc123 HTTP/1.1
El token de paginación tiene un tiempo de expiración. Si expira, se debe reiniciar la consulta desde el principio.
Autenticación
GS1 recomienda OAuth 2.0 Bearer token para autenticación:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
El estándar no prescribe un proveedor OAuth específico. Cada implementación puede usar su propio identity provider (Auth0, Keycloak, Azure AD, etc.).
Webhooks y suscripciones
Para recibir eventos en tiempo real sin polling, EPCIS 2.0 define suscripciones:
Crear suscripción
POST /queries/SimpleEventQuery/subscriptions HTTP/1.1
Host: epcis.ejemplo.com
Content-Type: application/json
Authorization: Bearer {token}
{
"dest": "https://mi-sistema.com/webhooks/epcis",
"signatureToken": "mi-secreto-para-verificar",
"reportIfEmpty": false,
"schedule": {
"second": "0",
"minute": "*/5"
},
"queryName": "SimpleEventQuery",
"params": {
"EQ_bizStep": "shipping",
"EQ_bizLocation": "urn:epc:id:sgln:0614141.07346.0"
}
}
Esto crea una suscripción que envía eventos de shipping cada 5 minutos al webhook configurado. También se puede usar WebSockets para streaming en tiempo real.
Listar suscripciones activas
GET /queries/SimpleEventQuery/subscriptions HTTP/1.1
Eliminar suscripción
DELETE /queries/SimpleEventQuery/subscriptions/{subscriptionID} HTTP/1.1
Próximo capítulo
En el capítulo 8 veremos herramientas open source para trabajar con EPCIS y casos de uso reales en farmacia (DSCSA) y alimentos (FSMA 204).