Référence de l'API
Tout MyProductPassport est accessible via une API REST authentifiée par clé : créez des produits, générez et publiez des passeports numériques de produit, envoyez des données de batterie en direct et vérifiez la conformité, directement depuis votre ERP, votre PIM ou votre pipeline de build.
01 / Premiers pasAuthentification
Chaque requête est authentifiée par une clé API transmise comme jeton Bearer. Les clés se créent dans l'application, sous Clés API, ne s'affichent qu'une fois et sont stockées hachées ; chaque clé a ses propres autorisations, une liste d'adresses IP autorisées facultative et une date d'expiration facultative. Les clés peuvent être renouvelées sans interruption.
Authorization: Bearer pk_your_api_keyLes autorisations sont accordées par clé, pour qu'une intégration n'obtienne que ce dont elle a besoin :
| Autorisation | Autorisations |
|---|---|
| products:read | Lire les produits |
| products:write | Créer, modifier et supprimer des produits |
| passports:read | Lire les passeports |
| passports:write | Générer des passeports |
| passports:publish | Publier et archiver des passeports |
| webhooks:manage | Créer, tester et supprimer des points de terminaison 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 / Premiers pasLimites de requêtes
Les limites s'appliquent par clé et par minute et dépendent de l'offre :
| Plan | Requêtes / minute |
|---|---|
| Gratuit | 30 |
| Micro | 60 |
| E-Label | 60 |
| Starter | 120 |
| Professional | 300 |
| Business | 600 |
| Battery | 600 |
Chaque réponse contient les en-têtes X-RateLimit-Limit et X-RateLimit-Remaining. Au-delà de la limite, la réponse est 429 :
{ "error": "Rate limit exceeded.", "limit": 300, "retry_after": 60 }03 / Premiers pasErreurs
Les erreurs sont renvoyées en JSON avec un code de statut classique. Les plus courantes :
| Statut | Signification | Exemple de corps |
|---|---|---|
| 401 | Clé absente, invalide, révoquée ou expirée | {"error": "Invalid or revoked API key."} |
| 403 | La clé n'a pas une permission, l'IP n'est pas sur la liste autorisée, ou le quota de l'offre est atteint | {"message": "API key does not have 'products:write' permission."} |
| 404 | La ressource n'existe pas dans votre espace de travail | {"message": "Not found."} |
| 422 | La validation a échoué | {"message": "…", "errors": {"gtin": ["…"]}} |
| 429 | Limite de requêtes dépassée | {"error": "Rate limit exceeded."} |
04 / Premiers pasPagination
Les endpoints de liste renvoient 25 éléments par page avec les objets links et meta standard. Passez ?page=2 pour parcourir la collection.
05 / Premiers pasConnecteur d'assistant IA (MCP)
Connectez Claude, Cursor ou tout assistant qui parle le Model Context Protocol, et demandez-lui simplement de créer des produits, de remplir des passeports à partir de ce que vous lui dites et de vérifier ce qui manque encore. Il utilise une clé API, avec ses permissions et sa limite de requêtes. Il peut créer des brouillons et remplir des champs ; il ne publie, n'archive et ne supprime jamais rien : cela reste entre vos mains dans l'application.
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"]
}
}
}Les outils proposés :
| Outil | Ce qu'il fait |
|---|---|
| list_products | Les produits de l'espace de travail, du plus récent au plus ancien, 25 par page, avec leur secteur et leur dernier passeport. |
| get_product | Un produit avec ses détails, son secteur, ses sections réglementaires et son dernier passeport. |
| list_sectors | Les modèles de secteur qu'un produit peut utiliser (textile, électronique, batteries, vin et plus), avec leurs identifiants. Le secteur d'un produit détermine les champs obligatoires de son passeport. |
| create_product | Ajoute un produit à l'espace de travail. Utilisez un sector_id issu de list_sectors. compliance_sections ajoute des sections réglementaires à son passeport : gpsr, epr, france, chemicals, eudr. |
| list_passports | Les passeports de l'espace de travail, du plus récent au plus ancien, 25 par page, avec leur statut (draft, published, archived), leur taux de complétude et leur adresse publique. |
| get_passport | Un passeport : statut, version, taux de complétude, adresse publique et liens vers le code QR. |
| create_passport | Crée un brouillon de passeport pour un produit. Il n'est pas publié : c'est une personne qui le publie dans l'application. |
| get_passport_fields | Ce que demande un passeport : les clés des champs obligatoires et facultatifs, le sens de chacun (libellé, description, exemple), les valeurs présentes et les champs obligatoires manquants. |
| update_passport_fields | Écrit des valeurs de champs sur un passeport en brouillon ou publié (un passeport publié est mis à jour sur place : même adresse, même code QR). Clés issues de get_passport_fields ; une chaîne vide supprime une valeur. N'écrire que des faits indiqués par l'utilisateur ou ses documents. |
| get_compliance | La complétude d'un passeport : pourcentage, statut et champs obligatoires encore manquants. |
06 / Points de terminaisonCompte
/me
Renvoie le compte authentifié, son offre d'abonnement et la part utilisée du quota de produits. Utile pour tester la connexion.
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 / Points de terminaisonProduits
/products
nécessite products:read Liste les produits de votre espace de travail, du plus récent au plus ancien, 25 par page. Chaque produit inclut son secteur et un résumé de son dernier passeport.
| Paramètre | Type | Description | |
|---|---|---|---|
| page | integer | Numéro de page. |
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
nécessite products:write Crée un produit. Échoue avec 403 si le quota de produits de l'offre est épuisé.
| Paramètre | Type | Description | |
|---|---|---|---|
| name | string | obligatoire | Nom du produit, jusqu'à 255 caractères. |
| sku | string | Votre SKU interne, jusqu'à 100 caractères. | |
| gtin | string | GTIN-8, 12, 13 ou 14 (chiffres uniquement). | |
| brand | string | Marque affichée sur le passeport public. | |
| description | string | Jusqu'à 2 000 caractères. | |
| category | string | Catégorie en texte libre. Par défaut « general ». | |
| sector_id | integer | Un identifiant de secteur, qui sélectionne le modèle de champs du passeport. | |
| country_of_origin | string | Code pays, par ex. « PT ». | |
| weight | number | Poids net. | |
| weight_unit | string | L'une des valeurs kg, g, lb, oz. Par défaut kg. | |
| materials | array | Objets {name, percentage 0-100}. | |
| has_packaging | boolean | Ajoute au passeport les champs du modèle Emballage (clés commençant par pkg_), sous le même QR code. |
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
nécessite products:write Crée jusqu'à 100 produits en un appel. Le lot entier est refusé avec 403 s'il dépasse votre quota de produits restant. Pour des catalogues de plusieurs milliers d'articles, appelez ce point de terminaison en boucle ou utilisez l'import CSV de l'application.
| Paramètre | Type | Description | |
|---|---|---|---|
| products | array | obligatoire | De 1 à 100 objets produit avec les mêmes champs que « Créer un produit » (hors matériaux). |
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}
nécessite products:read Renvoie un produit avec son secteur et un résumé de son dernier passeport. 404 si l'id n'est pas dans votre espace de travail.
curl https://myproductpassport.eu/api/v1/products/512 \
-H "Authorization: Bearer pk_your_key"/products/{id}
nécessite products:write Met à jour partiellement un produit. N'envoyez que les champs à modifier ; la liste des champs est la même que pour Créer un produit.
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}
nécessite products:write Supprime un produit de façon logique (soft delete). Les passeports publiés du produit continuent de fonctionner, pour que les QR codes imprimés ne soient jamais orphelins.
curl -X DELETE https://myproductpassport.eu/api/v1/products/512 \
-H "Authorization: Bearer pk_your_key"{ "message": "Product deleted." }08 / Points de terminaisonPasseports
/passports
nécessite passports:read Liste les passeports, du plus récent au plus ancien, 25 par page, avec un résumé du produit et tous les champs du passeport.
| Paramètre | Type | Description | |
|---|---|---|---|
| page | integer | Numéro de page. |
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
nécessite passports:write Génère un passeport brouillon pour un produit, en préremplissant les champs à partir des données produit et du modèle du secteur. Renvoie le brouillon avec son score de conformité. Si le produit a déjà un passeport en ligne, renvoie 409 avec ce passeport : corrigez-le avec PUT /passports/{id}/fields, qui conserve son adresse et son code QR.
curl -X POST https://myproductpassport.eu/api/v1/products/512/passports \
-H "Authorization: Bearer pk_your_key"/passports/{id}
nécessite passports:read Renvoie un passeport avec son produit, ses champs, son URL publique et son GS1 Digital Link.
curl https://myproductpassport.eu/api/v1/passports/96 \
-H "Authorization: Bearer pk_your_key"/passports/{id}/publish
nécessite passports:publish Publie un brouillon de passeport et met en ligne sa page publique et son QR code. Seuls les brouillons peuvent être publiés ; tout autre statut renvoie 404.
curl -X POST https://myproductpassport.eu/api/v1/passports/96/publish \
-H "Authorization: Bearer pk_your_key"/passports/{id}/archive
nécessite passports:publish Archive un passeport et retire sa page publique de la circulation.
curl -X POST https://myproductpassport.eu/api/v1/passports/96/archive \
-H "Authorization: Bearer pk_your_key"/passports/bulk-publish
nécessite passports:publish Publie jusqu'à 50 brouillons de passeport en un appel et indique le résultat pour chacun, afin qu'un échec n'interrompe jamais le lot.
| Paramètre | Type | Description | |
|---|---|---|---|
| passport_ids | array | obligatoire | De 1 à 50 identifiants de passeport. |
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
nécessite passports:write Pour un produit préparé en vue du réemploi, réaffecté ou reconditionné, le règlement sur les batteries (article 77, paragraphe 7) impose un nouveau passeport lié à l'original. Cette opération crée un nouvel enregistrement produit et un passeport brouillon prérempli à partir du passeport publié et lié à celui-ci. L'original reste en ligne et les deux passeports affichent le lien. Publiez le nouveau avec POST /passports/{id}/publish.
| Paramètre | Type | Description | |
|---|---|---|---|
| stage | string | obligatoire | prepared_for_reuse, repurposed ou 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
nécessite passports:read Renvoie les clés de champ demandées par le modèle du secteur du passeport (obligatoires et facultatives), les valeurs actuelles et les clés obligatoires encore manquantes. Utilisez-le pour construire le contenu 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
nécessite passports:write Écrit n'importe quel ensemble de valeurs de champ sur un passeport brouillon ou en ligne : l'ensemble complet de l'annexe XIII pour une batterie, les champs d'un modèle de secteur ou vos propres clés. N'envoyez que les clés à modifier ; une valeur nulle ou vide supprime le champ. Un passeport en ligne est mis à jour sur place, son adresse et son QR code ne changent pas et ses traductions automatiques sont régénérées. La conformité est recalculée. Cet appel ne publie pas un brouillon ; utilisez POST /passports/{id}/publish.
| Paramètre | Type | Description | |
|---|---|---|---|
| fields | object | obligatoire | Table de correspondance clé de champ / valeur. Les clés sont composées de lettres minuscules, de chiffres et de tirets bas ; les valeurs peuvent atteindre 5 000 caractères. Jusqu'à 200 clés par appel. |
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
nécessite passports:write Transmet les données propres à cette batterie (annexe XIII, point 4, du règlement (UE) 2023/1542) à un passeport publié, pour les systèmes BMS et de gestion de flotte. Envoyez n'importe quel sous-ensemble des champs ci-dessous ; la conformité est revérifiée après la mise à jour. Ces valeurs ne sont affichées qu'aux visiteurs approuvés par le titulaire du passeport (article 77, paragraphe 2), jamais sur la page publique. capacity_fade, power_capability et internal_resistance sont enregistrés comme mesures actuelles de cette batterie (current_*), distinctes des valeurs d'origine du modèle.
| Paramètre | Type | Description | |
|---|---|---|---|
| state_of_health | string | par ex. « 97 % à 412 cycles ». | |
| state_of_certified_energy | string | Énergie certifiée restante (batteries de véhicules électriques). | |
| battery_status | string | original, repurposed, re-used, remanufactured ou waste. | |
| capacity_fade | string | Perte de capacité à ce jour. Enregistrée sous current_capacity_fade. | |
| power_capability | string | Puissance actuelle. Enregistrée sous current_power_capability. | |
| internal_resistance | string | Résistance interne mesurée. Enregistrée sous current_internal_resistance. | |
| use_data | string | Cycles, événements négatifs, température et état de charge, jusqu'à 5 000 caractères. |
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
nécessite passports:write Chaque batterie doit avoir son propre passeport (règlement (UE) 2023/1542, article 77, paragraphe 1). Enregistrez jusqu'à 10 000 batteries d'un modèle en un appel, chacune avec son numéro de série (jusqu'à 20 lettres, chiffres, points, tirets ou traits de soulignement) et, en option, manufacturing_date, battery_status et ses données de l'annexe XIII, point 4. Les numéros de série existants sont mis à jour ; les valeurs omises sont conservées. Si le produit a un GTIN, l'adresse de chaque batterie est son GS1 Digital Link, /01/{gtin}/21/{serial}. Les données du point 4 ne sont visibles que par les personnes autorisées par le titulaire.
| Paramètre | Type | Description | |
|---|---|---|---|
| units[].serial | string | obligatoire | Le numéro de série de la batterie. |
| units[].manufacturing_date | string | Mois et année, par ex. "2026-09". | |
| units[].battery_status | string | original ou waste. Un changement de statut nécessite les valeurs mesurées lors de celui-ci (annexe XIII, point 4 a)) ; waste nécessite aussi responsible_party_type (producer, pro ou waste_operator), responsible_party_name et responsible_party_contact (article 77, paragraphe 7). recycled, avec recycled_at et recycler_name, met fin au passeport (article 77, paragraphe 8). Une batterie réaffectée, réemployée ou remanufacturée reçoit un nouveau passeport : POST /passports/{id}/units/{serial}/successor. | |
| units[].state_of_health | string | Également 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 et 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}
nécessite passports:write Pour un système de gestion de batterie qui envoie les données d'une batterie : n'importe lesquels de battery_status, state_of_health, state_of_certified_energy, current_capacity_fade, current_power_capability, current_internal_resistance et use_data. Faites un GET sur le même chemin pour les lire, ou GET /passports/{id}/units pour la liste (per_page jusqu'à 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
nécessite passports:read L'annexe XIII, point 4 a), exige les valeurs de performance et de durabilité lors de la mise sur le marché de la batterie et lors d'un changement de statut. Ces mesures sont conservées telles quelles, quelles que soient les données envoyées ensuite ; envoyez record_snapshot: true avec un PATCH pour conserver également une mesure périodique.
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
nécessite passports:write Article 77, paragraphe 7 : une batterie préparée en vue du réemploi, réaffectée ou remanufacturée dispose d'un nouveau passeport lié à son original. Cette opération enregistre à nouveau la batterie, avec un nouveau numéro de série et un nouvel identifiant, sous un modèle de batterie de seconde vie de votre espace de travail (créé à partir de ce modèle s'il n'en existe pas encore), relie les deux et conserve les valeurs mesurées lors du changement. La batterie d'origine conserve son passeport. Complétez et publiez le modèle de seconde vie avec POST /passports/{id}/publish.
| Paramètre | Type | Description | |
|---|---|---|---|
| stage | string | obligatoire | prepared_for_reuse, repurposed ou remanufactured. |
| values | object | obligatoire | Les valeurs mesurées lors du changement : au moins une valeur parmi remaining_capacity_ah ou current_capacity_fade, parmi current_power_capability ou power_fade, parmi current_internal_resistance ou internal_resistance_increase, ainsi que expected_lifetime_cycles_remaining (annexe IV, partie A). |
| serial | string | Le nouveau numéro de série. Par défaut : le numéro de série d'origine suivi de -RU, -RP ou -RM. | |
| measured_at | string | Date à laquelle les valeurs ont été mesurées. | |
| member_state | string | Code à deux lettres de l'État membre où l'état de santé a été testé (article 73, paragraphe 1, point a)). | |
| target_passport_id | integer | Un modèle de seconde vie existant de ce modèle de batterie, sous lequel l'enregistrer. |
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
nécessite passports:write Enregistre sur un passeport la soumission au registre DPP de l'UE et son résultat : statut, ID de corrélation, identifiant d'enregistrement renvoyé par le registre et lien facultatif vers une copie de sauvegarde hébergée par un prestataire de services DPP. L'enregistrement lui-même s'effectue dans le registre de la Commission (formulaire web ou envoi de fichier) ; ceci conserve le résultat avec le passeport. GET /passports/{id} renvoie le même bloc sous registry.
| Paramètre | Type | Description | |
|---|---|---|---|
| status | string | not_submitted, submitted, registered ou failed. | |
| product_group | string | Groupe de produits du registre, par exemple batteries. | |
| granularity | string | modèle, lot ou article. | |
| upi | string | Identifiant unique de produit sous forme d'URL https. Par défaut, l'URL du passeport public. | |
| correlation_id | string | Identifiant de corrélation attribué par le Registre lors de la soumission. | |
| uri | string | Identifiant d'enregistrement renvoyé par le registre. | |
| backup_url | string | Lien https vers la copie de sauvegarde hébergée par un prestataire de services DPP. | |
| submitted_at | date | Date de soumission. | |
| registered_at | date | Date d'enregistrement. | |
| error | string | Description de l'erreur d'une soumission échouée. |
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
nécessite passports:read Le QR code du passeport sous forme de fichier : svg (par défaut), png (à vos couleurs, prêt à imprimer) ou pdf (planche d'étiquettes).
| Paramètre | Type | Description | |
|---|---|---|---|
| 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 / Points de terminaisonConformité
/passports/{passportId}/compliance
nécessite passports:read Effectue un contrôle de conformité en direct d'un passeport par rapport aux champs obligatoires de son secteur et indique exactement ce qui manque.
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 / Points de terminaisonSecteurs
/sectors
Les secteurs dans lesquels un produit peut être classé : les secteurs système de la plateforme ainsi que ceux définis par votre espace de travail. Utilisez l'id pour créer des produits et les clés de champ pour écrire les champs du passeport.
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 / Points de terminaisonDocuments
/products/{productId}/documents
nécessite products:read Déclarations de conformité, rapports d'essai et certificats joints au produit. Un document public est lié depuis chaque passeport publié du produit.
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
nécessite products:write Envoi multipart. PDF, Word, Excel, CSV, texte, PNG et JPEG jusqu'à 10 Mo, 20 au maximum par produit. Le texte est extrait en arrière-plan.
| Paramètre | Type | Description | |
|---|---|---|---|
| file | file | obligatoire | Le document. |
| is_public | boolean | L'afficher sur le passeport public (false par défaut). |
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}
nécessite products:write Indique si le document est lié depuis le passeport public.
| Paramètre | Type | Description | |
|---|---|---|---|
| is_public | boolean | obligatoire |
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}
nécessite products:write Supprime le fichier et son lien avec le passeport.
curl -X DELETE https://myproductpassport.eu/api/v1/products/512/documents/31 \
-H "Authorization: Bearer pk_your_key"{ "message": "Document deleted." }12 / Points de terminaisonChaîne d'approvisionnement
/products/{productId}/supply-chain
nécessite products:read Les étapes affichées sur le passeport du produit, dans l'ordre.
curl https://myproductpassport.eu/api/v1/products/512/supply-chain \
-H "Authorization: Bearer pk_your_key"/products/{productId}/supply-chain
nécessite products:write Remplace toutes les étapes par la liste envoyée, dans l'ordre d'envoi. Envoyez une liste vide pour la vider. Types d'étape : raw_material, processing, manufacturing, assembly, packaging, distribution.
| Paramètre | Type | Description | |
|---|---|---|---|
| steps | array | obligatoire | Jusqu'à 50 étapes. |
| steps[].step_type | string | obligatoire | |
| steps[].supplier_name | string | obligatoire | |
| 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 / Points de terminaisonTraductions
/passports/{id}/translations
nécessite passports:read Chaque valeur de champ traduite par langue, avec sa source : auto (automatique, générée à la publication) ou manuelle.
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}
nécessite passports:write Définit les traductions d'une langue, par clé de champ. Une traduction manuelle n'est jamais écrasée par la machine. Envoyez une chaîne vide pour en supprimer une.
| Paramètre | Type | Description | |
|---|---|---|---|
| fields | object | obligatoire | field_key : valeur traduite |
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 / Points de terminaisonIntégrité et exports
/passports/{id}/integrity
nécessite passports:read Chaque état publié du passeport sous forme d'enregistrement chaîné par hachage et signé en Ed25519 : empreinte (SHA-256), valeur de chaîne et signature. Les clés publiques se trouvent à /.well-known/mpp-integrity-keys.json, afin que chacun puisse vérifier la chaîne.
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}
nécessite passports:read L'enregistrement complet tel qu'il a été signé, instantané inclus : ce qu'indiquait le passeport à ce moment précis, jusqu'au hachage de chaque fichier joint.
curl https://myproductpassport.eu/api/v1/passports/96/integrity/1 \
-H "Authorization: Bearer pk_your_key"/passports/{id}/epcis
nécessite passports:read Le passeport sous forme de document GS1 EPCIS 2.0 JSON-LD : l'article mis en service, chaque étape de la chaîne d'approvisionnement en tant qu'observation, les batteries individuelles, et un passeport seconde vie en tant que transformation. Les identifiants sont des URI GS1 Digital Link lorsque le produit possède un GTIN.
curl https://myproductpassport.eu/api/v1/passports/96/epcis \
-H "Authorization: Bearer pk_your_key"15 / Points de terminaisonDemandes fournisseur
/passports/{id}/supplier-requests
nécessite passports:write Envoie par e-mail à un fournisseur un lien privé pour renseigner les champs que vous choisissez, dans sa langue. Rien n'est ajouté au passeport tant qu'un membre de votre espace de travail ne l'a pas approuvé.
| Paramètre | Type | Description | |
|---|---|---|---|
| supplier_name | string | obligatoire | |
| supplier_email | string | obligatoire | |
| field_keys | array | obligatoire | Clés de champs issues du modèle du passeport. |
| locale | string | Langue de l'e-mail et du formulaire, par ex. de. | |
| due_at | date | Date limite de réponse ; 14 jours si omise. | |
| 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
nécessite passports:read Chaque demande concernant le passeport, avec son statut.
curl https://myproductpassport.eu/api/v1/passports/96/supplier-requests \
-H "Authorization: Bearer pk_your_key"/supplier-requests/{id}
nécessite passports:read Une demande avec les réponses du fournisseur, sa note et les noms des fichiers joints.
curl https://myproductpassport.eu/api/v1/supplier-requests/12 \
-H "Authorization: Bearer pk_your_key"16 / Points de terminaisonAprès-vente
/passports/{id}/items
nécessite items:write Donnez aux articles d'un produit (tout secteur sauf les batteries, qui utilisent /units) leur propre numéro de série : chacun reçoit sa propre adresse et son QR code, un code d'authenticité caché pour son étiquette, et peut être enregistré par son propriétaire. Envoyez jusqu'à 10 000 articles, ou une plage. Avec un GTIN, l'adresse est le GS1 Digital Link /01/{gtin}/21/{serial}.
| Paramètre | Type | Description | |
|---|---|---|---|
| items[].serial | string | obligatoire | Jusqu'à 20 lettres, chiffres, points, tirets ou traits de soulignement. |
| items[].batch | string | Lot, jusqu'à 20 caractères. | |
| items[].manufactured_on | string | Date de fabrication, AAAA-MM-JJ. | |
| range | object | À la place de items : prefix, start, count, digits et batch, par exemple SN-00001 à 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}
nécessite items:read Un article avec son adresse, son statut, s'il est enregistré et jusqu'à quand court sa garantie, ses vérifications d'authenticité et son historique. Une clé avec items:write obtient aussi son code caché, pour l'impression. GET /passports/{id}/items les liste (filtres status et batch, per_page jusqu'à 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}
nécessite items:write Passez status à stolen ou recalled et sa page avertit quiconque le scanne, avec votre status_note ; un article volé ne peut pas être enregistré. retired met sa page hors ligne. batch et manufactured_on peuvent aussi être modifiés.
| Paramètre | Type | Description | |
|---|---|---|---|
| status | string | active, stolen, recalled ou retired. | |
| status_note | string | Affiché sur la page de l'article, jusqu'à 500 caractères. |
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
nécessite aftersales:read Les personnes qui ont enregistré vos produits : nom, e-mail, pays, date d'achat, revendeur, dates de garantie, et si elles ont accepté les actualités et offres (marketing_consent=1 ne liste que celles-ci). Enregistrements actifs par défaut ; status=pending, transferred ou ended pour les autres ; since= pour les changements après une date.
curl "https://myproductpassport.eu/api/v1/owner-registrations?marketing_consent=1&since=2026-10-01" \
-H "Authorization: Bearer pk_your_key"/service-requests
nécessite aftersales:read Réparations, demandes de garantie, reprises, pièces détachées et questions envoyées depuis vos passeports, les plus récentes d'abord, avec filtres status et type. GET /service-requests/{reference} ajoute la conversation.
curl "https://myproductpassport.eu/api/v1/service-requests?status=new" \
-H "Authorization: Bearer pk_your_key"/service-requests/{reference}/replies
nécessite aftersales:write Votre réponse est envoyée au client par e-mail avec un lien vers sa page de demande, dans sa langue. internal: true ajoute une note que seule votre équipe voit. PATCH /service-requests/{reference} avec un status la fait avancer (le client est prévenu quand elle est en cours, résolue ou fermée).
| Paramètre | Type | Description | |
|---|---|---|---|
| body | string | obligatoire | La réponse, jusqu'à 5 000 caractères. |
| internal | boolean | Une note pour votre équipe au lieu d'une réponse. | |
| status | string | new, in_progress, waiting, resolved ou 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 / Points de terminaisonModifications en masse et images
/products/bulk-fields
nécessite products:write Définit une information produit ou un champ de passeport sur jusqu'à 5 000 produits. mode vaut set, fill (uniquement là où la valeur est vide) ou clear. Jusqu'à 100 produits sont mis à jour dans la requête ; les ensembles plus importants sont mis en file d'attente (202).
| Paramètre | Type | Description | |
|---|---|---|---|
| product_ids | array | obligatoire | |
| target | string | obligatoire | product | field |
| key | string | obligatoire | |
| 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
nécessite products:write Téléversement multipart d'un fichier JPG, PNG ou WebP (jusqu'à 15MB, 8 par produit). La première image sert d'image de couverture sur le passeport public.
| Paramètre | Type | Description | |
|---|---|---|---|
| image | file | obligatoire | |
| alt | string | Description de l'image. |
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
nécessite products:write Transmettez image_ids dans l'ordre souhaité ; la première devient l'image de couverture.
| Paramètre | Type | Description | |
|---|---|---|---|
| image_ids | array | obligatoire |
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}
nécessite products:write Supprime l'image et son fichier.
curl -X DELETE https://myproductpassport.eu/api/v1/products/12/images/31 \
-H "Authorization: Bearer pk_your_key"18 / Points de terminaisonWebhooks
/webhooks
nécessite webhooks:manage Les endpoints enregistrés pour votre espace de travail. Les secrets n'y figurent pas ; récupérez un endpoint pour voir son secret.
curl https://myproductpassport.eu/api/v1/webhooks \
-H "Authorization: Bearer pk_your_key"/webhooks
nécessite webhooks:manage Enregistre une URL HTTPS publique pour un ou plusieurs événements. La réponse inclut le secret de signature. Les hôtes privés ou internes sont refusés.
| Paramètre | Type | Description | |
|---|---|---|---|
| url | string | obligatoire | |
| events | array | obligatoire | L'un des événements listés ci-dessous. |
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}
nécessite webhooks:manage curl https://myproductpassport.eu/api/v1/webhooks/3 \
-H "Authorization: Bearer pk_your_key"/webhooks/{id}
nécessite webhooks:manage Modifiez l'URL ou les événements, ou suspendez-le puis réactivez-le. La réactivation remet le compteur d'échecs à zéro ; un point de terminaison est suspendu automatiquement après 10 livraisons échouées consécutives.
| Paramètre | Type | Description | |
|---|---|---|---|
| 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
nécessite webhooks:manage Met en file d'attente un envoi webhook.test pour vérifier votre récepteur et votre code de signature.
curl -X POST https://myproductpassport.eu/api/v1/webhooks/3/test \
-H "Authorization: Bearer pk_your_key"{ "message": "Test delivery queued." }/webhooks/{id}/deliveries
nécessite webhooks:manage Envois récents, du plus récent au plus ancien, avec le statut HTTP renvoyé par votre endpoint et les 500 premiers caractères de sa réponse.
| Paramètre | Type | Description | |
|---|---|---|---|
| per_page | integer | Jusqu'à 100. |
curl https://myproductpassport.eu/api/v1/webhooks/3/deliveries \
-H "Authorization: Bearer pk_your_key"/webhooks/{id}
nécessite webhooks:manage curl -X DELETE https://myproductpassport.eu/api/v1/webhooks/3 \
-H "Authorization: Bearer pk_your_key"{ "message": "Webhook endpoint deleted." }19 / ÉvénementsWebhooks
Au lieu d'interroger régulièrement l'API, enregistrez un endpoint webhook dans l'application (page Webhooks, disponible à partir de l'offre Starter) et MyProductPassport enverra du JSON en POST à votre URL au fil des événements :
| Événement | Déclenché quand |
|---|---|
| product.created | Un produit est créé (application, API ou import CSV) |
| product.updated | Un produit est mis à jour |
| product.deleted | Un produit est supprimé |
| passport.created | Un passeport est généré |
| passport.published | Un passeport est publié |
| passport.archived | Un passeport est archivé |
| supplier_request.submitted | Un fournisseur envoie les informations que vous avez demandées |
| owner.registered | Un propriétaire confirme son enregistrement |
| owner.transferred | Un article passe à un nouveau propriétaire enregistré |
| service_request.created | Un client envoie une demande de service depuis un passeport |
| service_request.updated | Une demande de service reçoit une réponse ou un nouveau statut |
| item.status_changed | Un article est signalé volé, rappelé ou hors service, ou rétabli |
| item.verification_failed | Une lecture sécurisée échoue, les codes erronés s'accumulent, ou un numéro de série est vu à trop d'endroits |
| webhook.test | Vous envoyez un envoi de test depuis l'application |
Chaque livraison est une enveloppe JSON : un identifiant de livraison (le même identifiant est renvoyé lors des nouvelles tentatives, pour dédoublonner), l'événement, le numéro de tentative, un horodatage et les données de l'événement. Les événements de passeport contiennent l'uuid et l'URL publique du passeport, ce qui évite le plus souvent une seconde requête :
{
"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"}
}
}Les en-têtes contiennent le nom de l'événement, l'id d'envoi, un horodatage Unix et une signature HMAC du corps brut, pour que vous puissiez vérifier qu'il vient de nous et rejeter les rejeux :
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épondez par un code 2xx dans les 10 secondes. Toute autre réponse est réessayée cinq fois sur environ 90 minutes (30 s, 1 min, 5 min, 15 min, 1 h) ; après 10 échecs consécutifs, le point de terminaison est suspendu jusqu'à ce que vous le réactiviez.
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $endpointSecret);
abort_unless(hash_equals($expected, $request->header('X-MPP-Signature')), 401);