Referencia de la API
Todo MyProductPassport está disponible mediante una API REST autenticada con clave: cree productos, genere y publique pasaportes digitales de producto, envíe datos de batería en tiempo real y compruebe la conformidad, directamente desde su ERP, PIM o canal de compilación.
01 / Primeros pasosAutenticación
Cada solicitud se autentica con una clave API enviada como token Bearer. Las claves se crean en la aplicación, en Claves API, se muestran una sola vez y se guardan con hash; cada clave tiene su propio conjunto de permisos, una lista opcional de IP permitidas y una fecha de caducidad opcional. Las claves se pueden rotar sin interrupciones.
Authorization: Bearer pk_your_api_keyLos permisos se conceden por clave, de modo que una integración solo obtiene lo que necesita:
| Permiso | Concesiones |
|---|---|
| products:read | Leer productos |
| products:write | Crear, actualizar y eliminar productos |
| passports:read | Leer pasaportes |
| passports:write | Generar pasaportes |
| passports:publish | Publicar y archivar pasaportes |
| webhooks:manage | Crear, probar y eliminar endpoints de webhook |
| items:read | Read individual items and their history |
| items:write | Add, update and flag individual items |
| aftersales:read | Read owner registrations and service requests |
| aftersales:write | Update service requests and reply to customers |
02 / Primeros pasosLímites de solicitudes
Los límites son por clave y por minuto, y dependen del plan:
| Plan | Solicitudes / minuto |
|---|---|
| Gratuito | 30 |
| Micro | 60 |
| E-Label | 60 |
| Starter | 120 |
| Professional | 300 |
| Business | 600 |
| Battery | 600 |
Cada respuesta incluye las cabeceras X-RateLimit-Limit y X-RateLimit-Remaining. Si se supera el límite se devuelve 429:
{ "error": "Rate limit exceeded.", "limit": 300, "retry_after": 60 }03 / Primeros pasosErrores
Los errores se devuelven en JSON con un código de estado habitual. Los más comunes:
| Estado | Significado | Cuerpo de ejemplo |
|---|---|---|
| 401 | Clave ausente, no válida, revocada o caducada | {"error": "Invalid or revoked API key."} |
| 403 | A la clave le falta un permiso, la IP no está en la lista permitida o se ha alcanzado el cupo del plan | {"message": "API key does not have 'products:write' permission."} |
| 404 | El recurso no existe en su espacio de trabajo | {"message": "Not found."} |
| 422 | La validación ha fallado | {"message": "…", "errors": {"gtin": ["…"]}} |
| 429 | Límite de solicitudes superado | {"error": "Rate limit exceeded."} |
04 / Primeros pasosPaginación
Los endpoints de listado devuelven 25 elementos por página con los objetos links y meta estándar. Pase ?page=2 para recorrer la colección.
05 / Primeros pasosConector de asistente de IA (MCP)
Conecta Claude, Cursor o cualquier asistente que hable el Model Context Protocol y pídele con tus palabras que cree productos, rellene pasaportes con lo que le digas y compruebe lo que falta. Usa una clave API con sus permisos y su límite de solicitudes. Puede crear borradores y rellenar campos; nunca publica, archiva ni elimina nada: eso sigue en tus manos en la aplicación.
https://myproductpassport.eu/api/mcpclaude mcp add --transport http myproductpassport https://myproductpassport.eu/api/mcp \
--header "Authorization: Bearer pk_live_your_key"{
"mcpServers": {
"myproductpassport": {
"url": "https://myproductpassport.eu/api/mcp",
"headers": { "Authorization": "Bearer pk_live_your_key" }
}
}
}{
"mcpServers": {
"myproductpassport": {
"command": "npx",
"args": ["mcp-remote", "https://myproductpassport.eu/api/mcp", "--header", "Authorization: Bearer pk_live_your_key"]
}
}
}Las herramientas que ofrece:
| Herramienta | Qué hace |
|---|---|
| list_products | Los productos del espacio de trabajo, del más reciente al más antiguo, 25 por página, con su sector y su último pasaporte. |
| get_product | Un producto con sus datos, sector, secciones normativas y último pasaporte. |
| list_sectors | Las plantillas de sector que puede usar un producto (textil, electrónica, baterías, vino y más), con sus identificadores. El sector de un producto decide qué campos del pasaporte son obligatorios. |
| create_product | Añade un producto al espacio de trabajo. Usa un sector_id de list_sectors. compliance_sections añade secciones normativas a su pasaporte: gpsr, epr, france, chemicals, eudr. |
| list_passports | Los pasaportes del espacio de trabajo, del más reciente al más antiguo, 25 por página, con su estado (draft, published, archived), porcentaje de cumplimiento y dirección pública. |
| get_passport | Un pasaporte: estado, versión, porcentaje de cumplimiento, dirección pública y enlaces al código QR. |
| create_passport | Crea un pasaporte en borrador para un producto. No se publica: lo publica una persona en la aplicación. |
| get_passport_fields | Lo que pide un pasaporte: las claves de los campos obligatorios y opcionales, qué significa cada uno (etiqueta, descripción, ejemplo), los valores que tiene y qué campos obligatorios faltan. |
| update_passport_fields | Escribe valores de campos en un pasaporte en borrador o publicado (uno publicado se actualiza en el sitio: misma dirección, mismo código QR). Claves de get_passport_fields; un texto vacío elimina un valor. Escribe solo hechos que indiquen el usuario o sus documentos. |
| get_compliance | La completitud de un pasaporte: porcentaje, estado y los campos obligatorios que aún faltan. |
06 / EndpointsCuenta
/me
Devuelve la cuenta autenticada, su plan de suscripción y cuánto se ha usado del límite de productos. Útil como comprobación de conexión.
curl https://myproductpassport.eu/api/v1/me \
-H "Authorization: Bearer pk_your_key"{
"data": {
"id": 42,
"name": "Jane Doe",
"email": "[email protected]",
"company_name": "Acme Ltd",
"subscription_tier": "professional",
"product_count": 128,
"product_limit": 500,
"passport_count": 96,
"organization": {"id": 7, "name": "Acme Ltd"},
"api_key": {"name": "ERP sync", "permissions": ["*"], "rate_limit_per_minute": 1000, "expires_at": null},
"webhooks_available": true
}
}07 / EndpointsProductos
/products
requiere products:read Lista los productos de su espacio de trabajo, del más reciente al más antiguo, 25 por página. Cada producto incluye su sector y un resumen de su pasaporte más reciente.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| page | integer | Número de página. |
curl "https://myproductpassport.eu/api/v1/products?page=1" \
-H "Authorization: Bearer pk_your_key"{
"data": [
{
"id": 512,
"name": "Alpine Merino Crew Sweater",
"sku": "AM-CREW-01",
"gtin": "05012345678900",
"brand": "Northloom",
"category": "textiles",
"status": "active",
"country_of_origin": "PT",
"weight": 0.4,
"weight_unit": "kg",
"materials": [
{ "name": "Merino wool (RWS)", "percentage": 78 },
{ "name": "Recycled nylon (GRS)", "percentage": 20 },
{ "name": "Elastane", "percentage": 2 }
],
"sector": { "id": 3, "name": "Textiles" },
"latest_passport": {
"id": 96, "version": 1,
"status": "published", "compliance_percentage": 100
},
"created_at": "2026-08-14T09:21:00+00:00",
"updated_at": "2026-09-01T16:02:11+00:00"
}
],
"links": { "next": null },
"meta": { "current_page": 1, "per_page": 25, "total": 1 }
}/products
requiere products:write Crea un producto. Falla con 403 si se ha agotado el cupo de productos del plan.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| name | string | obligatorio | Nombre del producto, hasta 255 caracteres. |
| sku | string | Su SKU interno, hasta 100 caracteres. | |
| gtin | string | GTIN-8, 12, 13 o 14 (solo dígitos). | |
| brand | string | Marca que se muestra en el pasaporte público. | |
| description | string | Hasta 2.000 caracteres. | |
| category | string | Categoría de texto libre. Por defecto, «general». | |
| sector_id | integer | Un identificador de sector, que selecciona la plantilla de campos del pasaporte. | |
| country_of_origin | string | Código de país, p. ej. «PT». | |
| weight | number | Peso neto. | |
| weight_unit | string | Uno de kg, g, lb, oz. Por defecto, kg. | |
| materials | array | Objetos de {name, percentage 0-100}. | |
| has_packaging | boolean | Añade al pasaporte los campos de la plantilla de embalaje (claves que empiezan por pkg_), con el mismo código QR. |
curl -X POST https://myproductpassport.eu/api/v1/products \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Alpine Merino Crew Sweater",
"sku": "AM-CREW-01",
"gtin": "05012345678900",
"sector_id": 3,
"materials": [
{"name": "Merino wool (RWS)", "percentage": 78},
{"name": "Recycled nylon (GRS)", "percentage": 22}
]
}'{
"data": {
"id": 513,
"name": "Alpine Merino Crew Sweater",
"sku": "AM-CREW-01",
"status": "active",
"sector": { "id": 3, "name": "Textiles" },
"created_at": "2026-09-07T18:40:00+00:00"
}
}/products/bulk
requiere products:write Crea hasta 100 productos en una llamada. Todo el lote se rechaza con 403 si superara el cupo de productos restante. Para catálogos de miles de artículos, llame a este endpoint en bucle o use la importación CSV de la aplicación.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| products | array | obligatorio | De 1 a 100 objetos de producto con los mismos campos que «Crear un producto» (sin materiales). |
curl -X POST https://myproductpassport.eu/api/v1/products/bulk \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{
"products": [
{"name": "PSL-BT-122000", "sku": "PSL-BT-122000", "sector_id": 5},
{"name": "PSL-BT-123000", "sku": "PSL-BT-123000", "sector_id": 5}
]
}'{
"message": "2 product(s) created.",
"products": [
{ "id": 514, "name": "PSL-BT-122000", "status": "active" },
{ "id": 515, "name": "PSL-BT-123000", "status": "active" }
]
}/products/{id}
requiere products:read Devuelve un producto con su sector y un resumen de su pasaporte más reciente. 404 si el id no está en su espacio de trabajo.
curl https://myproductpassport.eu/api/v1/products/512 \
-H "Authorization: Bearer pk_your_key"/products/{id}
requiere products:write Actualiza parcialmente un producto. Envíe solo los campos que quiera cambiar; la lista de campos es la misma que en Crear un producto.
curl -X PUT https://myproductpassport.eu/api/v1/products/512 \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"brand": "Northloom"}'/products/{id}
requiere products:write Elimina un producto de forma lógica (soft delete). Los pasaportes publicados del producto siguen funcionando, de modo que los códigos QR impresos nunca quedan huérfanos.
curl -X DELETE https://myproductpassport.eu/api/v1/products/512 \
-H "Authorization: Bearer pk_your_key"{ "message": "Product deleted." }08 / EndpointsPasaportes
/passports
requiere passports:read Lista los pasaportes, del más reciente al más antiguo, 25 por página, con resumen del producto y todos los campos del pasaporte.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| page | integer | Número de página. |
curl https://myproductpassport.eu/api/v1/passports \
-H "Authorization: Bearer pk_your_key"{
"data": [
{
"id": 96,
"uuid": "36ff3776-d517-4228-8cde-9208136ea84a",
"version": 1,
"status": "published",
"compliance_status": "compliant",
"compliance_percentage": 100,
"public_url": "https://myproductpassport.co.uk/p/36ff3776-…",
"gs1_url": "https://myproductpassport.co.uk/01/05012345678900",
"product": { "id": 512, "name": "Alpine Merino Crew Sweater", "sku": "AM-CREW-01" },
"fields": [
{ "key": "material_composition", "value": "…", "verification_status": "verified" }
],
"published_at": "2026-08-16T10:00:00+00:00"
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 1 }
}/products/{productId}/passports
requiere passports:write Genera un pasaporte en borrador para un producto y rellena los campos a partir de los datos del producto y la plantilla del sector. Devuelve el borrador con su puntuación de conformidad. Si el producto ya tiene un pasaporte publicado, devuelve 409 con ese pasaporte: corríjalo con PUT /passports/{id}/fields, que conserva su dirección y su código QR.
curl -X POST https://myproductpassport.eu/api/v1/products/512/passports \
-H "Authorization: Bearer pk_your_key"/passports/{id}
requiere passports:read Devuelve un pasaporte con el producto, los campos, la URL pública y el GS1 Digital Link.
curl https://myproductpassport.eu/api/v1/passports/96 \
-H "Authorization: Bearer pk_your_key"/passports/{id}/publish
requiere passports:publish Publica un borrador de pasaporte y activa su página pública y su código QR. Solo se pueden publicar borradores; cualquier otro estado devuelve 404.
curl -X POST https://myproductpassport.eu/api/v1/passports/96/publish \
-H "Authorization: Bearer pk_your_key"/passports/{id}/archive
requiere passports:publish Archiva un pasaporte y retira su página pública de la circulación.
curl -X POST https://myproductpassport.eu/api/v1/passports/96/archive \
-H "Authorization: Bearer pk_your_key"/passports/bulk-publish
requiere passports:publish Publica hasta 50 borradores de pasaporte en una sola llamada e informa del resultado de cada uno, de modo que un fallo nunca aborta el lote.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| passport_ids | array | obligatorio | De 1 a 50 identificadores de pasaporte. |
curl -X POST https://myproductpassport.eu/api/v1/passports/bulk-publish \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"passport_ids": [96, 97, 98]}'{
"published": 2,
"failed": 1,
"published_ids": [96, 97],
"errors": [
{ "id": 98, "error": "Compliance below the publishing threshold." }
]
}/passports/{id}/successor
requiere passports:write Para un producto preparado para su reutilización, reconvertido o refabricado, el Reglamento de Pilas y Baterías (artículo 77, apartado 7) exige un nuevo pasaporte vinculado al original. Esto crea un nuevo registro de producto y un pasaporte en borrador rellenado a partir del publicado y vinculado a él. El original sigue publicado y ambos pasaportes muestran el vínculo. Publique el nuevo con POST /passports/{id}/publish.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| stage | string | obligatorio | prepared_for_reuse, repurposed o remanufactured. |
curl -X POST https://myproductpassport.eu/api/v1/passports/96/successor \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{ "stage": "repurposed" }'{
"data": {
"id": 131, "status": "draft", "version": 1,
"lineage": {
"stage": "repurposed",
"original": { "id": 96, "url": "https://myproductpassport.co.uk/p/..." },
"originals": [{ "passport_id": 96, "product_id": 40, "stage": "repurposed", "status": "published", "url": "https://myproductpassport.co.uk/p/..." }],
"successors": []
}
}
}/passports/{id}/fields
requiere passports:read Devuelve las claves de campo que pide la plantilla del sector del pasaporte (obligatorias y opcionales), los valores actuales y qué claves obligatorias faltan todavía. Úselo para construir el cuerpo de PUT /passports/{id}/fields.
curl https://myproductpassport.eu/api/v1/passports/96/fields \
-H "Authorization: Bearer pk_your_key"{
"passport_id": 96,
"sector": "batteries",
"compliance_percentage": 84,
"required": ["battery_category", "carbon_footprint", "..."],
"optional": ["energy_round_trip_efficiency", "..."],
"missing_required": ["carbon_footprint_class", "recycled_content"],
"values": { "battery_category": "Industrial", "...": "..." }
}/passports/{id}/fields
requiere passports:write Escribe cualquier conjunto de valores de campo en un pasaporte en borrador o publicado: el conjunto completo del anexo XIII para una batería, los campos de una plantilla de sector o sus propias claves. Envíe solo las claves que quiera cambiar; un valor nulo o vacío elimina ese campo. Un pasaporte publicado se actualiza en el mismo sitio, su dirección y su código QR no cambian y sus traducciones automáticas se regeneran. El cumplimiento se vuelve a puntuar. Esta llamada no publica un borrador; use POST /passports/{id}/publish.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| fields | object | obligatorio | Mapa de clave de campo a valor. Las claves son letras minúsculas, dígitos y guiones bajos; los valores, de hasta 5.000 caracteres. Hasta 200 claves por llamada. |
curl -X PUT https://myproductpassport.eu/api/v1/passports/96/fields \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"carbon_footprint": "61.2 kg CO2e/kWh",
"carbon_footprint_class": "C",
"recycled_content": "Cobalt 16%, lithium 6%, nickel 6%, lead 0%"
}
}'{
"message": "3 field(s) changed, 0 removed.",
"changed": ["carbon_footprint", "carbon_footprint_class", "recycled_content"],
"removed": [],
"passport": { "id": 96, "status": "published", "compliance_percentage": 92 }
}/passports/{id}/state-of-health
requiere passports:write Envía los datos propios de esta batería (anexo XIII, punto 4, del Reglamento (UE) 2023/1542) a un pasaporte publicado, para sistemas BMS y de flotas. Envíe cualquier subconjunto de los campos siguientes; el cumplimiento se vuelve a comprobar tras la actualización. Estos valores solo se muestran a los visitantes aprobados por el titular del pasaporte (artículo 77, apartado 2), nunca en la página pública. capacity_fade, power_capability e internal_resistance se guardan como lecturas actuales de esta batería (current_*), separadas de los valores originales del modelo.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| state_of_health | string | p. ej., «97 % a los 412 ciclos». | |
| state_of_certified_energy | string | Energía certificada restante (baterías de vehículos eléctricos). | |
| battery_status | string | original, repurposed, re-used, remanufactured o waste. | |
| capacity_fade | string | Pérdida de capacidad hasta la fecha. Se guarda como current_capacity_fade. | |
| power_capability | string | Capacidad de potencia actual. Se guarda como current_power_capability. | |
| internal_resistance | string | Resistencia interna medida. Se guarda como current_internal_resistance. | |
| use_data | string | Ciclos, incidentes negativos, temperatura y estado de carga, hasta 5000 caracteres. |
curl -X POST https://myproductpassport.eu/api/v1/passports/96/state-of-health \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{
"state_of_health": "97% at 412 cycles",
"capacity_fade": "3% from initial rated capacity"
}'{
"message": "2 field(s) updated.",
"updated_fields": ["state_of_health", "current_capacity_fade"],
"passport": { "id": 96, "status": "published", "compliance_percentage": 100 }
}/passports/{id}/units
requiere passports:write Cada batería necesita su propio pasaporte (Reglamento (UE) 2023/1542, artículo 77, apartado 1). Registre hasta 10 000 baterías de un modelo en una llamada, cada una con su número de serie (hasta 20 letras, dígitos, puntos, guiones o guiones bajos) y, opcionalmente, manufacturing_date, battery_status y sus datos del anexo XIII, punto 4. Los números de serie existentes se actualizan; los valores omitidos se conservan. Si el producto tiene GTIN, la dirección de cada batería es su GS1 Digital Link, /01/{gtin}/21/{serial}. Los datos del punto 4 solo los ven las personas que el titular autorice.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| units[].serial | string | obligatorio | El número de serie de la batería. |
| units[].manufacturing_date | string | Mes y año, p. ej. "2026-09". | |
| units[].battery_status | string | original o waste. Un cambio de estado necesita los valores medidos en él (anexo XIII, punto 4, letra a)); waste también necesita responsible_party_type (producer, pro o waste_operator), responsible_party_name y responsible_party_contact (artículo 77, apartado 7). recycled, con recycled_at y recycler_name, pone fin al pasaporte (artículo 77, apartado 8). Una batería reconvertida, reutilizada o refabricada recibe un nuevo pasaporte: POST /passports/{id}/units/{serial}/successor. | |
| units[].state_of_health | string | También state_of_certified_energy, current_capacity_fade, current_power_capability, current_internal_resistance, remaining_capacity_ah, power_fade, internal_resistance_increase, round_trip_efficiency, round_trip_efficiency_fade, expected_lifetime_cycles_remaining, self_discharge_rate, ohmic_resistance y use_data. |
curl -X POST https://myproductpassport.eu/api/v1/passports/96/units \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"units": [{"serial": "KES-00001", "manufacturing_date": "2026-09", "state_of_health": "100%"}]}'{ "created": 1, "updated": 0, "skipped": 0, "errors": [] }/passports/{id}/units/{serial}
requiere passports:write Para un sistema de gestión de baterías que envía los datos de una batería: cualquiera de battery_status, state_of_health, state_of_certified_energy, current_capacity_fade, current_power_capability, current_internal_resistance y use_data. Haga GET a la misma ruta para leerlos, o GET /passports/{id}/units para la lista (per_page hasta 500).
curl -X PATCH https://myproductpassport.eu/api/v1/passports/96/units/KES-00001 \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"state_of_health": "96% at 412 cycles"}'{
"data": { "serial": "KES-00001", "public_url": "https://myproductpassport.co.uk/01/05012345678900/21/KES-00001", "battery_status": "original", "data": { "state_of_health": "96% at 412 cycles" } }
}/passports/{id}/units/{serial}/snapshots
requiere passports:read El anexo XIII, punto 4, letra a), exige los valores de rendimiento y durabilidad cuando la batería se introduce en el mercado y cuando cambia su estado. Esas lecturas se conservan tal como eran, independientemente de lo que se envíe después; envíe record_snapshot: true con un PATCH para conservar también una lectura periódica.
curl https://myproductpassport.eu/api/v1/passports/96/units/KES-00001/snapshots \
-H "Authorization: Bearer pk_your_key"{
"data": [
{ "event": "placed_on_market", "status": "original", "values": { "state_of_health": "100%" }, "measured_at": "2026-09-26T09:00:00+00:00", "source": "api" },
{ "event": "status_change", "status": "waste", "values": { "remaining_capacity_ah": "71 Ah", "power_fade": "14%", "internal_resistance_increase": "22%", "expected_lifetime_cycles_remaining": "0" }, "measured_at": "2029-03-02T10:00:00+00:00", "source": "bms" }
]
}/passports/{id}/units/{serial}/successor
requiere passports:write Artículo 77, apartado 7: una batería que ha sido preparada para la reutilización, reconvertida o refabricada tiene un nuevo pasaporte vinculado a su original. Esto registra la batería de nuevo, con un nuevo número de serie e identificador, bajo un modelo de batería de segunda vida de su espacio de trabajo (creado a partir de este modelo si aún no existe), vincula ambas y conserva los valores medidos en el cambio. La batería original conserva su pasaporte. Complete y publique el modelo de segunda vida con POST /passports/{id}/publish.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| stage | string | obligatorio | prepared_for_reuse, repurposed o remanufactured. |
| values | object | obligatorio | Los valores medidos en el cambio: al menos uno de remaining_capacity_ah o current_capacity_fade, de current_power_capability o power_fade, de current_internal_resistance o internal_resistance_increase, y expected_lifetime_cycles_remaining (anexo IV, parte A). |
| serial | string | El nuevo número de serie. Por defecto: el número de serie original más -RU, -RP o -RM. | |
| measured_at | string | Cuándo se midieron los valores. | |
| member_state | string | Código de dos letras del Estado miembro en el que se evaluó el estado de salud (artículo 73, apartado 1, letra a)). | |
| target_passport_id | integer | Un modelo de segunda vida existente de este modelo de batería en el que registrarla. |
curl -X POST https://myproductpassport.eu/api/v1/passports/96/units/KES-00001/successor \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"stage": "repurposed", "values": {"remaining_capacity_ah": "82 Ah", "power_fade": "9%", "internal_resistance_increase": "15%", "expected_lifetime_cycles_remaining": "2000"}}'{
"data": {
"serial": "KES-00001-RP", "battery_status": "repurposed", "passport_id": 131,
"lineage": { "originals": [{ "serial": "KES-00001", "passport_id": 96, "stage": "repurposed" }], "successors": [] }
}
}/passports/{id}/registry
requiere passports:write Guarda en un pasaporte el envío al registro de DPP de la UE y su resultado: estado, ID de correlación, el identificador de registro que devuelve el registro y un enlace opcional a una copia de seguridad alojada por un proveedor de servicios DPP. El registro en sí se realiza en el registro de la Comisión (formulario web o carga de archivo); esto conserva el resultado junto al pasaporte. GET /passports/{id} devuelve el mismo bloque en registry.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| status | string | not_submitted, submitted, registered o failed. | |
| product_group | string | Grupo de productos del registro, por ejemplo batteries. | |
| granularity | string | modelo, lote o artículo. | |
| upi | string | Identificador único de producto como URL https. Por defecto, la URL del pasaporte público. | |
| correlation_id | string | Identificador de correlación asignado por el Registro al enviar. | |
| uri | string | Identificador de registro devuelto por el registro. | |
| backup_url | string | Enlace https a la copia de seguridad alojada por un proveedor de servicios DPP. | |
| submitted_at | date | Fecha de envío. | |
| registered_at | date | Fecha de registro. | |
| error | string | Descripción del error de un envío fallido. |
curl -X POST https://myproductpassport.eu/api/v1/passports/96/registry \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{
"status": "registered",
"correlation_id": "7f3a2c1e-0b4d-4f8e-9a6b-2d1c3e4f5a6b",
"uri": "urn:eu:dpp:reg:00000001",
"registered_at": "2027-02-18"
}'{
"message": "Registry details updated.",
"passport": {
"id": 96,
"registry": {
"status": "registered",
"upi": "https://myproductpassport.co.uk/p/552fbb4e-5d9a-41da-9050-cc9005d8b66b",
"correlation_id": "7f3a2c1e-0b4d-4f8e-9a6b-2d1c3e4f5a6b",
"uri": "urn:eu:dpp:reg:00000001",
"registered_at": "2027-02-18T00:00:00+00:00"
}
}
}/passports/{id}/qr
requiere passports:read El código QR del pasaporte como archivo: svg (por defecto), png (con marca, listo para imprimir) o pdf (hoja de etiquetas).
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| format | string | svg | png | pdf |
curl "https://myproductpassport.eu/api/v1/passports/96/qr?format=png" \
-H "Authorization: Bearer pk_your_key" -o passport-96.png09 / EndpointsConformidad
/passports/{passportId}/compliance
requiere passports:read Ejecuta una comprobación de cumplimiento en vivo de un pasaporte frente a los campos obligatorios de su sector e indica exactamente qué falta.
curl https://myproductpassport.eu/api/v1/passports/96/compliance \
-H "Authorization: Bearer pk_your_key"{
"data": {
"passport_id": 96,
"product_name": "Alpine Merino Crew Sweater",
"status": "compliant",
"percentage": 100,
"completed_fields": 12,
"total_fields": 12,
"missing_fields": []
}
}10 / EndpointsSectores
/sectors
Los sectores en los que se puede clasificar un producto: los sectores del sistema de la plataforma más los que haya definido su espacio de trabajo. Use el id al crear productos y las claves de campo al escribir campos del pasaporte.
curl https://myproductpassport.eu/api/v1/sectors \
-H "Authorization: Bearer pk_your_key"{
"data": [
{
"id": 4,
"slug": "batteries",
"name": "Batteries",
"system": true,
"regulations_finalised": true,
"deadline": "2027-02-18",
"deadline_label": "18 Feb 2027",
"required_fields": ["battery_category", "battery_weight", "..."],
"optional_fields": ["energy_round_trip_efficiency", "..."]
}
]
}11 / EndpointsDocumentos
/products/{productId}/documents
requiere products:read Declaraciones de conformidad, informes de ensayo y certificados adjuntos al producto. Los documentos públicos se enlazan desde cada pasaporte publicado del producto.
curl https://myproductpassport.eu/api/v1/products/512/documents \
-H "Authorization: Bearer pk_your_key"{
"data": [
{
"id": 31,
"product_id": 512,
"filename": "declaration-of-conformity.pdf",
"mime_type": "application/pdf",
"file_size": 184322,
"is_public": true,
"processing_status": "completed",
"public_url": "https://myproductpassport.co.uk/p/3f0c.../document/31",
"created_at": "2026-09-22T10:12:00+00:00"
}
]
}/products/{productId}/documents
requiere products:write Carga multipart. PDF, Word, Excel, CSV, texto, PNG y JPEG de hasta 10 MB, como máximo 20 por producto. El texto se extrae en segundo plano.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| file | file | obligatorio | El documento. |
| is_public | boolean | Mostrarlo en el pasaporte público (por defecto false). |
curl -X POST https://myproductpassport.eu/api/v1/products/512/documents \
-H "Authorization: Bearer pk_your_key" \
-F "[email protected]" \
-F "is_public=1"/products/{productId}/documents/{id}
requiere products:write Indica si el documento se enlaza desde el pasaporte público.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| is_public | boolean | obligatorio |
curl -X PATCH https://myproductpassport.eu/api/v1/products/512/documents/31 \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"is_public": false}'/products/{productId}/documents/{id}
requiere products:write Elimina el archivo y su vínculo con el pasaporte.
curl -X DELETE https://myproductpassport.eu/api/v1/products/512/documents/31 \
-H "Authorization: Bearer pk_your_key"{ "message": "Document deleted." }12 / EndpointsCadena de suministro
/products/{productId}/supply-chain
requiere products:read Los pasos que se muestran en el pasaporte del producto, en orden.
curl https://myproductpassport.eu/api/v1/products/512/supply-chain \
-H "Authorization: Bearer pk_your_key"/products/{productId}/supply-chain
requiere products:write Sustituye todos los pasos por la lista que envíe, en el orden enviado. Envíe una lista vacía para borrarla. Tipos de paso: raw_material, processing, manufacturing, assembly, packaging, distribution.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| steps | array | obligatorio | Hasta 50 pasos. |
| steps[].step_type | string | obligatorio | |
| steps[].supplier_name | string | obligatorio | |
| steps[].supplier_location | string | ||
| steps[].supplier_country | string | ISO 3166-1 alfa-2. | |
| steps[].lat / lng | number | ||
| steps[].description | string | ||
| steps[].certifications | array | ||
| steps[].date | date |
curl -X PUT https://myproductpassport.eu/api/v1/products/512/supply-chain \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"steps": [{"step_type": "raw_material", "supplier_name": "Merino Growers Co-op", "supplier_country": "NZ", "certifications": ["RWS"]}, {"step_type": "manufacturing", "supplier_name": "Northloom Mill", "supplier_location": "Biella", "supplier_country": "IT"}]}'13 / EndpointsTraducciones
/passports/{id}/translations
requiere passports:read Cada valor de campo traducido por idioma, con su origen: auto (automático, generado al publicar) o manual.
curl https://myproductpassport.eu/api/v1/passports/96/translations \
-H "Authorization: Bearer pk_your_key"{
"data": {
"passport_id": 96,
"available_locales": ["bg", "cs", "da", "de", "..."],
"translations": {
"de": {"care_instructions": {"value": "Kalt waschen", "source": "manual"}}
}
}
}/passports/{id}/translations/{locale}
requiere passports:write Define las traducciones de un idioma, por clave de campo. Una traducción manual nunca se sobrescribe automáticamente. Envíe una cadena vacía para eliminar una.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| fields | object | obligatorio | field_key: valor traducido |
curl -X PUT https://myproductpassport.eu/api/v1/passports/96/translations/de \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"fields": {"care_instructions": "Kalt waschen, nicht bleichen"}}'{ "message": "1 translation(s) written, 0 removed.", "locale": "de", "written": 1, "removed": 0 }14 / EndpointsIntegridad y exportaciones
/passports/{id}/integrity
requiere passports:read Cada estado publicado del pasaporte como un registro encadenado por hash y firmado con Ed25519: huella digital (SHA-256), valor de la cadena y firma. Las claves públicas están en /.well-known/mpp-integrity-keys.json, de modo que cualquiera puede verificar la cadena.
curl https://myproductpassport.eu/api/v1/passports/96/integrity \
-H "Authorization: Bearer pk_your_key"{ "data": { "state": "intact", "hash_algorithm": "SHA-256", "signature_algorithm": "Ed25519", "records": [ { "sequence": 1, "event": "published", "content_hash": "8f3a...", "chain_hash": "c21e...", "signature": "MEUC...", "key_id": "3fa9c21e0b7d4a11" } ], "problems": [] } }/passports/{id}/integrity/{sequence}
requiere passports:read El registro completo tal como se firmó, instantánea incluida: lo que decía el pasaporte en ese momento, hasta el hash de cada archivo adjunto.
curl https://myproductpassport.eu/api/v1/passports/96/integrity/1 \
-H "Authorization: Bearer pk_your_key"/passports/{id}/epcis
requiere passports:read El pasaporte como documento JSON-LD de GS1 EPCIS 2.0: el artículo puesto en servicio, cada etapa de la cadena de suministro como una observación, las baterías individuales y un pasaporte de segunda vida como una transformación. Los identificadores son URI de GS1 Digital Link cuando el producto tiene un GTIN.
curl https://myproductpassport.eu/api/v1/passports/96/epcis \
-H "Authorization: Bearer pk_your_key"15 / EndpointsSolicitudes a proveedores
/passports/{id}/supplier-requests
requiere passports:write Envía por correo electrónico a un proveedor un enlace privado para rellenar los campos que usted elija, en su idioma. Nada llega al pasaporte hasta que alguien de su espacio de trabajo lo aprueba.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| supplier_name | string | obligatorio | |
| supplier_email | string | obligatorio | |
| field_keys | array | obligatorio | Claves de campo de la plantilla del pasaporte. |
| locale | string | Idioma del correo electrónico y del formulario, p. ej., de. | |
| due_at | date | Fecha límite de respuesta; 14 días si se omite. | |
| message | string |
curl -X POST https://myproductpassport.eu/api/v1/passports/96/supplier-requests \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"supplier_name": "Mei Chen", "supplier_email": "[email protected]", "field_keys": ["recycled_content_cobalt", "carbon_footprint"], "locale": "de"}'/passports/{id}/supplier-requests
requiere passports:read Todas las solicitudes del pasaporte con su estado.
curl https://myproductpassport.eu/api/v1/passports/96/supplier-requests \
-H "Authorization: Bearer pk_your_key"/supplier-requests/{id}
requiere passports:read Una solicitud con las respuestas del proveedor, la nota y los nombres de los archivos adjuntos.
curl https://myproductpassport.eu/api/v1/supplier-requests/12 \
-H "Authorization: Bearer pk_your_key"16 / EndpointsPosventa
/passports/{id}/items
requiere items:write Dé a los artículos de un producto (cualquier sector excepto baterías, que usan /units) su propio número de serie: cada uno recibe su propia dirección y código QR, un código de autenticidad oculto para su etiqueta, y su propietario puede registrarlo. Envíe hasta 10.000 artículos o un rango. Con un GTIN, la dirección es el GS1 Digital Link /01/{gtin}/21/{serial}.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| items[].serial | string | obligatorio | Hasta 20 letras, cifras, puntos, guiones o guiones bajos. |
| items[].batch | string | Lote, hasta 20 caracteres. | |
| items[].manufactured_on | string | Fecha de fabricación, AAAA-MM-DD. | |
| range | object | En lugar de items: prefix, start, count, digits y batch, por ejemplo SN-00001 a SN-00500. |
curl -X POST https://myproductpassport.eu/api/v1/passports/96/items \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"range": {"prefix": "SN-", "start": 1, "count": 500, "digits": 5, "batch": "B2026-10"}}'{ "created": 500, "updated": 0, "skipped": 0, "over_limit": 0, "errors": [] }/passports/{id}/items/{serial}
requiere items:read Un artículo con su dirección, estado, si está registrado y hasta cuándo dura su garantía, sus comprobaciones de autenticidad y su historial. Una clave con items:write obtiene también su código oculto, para imprimir. GET /passports/{id}/items los enumera (filtros status y batch, per_page hasta 500).
curl https://myproductpassport.eu/api/v1/passports/96/items/SN-00001 \
-H "Authorization: Bearer pk_your_key"{
"data": { "serial": "SN-00001", "status": "active", "url": "https://myproductpassport.co.uk/01/05012345678900/21/SN-00001", "registered": true, "warranty_ends_on": "2028-10-02", "events": [ { "type": "registered", "country": "IE", "at": "2026-10-03T09:12:00+00:00" } ] }
}/passports/{id}/items/{serial}
requiere items:write Ponga status en stolen o recalled y su página avisará a quien lo escanee, con su status_note; un artículo robado no se puede registrar. retired desactiva su página. También se pueden cambiar batch y manufactured_on.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| status | string | active, stolen, recalled o retired. | |
| status_note | string | Se muestra en la página del artículo, hasta 500 caracteres. |
curl -X PATCH https://myproductpassport.eu/api/v1/passports/96/items/SN-00001 \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"status": "stolen", "status_note": "Reported stolen on 2 October 2026."}'/owner-registrations
requiere aftersales:read Personas que registraron sus productos: nombre, correo, país, fecha de compra, tienda, fechas de garantía y si aceptaron novedades y ofertas (marketing_consent=1 solo enumera esos). Registros activos por defecto; status=pending, transferred o ended para los demás; since= para cambios posteriores a una fecha.
curl "https://myproductpassport.eu/api/v1/owner-registrations?marketing_consent=1&since=2026-10-01" \
-H "Authorization: Bearer pk_your_key"/service-requests
requiere aftersales:read Reparaciones, reclamaciones de garantía, devoluciones, recambios y preguntas enviadas desde sus pasaportes, las más recientes primero, con filtros status y type. GET /service-requests/{reference} añade la conversación.
curl "https://myproductpassport.eu/api/v1/service-requests?status=new" \
-H "Authorization: Bearer pk_your_key"/service-requests/{reference}/replies
requiere aftersales:write Su respuesta se envía al cliente por correo con un enlace a la página de su solicitud, en su idioma. internal: true añade una nota que solo ve su equipo. PATCH /service-requests/{reference} con un status la hace avanzar (se avisa al cliente cuando está en curso, resuelta o cerrada).
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| body | string | obligatorio | La respuesta, hasta 5.000 caracteres. |
| internal | boolean | Una nota para su equipo en lugar de una respuesta. | |
| status | string | new, in_progress, waiting, resolved o closed. |
curl -X POST https://myproductpassport.eu/api/v1/service-requests/SR-7K3F9Q/replies \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"body": "A new lid is on its way today.", "status": "waiting"}'17 / EndpointsEdiciones masivas e imágenes
/products/bulk-fields
requiere products:write Establece un dato del producto o un campo del pasaporte en hasta 5.000 productos. mode es set, fill (solo donde esté vacío) o clear. En la solicitud se actualizan hasta 100 productos; los conjuntos más grandes se ponen en cola (202).
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| product_ids | array | obligatorio | |
| target | string | obligatorio | product | field |
| key | string | obligatorio | |
| value | string | ||
| mode | string | set | fill | clear |
curl -X PATCH https://myproductpassport.eu/api/v1/products/bulk-fields \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"product_ids": [12, 13, 14], "target": "field", "key": "warranty_period", "value": "10 years", "mode": "fill"}'{ "data": { "changed": 2, "skipped": 1, "errors": [] } }/products/{id}/images
requiere products:write Carga multipart de un archivo JPG, PNG o WebP (hasta 15MB, 8 por producto). La primera imagen es la portada del pasaporte público.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| image | file | obligatorio | |
| alt | string | Descripción de la imagen. |
curl -X POST https://myproductpassport.eu/api/v1/products/12/images \
-H "Authorization: Bearer pk_your_key" \
-F [email protected] -F alt="Front of the battery"/products/{id}/images/order
requiere products:write Pase image_ids en el orden que desee; la primera será la portada.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| image_ids | array | obligatorio |
curl -X PUT https://myproductpassport.eu/api/v1/products/12/images/order \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"image_ids": [31, 30]}'/products/{id}/images/{imageId}
requiere products:write Elimina la imagen y su archivo.
curl -X DELETE https://myproductpassport.eu/api/v1/products/12/images/31 \
-H "Authorization: Bearer pk_your_key"18 / EndpointsWebhooks
/webhooks
requiere webhooks:manage Los endpoints registrados para su espacio de trabajo. Los secretos no se incluyen aquí; obtenga un endpoint concreto para ver su secreto.
curl https://myproductpassport.eu/api/v1/webhooks \
-H "Authorization: Bearer pk_your_key"/webhooks
requiere webhooks:manage Registra una URL HTTPS pública para uno o más eventos. La respuesta incluye el secreto de firma. Se rechazan los hosts privados o internos.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| url | string | obligatorio | |
| events | array | obligatorio | Cualquiera de los eventos indicados abajo. |
curl -X POST https://myproductpassport.eu/api/v1/webhooks \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://erp.acme.example/mpp", "events": ["passport.published", "product.updated"]}'{
"data": {
"id": 3,
"url": "https://erp.acme.example/mpp",
"events": ["passport.published", "product.updated"],
"is_active": true,
"failure_count": 0,
"secret": "9f1c...64 hex characters...",
"created_at": "2026-09-22T10:12:00+00:00"
}
}/webhooks/{id}
requiere webhooks:manage curl https://myproductpassport.eu/api/v1/webhooks/3 \
-H "Authorization: Bearer pk_your_key"/webhooks/{id}
requiere webhooks:manage Cambie la URL o los eventos, o páuselo y reanúdelo. Al reanudarlo se pone a cero el contador de fallos; un endpoint se pausa automáticamente tras 10 entregas fallidas consecutivas.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| url | string | ||
| events | array | ||
| is_active | boolean |
curl -X PUT https://myproductpassport.eu/api/v1/webhooks/3 \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d '{"is_active": true}'/webhooks/{id}/test
requiere webhooks:manage Pone en cola una entrega webhook.test para que pueda comprobar su receptor y su código de firma.
curl -X POST https://myproductpassport.eu/api/v1/webhooks/3/test \
-H "Authorization: Bearer pk_your_key"{ "message": "Test delivery queued." }/webhooks/{id}/deliveries
requiere webhooks:manage Entregas recientes, de la más reciente a la más antigua, con el estado HTTP que devolvió su endpoint y los primeros 500 caracteres del cuerpo.
| Parámetro | Tipo | Descripción | |
|---|---|---|---|
| per_page | integer | Hasta 100. |
curl https://myproductpassport.eu/api/v1/webhooks/3/deliveries \
-H "Authorization: Bearer pk_your_key"/webhooks/{id}
requiere webhooks:manage curl -X DELETE https://myproductpassport.eu/api/v1/webhooks/3 \
-H "Authorization: Bearer pk_your_key"{ "message": "Webhook endpoint deleted." }19 / EventosWebhooks
En lugar de consultar periódicamente, registre un endpoint de webhook en la aplicación (página Webhooks, disponible a partir del plan Starter) y MyProductPassport enviará JSON por POST a su URL cuando ocurran los eventos:
| Evento | Se activa cuando |
|---|---|
| product.created | Se crea un producto (aplicación, API o importación CSV) |
| product.updated | Se actualiza un producto |
| product.deleted | Se elimina un producto |
| passport.created | Se genera un pasaporte |
| passport.published | Un pasaporte se publica |
| passport.archived | Un pasaporte se archiva |
| supplier_request.submitted | Un proveedor envía la información que usted ha solicitado |
| owner.registered | Un propietario confirma su registro |
| owner.transferred | Un artículo pasa a un nuevo propietario registrado |
| service_request.created | Un cliente envía una solicitud de servicio desde un pasaporte |
| service_request.updated | Una solicitud de servicio recibe una respuesta o un nuevo estado |
| item.status_changed | Un artículo se marca como robado, retirado del mercado o dado de baja, o se le quita la marca |
| item.verification_failed | Falla una lectura segura, se acumulan códigos erróneos o un número de serie aparece en demasiados lugares |
| webhook.test | Envía una entrega de prueba desde la aplicación |
Cada entrega es un sobre JSON: un identificador de entrega (el mismo identificador se reenvía en los reintentos, para que pueda eliminar duplicados), el evento, el número de intento, una marca de tiempo y los datos del evento. Los eventos de pasaporte incluyen el uuid y la URL pública del pasaporte, así que rara vez necesitará una segunda solicitud:
{
"id": 8123,
"event": "passport.published",
"attempt": 1,
"created_at": "2026-09-22T10:12:00+00:00",
"data": {
"passport_id": 96,
"uuid": "3f0c8f1e-...",
"version": 2,
"status": "published",
"public_url": "https://myproductpassport.co.uk/p/3f0c8f1e-...",
"product_id": 512,
"product": {"id": 512, "name": "Alpine Merino Crew Sweater", "sku": "NL-AMC-001", "gtin": "5012345678900"}
}
}Las cabeceras incluyen el nombre del evento, el id de entrega, una marca de tiempo Unix y una firma HMAC del cuerpo sin procesar, para que pueda verificar que procede de nosotros y rechazar repeticiones:
Content-Type: application/json
User-Agent: MyProductPassport-Webhooks/1.0
X-MPP-Event: passport.published
X-MPP-Delivery: 8123
X-MPP-Timestamp: 1790084320
X-MPP-Signature: sha256=<hex hmac of the raw body, keyed with your endpoint secret>Responda con cualquier código 2xx en 10 segundos. Cualquier otra respuesta se reintenta cinco veces durante unos 90 minutos (30 s, 1 min, 5 min, 15 min, 1 h); tras 10 fallos consecutivos, el endpoint se pausa hasta que lo vuelva a activar.
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $endpointSecret);
abort_unless(hash_equals($expected, $request->header('X-MPP-Signature')), 401);