Note de référence
Le manifeste /.well-known/ucp, champ par champ
Manifeste UCP champ par champ : services, capacités, payment_handlers, clés de signature, négociation de version et erreurs.
Publiée le . Rattachée à le guide d'implémentation UCP.
Un marchand qui adopte UCP publie un fichier JSON à une adresse fixe, /.well-known/ucp.
C’est le point d’entrée unique : un agent qui découvre un domaine lit ce document
et en déduit ce qu’il peut faire avec ce marchand. La documentation grand public
s’arrête généralement à cette phrase. Cette note descend d’un cran, dans les champs
que le document contient réellement.
Les éléments ci-dessous suivent la spécification officielle, version 2026-04-08. UCP versionne par date : la structure décrite ici est celle de cette révision, et la négociation de version décrite plus bas est précisément le mécanisme prévu pour que les révisions coexistent.
Deux clés à la racine
Le document expose deux clés de premier niveau :
{
"ucp": { },
"signing_keys": [ ]
}
ucp porte l’ensemble des métadonnées de protocole. signing_keys porte les clés
publiques, au format JWK, qui servent à vérifier les signatures. Cette seconde clé
n’est pas décorative : la spécification définit des erreurs dédiées
signature_missing, signature_invalid et key_not_found, toutes en HTTP 401.
Un manifeste sans clés exploitables ferme donc la porte à tout échange signé.
À l’intérieur de ucp se trouvent quatre registres :
version, la version de protocole, au formatAAAA-MM-JJ;services, les surfaces d’API et leurs transports ;capabilities, les fonctionnalités déclarées ;payment_handlers, la façon dont les instruments de paiement sont traités.
services : où et comment parler au marchand
Un service décrit une surface d’API pour un domaine fonctionnel. Chaque entrée
combine version, spec, transport, endpoint et schema. La spécification
pose une règle minimale : tous les transports exigent version, spec et
transport ; REST, MCP et le mode embarqué exigent en plus schema.
Quatre transports sont définis :
| Transport | Nature |
|---|---|
| REST | HTTP/1.1 et suivants, charges JSON, verbes et codes standards |
| MCP | JSON-RPC via Model Context Protocol, appel tools/call |
| A2A | protocole Agent-to-Agent, via la spécification Agent Card |
| EP | OpenRPC, communication hôte / embarqué |
REST est le transport de base ; les autres sont optionnels et dépendent des capacités visées. C’est le point qui échappe le plus souvent aux lectures rapides : UCP n’impose pas MCP. Un marchand peut être pleinement conforme en REST seul. La distinction entre les deux protocoles est traitée sur la page UCP vs MCP.
capabilities : ce que le marchand sait faire
Une capacité déclare une fonctionnalité supportée. Les champs obligatoires sont
version, spec et schema. Les champs optionnels sont id, config et
extends.
extends est le mécanisme d’extension. Une capacité peut hériter d’un parent
unique, désigné par une chaîne, ou de plusieurs parents, désignés par un tableau.
La spécification illustre le cas avec une extension de livraison qui étend le
paiement :
{
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/fulfillment",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/fulfillment.json",
"extends": "dev.ucp.shopping.checkout"
}
]
}
Le nommage est un espace de noms inversé, dev.ucp.shopping.checkout. Un marchand
ou un éditeur peut donc déclarer ses propres capacités sous son propre espace de
noms sans entrer en collision avec le registre officiel.
payment_handlers : une spécification, pas un prestataire
C’est la nuance que la spécification prend soin d’écrire noir sur blanc : les gestionnaires de paiement sont des spécifications, pas des entités. Ils décrivent comment un type d’instrument est traité, pas quel prestataire le traite.
Une entrée combine id, version, spec, schema, available_instruments et
config. La conséquence pratique est directe : changer de PSP ne change pas
nécessairement le manifeste, tant que la spécification de traitement reste la même.
Le panorama des rails de paiement est sur la page
paiement agentique.
La négociation : une intersection, pas un accord
Quand un agent et un marchand se rencontrent, aucun des deux n’impose sa version. La spécification définit un algorithme d’intersection en quatre temps :
- calculer l’intersection, en ne gardant que les capacités présentes des deux côtés ;
- sélectionner, pour chaque capacité retenue, la version commune la plus élevée ;
- élaguer les extensions orphelines, dont le parent n’est pas dans l’intersection ;
- répéter l’élagage jusqu’à stabilisation.
Et la règle qui tranche les cas vides, citée telle quelle : « If the set is empty (no mutual version), exclude the capability from the intersection. » Une capacité sans version commune n’est pas une erreur, elle disparaît simplement du périmètre de l’échange.
Cette boucle d’élagage répétée mérite l’attention d’une équipe d’implémentation. Retirer une capacité de base peut faire tomber en cascade toutes les extensions qui en dépendent, y compris celles qu’on croyait indépendantes.
Les codes d’erreur, et leur double traduction
Chaque erreur porte un code stable, traduit différemment selon le transport. C’est la partie la plus opérationnelle du document, et celle qu’il faut câbler dans la supervision côté marchand.
| Code | REST | MCP |
|---|---|---|
invalid_profile_url |
400 | -32001 |
profile_unreachable |
424 | -32001 |
profile_malformed |
422 | -32001 |
version_unsupported |
422 | -32001 |
capabilities_incompatible |
200 | result |
signature_missing |
401 | -32000 |
signature_invalid |
401 | -32000 |
key_not_found |
401 | -32000 |
Deux lignes méritent d’être lues deux fois.
profile_unreachable renvoie un HTTP 424, Failed Dependency. Autrement dit, quand
votre manifeste est injoignable, l’échec n’est pas signalé comme une erreur du
client mais comme une dépendance défaillante. Une supervision qui ne surveille que
les 5xx de son propre domaine ne verra jamais ce cas.
capabilities_incompatible renvoie un HTTP 200. L’incompatibilité n’est pas une
erreur de transport : la requête a réussi, c’est la négociation qui n’a rien
trouvé de commun. Un tableau de bord qui compte les codes HTTP classera cet échec
commercial parmi les succès techniques. C’est un angle mort à corriger dans la
supervision avant, et non après, la mise en production.
Ce qu’il faut retenir avant d’implémenter
Le manifeste n’est pas un fichier de configuration statique qu’on dépose une fois. C’est un contrat versionné, signé, négocié à chaque rencontre, et dont les échecs se lisent en partie hors du canal HTTP habituel. Trois conséquences pour une feuille de route :
- versionner le manifeste comme du code, avec revue, puisque retirer une capacité élague ses extensions ;
- publier et faire tourner les
signing_keys, sans quoi tout le volet signé est inutilisable ; - instrumenter les codes de négociation, pas seulement les codes HTTP.
Pour la mise en place amont, prérequis Merchant Center et voie protocole, voir le guide d’implémentation. Pour la vue d’ensemble du standard et de ses partenaires, voir la page de référence UCP.
Sources
- Universal Commerce Protocol, spécification officielle 2026-04-08
- Google Developers Blog, Under the Hood: Universal Commerce Protocol
Revenir à le guide d'implémentation UCP · Toutes les notes · Read in English