Referință API
Totul în MyProductPassport este disponibil printr-un API REST autentificat cu cheie: creați produse, generați și publicați pașapoarte digitale ale produselor, trimiteți date live despre baterii și verificați conformitatea, direct din ERP, PIM sau fluxul de build.
01 / Primii pașiAutentificare
Fiecare cerere este autentificată cu o cheie API transmisă ca token Bearer. Cheile se creează în aplicație la Chei API, sunt afișate o singură dată și stocate sub formă de hash; fiecare cheie are propriul set de permisiuni, o listă opțională de IP-uri permise și o dată de expirare opțională. Cheile pot fi rotite fără întreruperi.
Authorization: Bearer pk_your_api_keyPermisiunile sunt acordate per cheie, astfel încât o integrare primește doar ce îi trebuie:
| Permisiune | Acces acordat |
|---|---|
| products:read | Citire produse |
| products:write | Creare, actualizare și ștergere produse |
| passports:read | Citire pașapoarte |
| passports:write | Generați pașapoarte |
| passports:publish | Publicare și arhivare pașapoarte |
| webhooks:manage | Creare, testare și eliminare endpointuri 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 / Primii pașiLimite de rată
Limitele sunt per cheie, pe minut, și depind de plan:
| Plan | Cereri / minut |
|---|---|
| Gratuit | 30 |
| Micro | 60 |
| Etichetă electronică | 60 |
| Starter | 120 |
| Professional | 300 |
| Business | 600 |
| Battery | 600 |
Fiecare răspuns conține antetele X-RateLimit-Limit și X-RateLimit-Remaining. Depășirea limitei returnează 429:
{ "error": "Rate limit exceeded.", "limit": 300, "retry_after": 60 }03 / Primii pașiErori
Erorile sunt JSON cu un cod de stare convențional. Cele mai frecvente:
| Stare | Semnificație | Corp exemplu |
|---|---|---|
| 401 | Cheie lipsă, nevalidă, revocată sau expirată | {"error": "Invalid or revoked API key."} |
| 403 | Cheii îi lipsește o permisiune, IP-ul nu este pe lista permisă sau s-a atins limita planului | {"message": "API key does not have 'products:write' permission."} |
| 404 | Resursa nu există în spațiul dvs. de lucru | {"message": "Not found."} |
| 422 | Validarea a eșuat | {"message": "…", "errors": {"gtin": ["…"]}} |
| 429 | Limită de rată depășită | {"error": "Rate limit exceeded."} |
04 / Primii pașiPaginare
Endpointurile de listare returnează 25 de elemente pe pagină cu obiectele standard links și meta. Transmiteți ?page=2 pentru a parcurge colecția.
05 / Primii pașiConector pentru asistent IA (MCP)
Conectați Claude, Cursor sau orice asistent care folosește Model Context Protocol și cereți-i simplu să creeze produse, să completeze pașapoarte cu ce îi spuneți și să verifice ce mai lipsește. Folosește o cheie API cu permisiunile și limita de cereri ale acesteia. Poate crea ciorne și completa câmpuri; nu publică, nu arhivează și nu șterge niciodată nimic: acestea rămân la dvs. în aplicație.
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"]
}
}
}Instrumentele oferite:
| Instrument | Ce face |
|---|---|
| list_products | Produsele spațiului de lucru, cele mai noi primele, câte 25 pe pagină, cu sectorul și ultimul pașaport. |
| get_product | Un produs cu detaliile, sectorul, secțiunile de reglementare și ultimul pașaport. |
| list_sectors | Șabloanele de sector pe care le poate folosi un produs (textile, electronice, baterii, vin și altele), cu ID-urile lor. Sectorul unui produs decide ce câmpuri ale pașaportului sunt obligatorii. |
| create_product | Adaugă un produs în spațiul de lucru. Folosiți un sector_id din list_sectors. compliance_sections adaugă secțiuni de reglementare pașaportului: gpsr, epr, france, chemicals, eudr. |
| list_passports | Pașapoartele spațiului de lucru, cele mai noi primele, câte 25 pe pagină, cu starea (draft, published, archived), procentul de completitudine și adresa publică. |
| get_passport | Un pașaport: stare, versiune, procent de completitudine, adresă publică și linkuri către codul QR. |
| create_passport | Creează o ciornă de pașaport pentru un produs. Nu se publică: o publică o persoană în aplicație. |
| get_passport_fields | Ce cere un pașaport: cheile câmpurilor obligatorii și opționale, ce înseamnă fiecare (etichetă, descriere, exemplu), valorile existente și câmpurile obligatorii lipsă. |
| update_passport_fields | Scrie valori de câmpuri într-un pașaport ciornă sau publicat (unul publicat se actualizează pe loc: aceeași adresă, același cod QR). Chei din get_passport_fields; un text gol elimină o valoare. Scrieți doar fapte indicate de utilizator sau de documentele sale. |
| get_compliance | Completitudinea unui pașaport: procent, stare și câmpurile obligatorii care încă lipsesc. |
06 / EndpointuriCont
/me
Returnează contul autentificat, nivelul abonamentului și cât din limita de produse este folosit. Util pentru verificarea conexiunii.
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 / EndpointuriProduse
/products
necesită products:read Listează produsele din spațiul de lucru, cele mai noi primele, 25 pe pagină. Fiecare produs include sectorul său și rezumatul celui mai recent pașaport.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| page | integer | Numărul paginii. |
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
necesită products:write Creează un produs. Returnează 403 dacă limita de produse a planului este epuizată.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| name | string | obligatoriu | Numele produsului, până la 255 de caractere. |
| sku | string | SKU-ul dvs. intern, până la 100 de caractere. | |
| gtin | string | GTIN-8, 12, 13 sau 14 (doar cifre). | |
| brand | string | Marca afișată pe pașaportul public. | |
| description | string | Până la 2.000 de caractere. | |
| category | string | Categorie text liber. Implicit "general". | |
| sector_id | integer | Un ID de sector, care selectează șablonul de câmpuri al pașaportului. | |
| country_of_origin | string | Codul țării, de ex. "PT". | |
| weight | number | Greutate netă. | |
| weight_unit | string | Unul dintre kg, g, lb, oz. Implicit kg. | |
| materials | array | Obiecte {name, percentage 0-100}. | |
| has_packaging | boolean | Adaugă la pașaport câmpurile șablonului de ambalaj (chei care încep cu pkg_), sub același cod 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
necesită products:write Creează până la 100 de produse într-un singur apel. Întregul lot este refuzat cu 403 dacă ar depăși limita de produse rămasă. Pentru cataloage cu mii de produse, apelați acest endpoint în buclă sau folosiți importul CSV din aplicație.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| products | array | obligatoriu | Între 1 și 100 de obiecte produs cu aceleași câmpuri ca la „Creați un produs” (fără materiale). |
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}
necesită products:read Returnează un produs cu sectorul său și rezumatul celui mai recent pașaport. 404 dacă id-ul nu este în spațiul dvs. de lucru.
curl https://myproductpassport.eu/api/v1/products/512 \
-H "Authorization: Bearer pk_your_key"/products/{id}
necesită products:write Actualizează parțial un produs. Trimiteți doar câmpurile pe care doriți să le schimbați; lista câmpurilor este aceeași ca la Creați un produs.
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}
necesită products:write Șterge un produs în mod recuperabil. Pașapoartele publicate ale produsului continuă să funcționeze, astfel încât codurile QR tipărite nu rămân niciodată fără pagină.
curl -X DELETE https://myproductpassport.eu/api/v1/products/512 \
-H "Authorization: Bearer pk_your_key"{ "message": "Product deleted." }08 / EndpointuriPașapoarte
/passports
necesită passports:read Listează pașapoartele, cele mai noi primele, 25 pe pagină, cu rezumatul produsului și toate câmpurile pașaportului.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| page | integer | Numărul paginii. |
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
necesită passports:write Generează o ciornă de pașaport pentru un produs, precompletând câmpurile din datele produsului și șablonul sectorului. Returnează ciorna cu scorul de conformitate. Un produs care are deja un pașaport activ returnează 409 cu acel pașaport: corectați-l cu PUT /passports/{id}/fields, care îi păstrează adresa și codul QR.
curl -X POST https://myproductpassport.eu/api/v1/products/512/passports \
-H "Authorization: Bearer pk_your_key"/passports/{id}
necesită passports:read Returnează un pașaport cu produsul, câmpurile, URL-ul public și GS1 Digital Link.
curl https://myproductpassport.eu/api/v1/passports/96 \
-H "Authorization: Bearer pk_your_key"/passports/{id}/publish
necesită passports:publish Publică o ciornă de pașaport, activând pagina publică și codul QR. Doar ciornele pot fi publicate; orice altceva returnează 404.
curl -X POST https://myproductpassport.eu/api/v1/passports/96/publish \
-H "Authorization: Bearer pk_your_key"/passports/{id}/archive
necesită passports:publish Arhivează un pașaport și îi scoate pagina publică din circulație.
curl -X POST https://myproductpassport.eu/api/v1/passports/96/archive \
-H "Authorization: Bearer pk_your_key"/passports/bulk-publish
necesită passports:publish Publică până la 50 de ciorne de pașaport într-un apel și raportează rezultatul pentru fiecare, astfel încât un eșec nu oprește niciodată lotul.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| passport_ids | array | obligatoriu | Între 1 și 50 de ID-uri de pașaport. |
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
necesită passports:write Pentru un produs pregătit pentru reutilizare, reutilizat în alt scop sau refabricat, Regulamentul privind bateriile (articolul 77 alineatul (7)) impune un pașaport nou legat de cel original. Acest lucru creează o nouă înregistrare de produs și o ciornă de pașaport precompletată din cel publicat, legată de acesta. Originalul rămâne activ, iar ambele pașapoarte afișează legătura. Publicați-l pe cel nou cu POST /passports/{id}/publish.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| stage | string | obligatoriu | prepared_for_reuse, repurposed sau 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
necesită passports:read Returnează cheile de câmp cerute de șablonul sectorului pașaportului (obligatorii și opționale), valorile curente și cheile obligatorii care încă lipsesc. Folosiți-l pentru a construi conținutul pentru 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
necesită passports:write Scrie orice set de valori ale câmpurilor într-un pașaport ciornă sau publicat: setul complet din anexa XIII pentru o baterie, câmpurile unui șablon de sector sau propriile chei. Trimiteți doar cheile pe care vreți să le modificați; o valoare null sau goală elimină câmpul. Un pașaport publicat este actualizat pe loc, adresa și codul QR nu se schimbă, iar traducerile automate sunt regenerate. Conformitatea este reevaluată. O ciornă nu este publicată prin acest apel; folosiți POST /passports/{id}/publish.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| fields | object | obligatoriu | Mapare de la cheia câmpului la valoare. Cheile sunt litere mici, cifre și liniuțe de subliniere; valori de până la 5.000 de caractere. Până la 200 de chei per apel. |
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
necesită passports:write Trimite datele proprii ale acestei baterii (punctul 4 din anexa XIII la Regulamentul (UE) 2023/1542) către un pașaport publicat, pentru sisteme BMS și de flote. Trimiteți orice subset din câmpurile de mai jos; conformitatea este reverificată după actualizare. Aceste valori sunt afișate doar vizitatorilor aprobați de titularul pașaportului (articolul 77 alineatul (2)), niciodată pe pagina publică. capacity_fade, power_capability și internal_resistance sunt stocate ca valori curente ale acestei baterii (current_*), separat de valorile inițiale ale modelului.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| state_of_health | string | de ex. "97% la 412 cicluri". | |
| state_of_certified_energy | string | Energie certificată rămasă (baterii VE). | |
| battery_status | string | original, repurposed, re-used, remanufactured sau waste. | |
| capacity_fade | string | Pierderea de capacitate până în prezent. Stocată ca current_capacity_fade. | |
| power_capability | string | Capacitatea de putere actuală. Stocată ca current_power_capability. | |
| internal_resistance | string | Rezistența internă măsurată. Stocată ca current_internal_resistance. | |
| use_data | string | Cicluri, evenimente negative, temperatură și stare de încărcare, până la 5.000 de caractere. |
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
necesită passports:write Fiecare baterie are nevoie de propriul pașaport (Regulamentul (UE) 2023/1542, articolul 77 alineatul (1)). Înregistrați până la 10.000 de baterii ale unui model într-un singur apel, fiecare cu propriul număr de serie (până la 20 de litere, cifre, puncte, cratime sau liniuțe de subliniere) și, opțional, manufacturing_date, battery_status și datele sale de la punctul 4 din anexa XIII. Numerele de serie existente sunt actualizate; valorile omise se păstrează. Cu un GTIN pe produs, adresa fiecărei baterii este GS1 Digital Link-ul său, /01/{gtin}/21/{serial}. Datele de la punctul 4 sunt afișate doar vizitatorilor aprobați de proprietar.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| units[].serial | string | obligatoriu | Numărul de serie al bateriei. |
| units[].manufacturing_date | string | Luna și anul, de ex. "2026-09". | |
| units[].battery_status | string | original sau waste. O schimbare de stare necesită valorile măsurate la acel moment (anexa XIII punctul 4 litera (a)); waste necesită și responsible_party_type (producer, pro sau waste_operator), responsible_party_name și responsible_party_contact (articolul 77 alineatul (7)). recycled, împreună cu recycled_at și recycler_name, încheie pașaportul (articolul 77 alineatul (8)). O baterie reutilizată în alt scop, reutilizată sau refabricată primește un pașaport nou: POST /passports/{id}/units/{serial}/successor. | |
| units[].state_of_health | string | De asemenea: 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 și 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}
necesită passports:write Pentru un sistem de gestionare a bateriei care trimite datele unei baterii: oricare dintre battery_status, state_of_health, state_of_certified_energy, current_capacity_fade, current_power_capability, current_internal_resistance și use_data. Folosiți GET pe aceeași cale pentru a le citi sau GET /passports/{id}/units pentru listă (per_page până la 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
necesită passports:read Anexa XIII punctul 4 litera (a) impune valorile de performanță și durabilitate la introducerea bateriei pe piață și la schimbarea statutului acesteia. Aceste citiri se păstrează așa cum au fost, indiferent de ce se trimite ulterior; trimiteți record_snapshot: true cu un PATCH pentru a păstra și o citire periodică.
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
necesită passports:write Articolul 77 alineatul (7): o baterie care a fost pregătită pentru reutilizare, reutilizată în alt scop sau refabricată are un pașaport nou, legat de originalul său. Această operațiune înregistrează din nou bateria, cu un număr de serie și un identificator noi, în cadrul unui model de baterie pentru a doua viață din spațiul dvs. de lucru (creat din acest model dacă nu există încă unul), leagă cele două pașapoarte și păstrează valorile măsurate la schimbare. Bateria originală își păstrează pașaportul. Completați și publicați modelul pentru a doua viață cu POST /passports/{id}/publish.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| stage | string | obligatoriu | prepared_for_reuse, repurposed sau remanufactured. |
| values | object | obligatoriu | Valorile măsurate la schimbare: cel puțin una dintre remaining_capacity_ah sau current_capacity_fade, una dintre current_power_capability sau power_fade, una dintre current_internal_resistance sau internal_resistance_increase, precum și expected_lifetime_cycles_remaining (anexa IV partea A). |
| serial | string | Noul număr de serie. Implicit: numărul de serie original plus -RU, -RP sau -RM. | |
| measured_at | string | Momentul în care au fost măsurate valorile. | |
| member_state | string | Codul din două litere al statului membru în care a fost testată starea de sănătate (articolul 73 alineatul (1) litera (a)). | |
| target_passport_id | integer | Un model de baterie pentru a doua viață existent, derivat din acest model, în cadrul căruia să o înregistrați. |
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
necesită passports:write Stochează în pașaport depunerea în Registrul DPP al UE și rezultatul acesteia: starea, ID-ul de corelare, identificatorul de înregistrare returnat de Registru și un link opțional către o copie de rezervă găzduită de un furnizor de servicii DPP. Înregistrarea propriu-zisă se face în Registrul Comisiei (formular web sau încărcare de fișier); aceasta păstrează rezultatul împreună cu pașaportul. GET /passports/{id} returnează același bloc sub registry.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| status | string | not_submitted, submitted, registered sau failed. | |
| product_group | string | Grupa de produse din registru, de exemplu batteries. | |
| granularity | string | model, lot sau articol. | |
| upi | string | Identificator unic al produsului ca URL https. Implicit, URL-ul pașaportului public. | |
| correlation_id | string | ID de corelare atribuit de registru la depunere. | |
| uri | string | Identificatorul de înregistrare returnat de registru. | |
| backup_url | string | Link https către copia de rezervă găzduită de un furnizor de servicii DPP. | |
| submitted_at | date | Data depunerii. | |
| registered_at | date | Data înregistrării. | |
| error | string | Descrierea erorii pentru o depunere eșuată. |
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
necesită passports:read Codul QR al pașaportului ca fișier: svg (implicit), png (cu marca, gata de tipar) sau pdf (foaie de etichete).
| Parametru | Tip | Descriere | |
|---|---|---|---|
| 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 / EndpointuriConformitate
/passports/{passportId}/compliance
necesită passports:read Rulează o verificare de conformitate în timp real a unui pașaport față de câmpurile obligatorii ale sectorului său și raportează exact ce lipsește.
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 / EndpointuriSectoare
/sectors
Sectoarele în care poate fi încadrat un produs: sectoarele de sistem ale platformei plus cele definite de spațiul dvs. de lucru. Folosiți id-ul la crearea produselor și cheile câmpurilor la scrierea câmpurilor pașaportului.
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 / EndpointuriDocumente
/products/{productId}/documents
necesită products:read Declarații de conformitate, rapoarte de testare și certificate atașate produsului. Un document public este legat din fiecare pașaport publicat al produsului.
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
necesită products:write Încărcare multipart. PDF, Word, Excel, CSV, text, PNG și JPEG de până la 10 MB, cel mult 20 per produs. Textul este extras în fundal.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| file | file | obligatoriu | Documentul. |
| is_public | boolean | Afișați-l în pașaportul public (implicit 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}
necesită products:write Comută dacă documentul este legat din pașaportul public.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| is_public | boolean | obligatoriu |
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}
necesită products:write Elimină fișierul și legătura lui cu pașaportul.
curl -X DELETE https://myproductpassport.eu/api/v1/products/512/documents/31 \
-H "Authorization: Bearer pk_your_key"{ "message": "Document deleted." }12 / EndpointuriLanț de aprovizionare
/products/{productId}/supply-chain
necesită products:read Pașii afișați în pașaportul produsului, în ordine.
curl https://myproductpassport.eu/api/v1/products/512/supply-chain \
-H "Authorization: Bearer pk_your_key"/products/{productId}/supply-chain
necesită products:write Înlocuiește toți pașii cu lista trimisă, în ordinea trimisă. Trimiteți o listă goală pentru a o goli. Tipuri de pași: raw_material, processing, manufacturing, assembly, packaging, distribution.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| steps | array | obligatoriu | Până la 50 de pași. |
| steps[].step_type | string | obligatoriu | |
| steps[].supplier_name | string | obligatoriu | |
| steps[].supplier_location | string | ||
| steps[].supplier_country | string | ISO 3166-1 alpha-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 / EndpointuriTraduceri
/passports/{id}/translations
necesită passports:read Fiecare valoare de câmp tradusă pe limbi, cu sursa ei: auto (automată, creată la publicare) sau 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}
necesită passports:write Setează traducerile pentru o limbă, după cheia câmpului. O traducere manuală nu este niciodată suprascrisă automat. Trimiteți un șir gol pentru a elimina una.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| fields | object | obligatoriu | field_key: valoare tradusă |
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 / EndpointuriIntegritate și exporturi
/passports/{id}/integrity
necesită passports:read Fiecare stare publicată a pașaportului, ca înregistrare înlănțuită prin hash și semnată Ed25519: amprentă (SHA-256), valoare a lanțului și semnătură. Cheile publice se află la /.well-known/mpp-integrity-keys.json, astfel încât oricine poate verifica lanțul.
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}
necesită passports:read Înregistrarea completă, așa cum a fost semnată, inclusiv instantaneul: ce conținea pașaportul în acel moment, până la hash-ul fiecărui fișier atașat.
curl https://myproductpassport.eu/api/v1/passports/96/integrity/1 \
-H "Authorization: Bearer pk_your_key"/passports/{id}/epcis
necesită passports:read Pașaportul ca document GS1 EPCIS 2.0 JSON-LD: articolul pus în funcțiune, fiecare pas al lanțului de aprovizionare ca observație, bateriile individuale și un pașaport pentru a doua viață ca transformare. Identificatorii sunt URI-uri GS1 Digital Link atunci când produsul are un GTIN.
curl https://myproductpassport.eu/api/v1/passports/96/epcis \
-H "Authorization: Bearer pk_your_key"15 / EndpointuriSolicitări către furnizori
/passports/{id}/supplier-requests
necesită passports:write Trimite unui furnizor, prin e-mail, un link privat pentru a completa câmpurile alese de dvs., în limba sa. Nimic nu ajunge în pașaport până când cineva din spațiul dvs. de lucru nu aprobă.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| supplier_name | string | obligatoriu | |
| supplier_email | string | obligatoriu | |
| field_keys | array | obligatoriu | Chei de câmp din șablonul pașaportului. |
| locale | string | Limba e-mailului și a formularului, de ex. de. | |
| due_at | date | Data limită pentru răspuns; 14 zile dacă este omisă. | |
| 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
necesită passports:read Fiecare solicitare pentru pașaport, împreună cu starea sa.
curl https://myproductpassport.eu/api/v1/passports/96/supplier-requests \
-H "Authorization: Bearer pk_your_key"/supplier-requests/{id}
necesită passports:read O solicitare, cu răspunsurile furnizorului, nota și numele fișierelor atașate.
curl https://myproductpassport.eu/api/v1/supplier-requests/12 \
-H "Authorization: Bearer pk_your_key"16 / EndpointuriPost-vânzare
/passports/{id}/items
necesită items:write Dați articolelor unui produs (orice sector, în afară de baterii, care folosesc /units) propriul număr de serie: fiecare primește propria adresă și cod QR, un cod de autenticitate ascuns pentru etichetă și poate fi înregistrat de proprietarul său. Trimiteți până la 10.000 de articole sau un interval. Cu un GTIN, adresa este GS1 Digital Link /01/{gtin}/21/{serial}.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| items[].serial | string | obligatoriu | Cel mult 20 de litere, cifre, puncte, cratime sau caractere de subliniere. |
| items[].batch | string | Lot, cel mult 20 de caractere. | |
| items[].manufactured_on | string | Data fabricației, AAAA-LL-ZZ. | |
| range | object | În loc de items: prefix, start, count, digits și batch, de exemplu de la SN-00001 la 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}
necesită items:read Un articol cu adresa, starea, dacă este înregistrat și până când îi este valabilă garanția, verificările de autenticitate și istoricul. O cheie cu items:write primește și codul ascuns, pentru tipărire. GET /passports/{id}/items le listează (filtre status și batch, per_page până la 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}
necesită items:write Setați status la stolen sau recalled, iar pagina sa avertizează pe oricine îl scanează, cu status_note al dumneavoastră; un articol furat nu poate fi înregistrat. retired scoate pagina offline. Se pot modifica și batch și manufactured_on.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| status | string | active, stolen, recalled sau retired. | |
| status_note | string | Afișat pe pagina articolului, cel mult 500 de caractere. |
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
necesită aftersales:read Persoanele care v-au înregistrat produsele: nume, e-mail, țară, data cumpărării, comerciant, datele garanției și dacă au acceptat noutăți și oferte (marketing_consent=1 îi listează doar pe aceștia). Implicit înregistrările active; status=pending, transferred sau ended pentru celelalte; since= pentru modificările de după o dată.
curl "https://myproductpassport.eu/api/v1/owner-registrations?marketing_consent=1&since=2026-10-01" \
-H "Authorization: Bearer pk_your_key"/service-requests
necesită aftersales:read Reparații, solicitări în garanție, returnări, piese de schimb și întrebări trimise din pașapoartele dumneavoastră, cele mai noi primele, cu filtre status și type. GET /service-requests/{reference} adaugă conversația.
curl "https://myproductpassport.eu/api/v1/service-requests?status=new" \
-H "Authorization: Bearer pk_your_key"/service-requests/{reference}/replies
necesită aftersales:write Răspunsul dumneavoastră este trimis clientului prin e-mail, cu un link către pagina solicitării, în limba sa. internal: true adaugă o notă vizibilă doar echipei. PATCH /service-requests/{reference} cu un status o duce mai departe (clientul este anunțat când este în lucru, rezolvată sau închisă).
| Parametru | Tip | Descriere | |
|---|---|---|---|
| body | string | obligatoriu | Răspunsul, cel mult 5.000 de caractere. |
| internal | boolean | O notă pentru echipă în loc de răspuns. | |
| status | string | new, in_progress, waiting, resolved sau 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 / EndpointuriEditări în bloc și imagini
/products/bulk-fields
necesită products:write Setează un detaliu al produsului sau un câmp al pașaportului pentru până la 5.000 de produse. mode este set, fill (doar unde este gol) sau clear. Până la 100 de produse sunt actualizate în cadrul solicitării; seturile mai mari sunt puse în coadă (202).
| Parametru | Tip | Descriere | |
|---|---|---|---|
| product_ids | array | obligatoriu | |
| target | string | obligatoriu | product | field |
| key | string | obligatoriu | |
| 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
necesită products:write Încărcare multipart a unui fișier JPG, PNG sau WebP (până la 15MB, maximum 8 per produs). Prima imagine este imaginea de copertă din pașaportul public.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| image | file | obligatoriu | |
| alt | string | Descrierea imaginii. |
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
necesită products:write Transmiteți image_ids în ordinea dorită; prima imagine devine imaginea de copertă.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| image_ids | array | obligatoriu |
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}
necesită products:write Elimină imaginea și fișierul acesteia.
curl -X DELETE https://myproductpassport.eu/api/v1/products/12/images/31 \
-H "Authorization: Bearer pk_your_key"18 / EndpointuriWebhookuri
/webhooks
necesită webhooks:manage Endpointurile înregistrate pentru spațiul dvs. de lucru. Secretele nu sunt incluse aici; obțineți un endpoint pentru a-i vedea secretul.
curl https://myproductpassport.eu/api/v1/webhooks \
-H "Authorization: Bearer pk_your_key"/webhooks
necesită webhooks:manage Înregistrează un URL HTTPS public pentru unul sau mai multe evenimente. Răspunsul include secretul de semnare. Gazdele private sau interne sunt refuzate.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| url | string | obligatoriu | |
| events | array | obligatoriu | Oricare dintre evenimentele enumerate mai jos. |
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}
necesită webhooks:manage curl https://myproductpassport.eu/api/v1/webhooks/3 \
-H "Authorization: Bearer pk_your_key"/webhooks/{id}
necesită webhooks:manage Schimbați URL-ul sau evenimentele, ori suspendați și reluați endpointul. Reluarea resetează numărul de eșecuri; un endpoint este suspendat automat după 10 livrări eșuate consecutive.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| 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
necesită webhooks:manage Pune în coadă o livrare webhook.test pentru a vă verifica receptorul și codul de semnătură.
curl -X POST https://myproductpassport.eu/api/v1/webhooks/3/test \
-H "Authorization: Bearer pk_your_key"{ "message": "Test delivery queued." }/webhooks/{id}/deliveries
necesită webhooks:manage Livrări recente, cele mai noi primele, cu starea HTTP returnată de endpoint și primele 500 de caractere ale răspunsului.
| Parametru | Tip | Descriere | |
|---|---|---|---|
| per_page | integer | Până la 100. |
curl https://myproductpassport.eu/api/v1/webhooks/3/deliveries \
-H "Authorization: Bearer pk_your_key"/webhooks/{id}
necesită webhooks:manage curl -X DELETE https://myproductpassport.eu/api/v1/webhooks/3 \
-H "Authorization: Bearer pk_your_key"{ "message": "Webhook endpoint deleted." }19 / EvenimenteWebhookuri
În loc de interogări repetate, înregistrați un endpoint webhook în aplicație (pagina Webhooks, disponibilă de la planul Starter) și MyProductPassport va trimite JSON prin POST la URL-ul dvs. pe măsură ce au loc evenimentele:
| Eveniment | Se declanșează când |
|---|---|
| product.created | Este creat un produs (aplicație, API sau import CSV) |
| product.updated | Un produs este actualizat |
| product.deleted | Un produs este șters |
| passport.created | Un pașaport este generat |
| passport.published | Un pașaport devine activ |
| passport.archived | Un pașaport este arhivat |
| supplier_request.submitted | Un furnizor trimite informațiile pe care le-ați solicitat |
| owner.registered | Un proprietar își confirmă înregistrarea |
| owner.transferred | Un articol trece la un nou proprietar înregistrat |
| service_request.created | Un client trimite o solicitare de service dintr-un pașaport |
| service_request.updated | O solicitare de service primește un răspuns sau o stare nouă |
| item.status_changed | Un articol este marcat ca furat, rechemat sau retras, ori marcajul este anulat |
| item.verification_failed | O citire securizată eșuează, codurile greșite se adună sau un număr de serie apare în prea multe locuri |
| webhook.test | Trimiteți o livrare de test din aplicație |
Fiecare livrare este un plic JSON: un ID de livrare (același ID este retrimis la reîncercări, ca să puteți elimina duplicatele), evenimentul, numărul încercării, un marcaj temporal și datele evenimentului. Evenimentele de pașaport conțin uuid-ul și URL-ul public al pașaportului, așa că rareori aveți nevoie de o a doua cerere:
{
"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"}
}
}Anteturile conțin numele evenimentului, ID-ul livrării, o marcă temporală Unix și o semnătură HMAC a corpului brut, astfel încât să puteți verifica faptul că provine de la noi și să respingeți reluările:
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>Răspundeți cu orice cod 2xx în 10 secunde. Orice altceva este reîncercat de cinci ori pe parcursul a aproximativ 90 de minute (30 s, 1 min, 5 min, 15 min, 1 h); după 10 eșecuri consecutive, endpointul este suspendat până când îl reactivați.
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $endpointSecret);
abort_unless(hash_equals($expected, $request->header('X-MPP-Signature')), 401);