Identifier votre application : la carte d'identité d'un appel Conexio
Chaque requête vers l'API Conexio peut porter deux en-têtes HTTP qui disent qui appelle,
en quelle version, pourquoi, pour qui et dans quel lot : conexio-agent et
traceparent. C'est la carte d'identité de l'appel. Elle ne remplace rien de ce que vous
faites déjà : l'authentification reste la Basic Auth avec le header COMPANY_CODE.
Elle s'y ajoute.
Recommandée dès maintenant pour toute application qui appelle l'API ; inscrite dans les journaux de la plateforme (voir ce que la plateforme en fait).
Ces en-têtes sont des déclarations de votre application, utiles au support, au diagnostic et aux statistiques. Ils n'ouvrent aucun droit et n'en ferment aucun : l'autorisation reste la licence et la clé d'API. Aucune requête n'est refusée parce qu'un de ces en-têtes manque ou est mal formé. Aucun d'eux n'est un secret : ils peuvent être journalisés tels quels, chez vous comme chez nous.
Pourquoi déclarer votre application
- Support. « L'importation de 10 h 42 a échoué » ne permet pas de retrouver un appel
parmi des milliers. Un identifiant de lot (
traceparent) que vous avez aussi écrit dans votre propre journal, oui : il relie vos lignes de journal aux nôtres. - Diagnostic. Sur une même licence, distinguer les appels de votre application de ceux d'un outil de test (Postman ou autre), d'un script ou d'une autre intégration. Une requête sans ces en-têtes est simplement un appel direct : c'est une information, pas une anomalie.
- Télémétrie. Savoir quelles versions de votre application sont en circulation et quelles fonctionnalités appellent l'API, pour préparer les évolutions sans casser ce qui tourne.
L'en-tête conexio-agent
Un seul en-tête, qui regroupe les réponses sous forme de clés :
conexio-agent: app=IES, ver="3.2.0.1000", intent=import-data
| Clé | Question | Statut | Contenu | Exemple |
|---|---|---|---|---|
app | quel logiciel ? | recommandé | jeton court et stable, propre à l'application | app=IES |
module | quelle partie du logiciel ? | facultatif | le composant ou la bibliothèque qui fait l'appel, quand le logiciel en a plusieurs | module=AutotaskAPI |
ver | quelle version ? | recommandé | la version du logiciel, telle qu'il la connaît | ver="3.2.0.1000" |
intent | pourquoi ? | recommandé | un jeton par fonctionnalité (pas par requête) | intent=import-data |
user | qui est au volant ? | facultatif : seulement si l'application connaît l'utilisateur | un identifiant | user=support:simon |
Le minimum utile est app + ver + intent, plus l'en-tête traceparent.
Rien n'est obligatoire : la plateforme ne refuse jamais une requête à cause de ces en-têtes. Ce
que vous y gagnez, c'est d'être retrouvable par le support.
Format
conexio-agent suit le format dictionnaire des champs structurés HTTP
(RFC 8941) :
- des paires
clé=valeurséparées par une virgule et une espace, dans l'ordreapp,module,ver,intent,user; - une valeur qui commence par une lettre et ne contient que des lettres, des chiffres et
_-.:/%*s'écrit telle quelle (intent=import-data) ; - toute autre valeur s'écrit entre guillemets, avec
"et\échappés par un\: c'est le cas d'une version, qui commence par un chiffre (ver="3.2.0.1000"), ou d'un identifiant qui contient un@(user="george@client.ca").
Une clé que le lecteur ne connaît pas est ignorée : de nouvelles clés pourront s'ajouter sans rien casser chez vous ni chez nous.
Règles de valeur
- ASCII seulement, pas de retour de ligne, 64 caractères au plus par valeur. Nettoyez la
valeur avant de l'envoyer plutôt que de compter sur le serveur : repliez les accents
(
é→e) et remplacez les espaces par des tirets (« créer facture » →creer-facture). - Jamais une valeur vide : si vous ne savez pas, omettez la clé. C'est le cas typique de
userpour un service sans utilisateur ou un complément qui ne voit pas la personne connectée. Si vous ne savez même pasapp, n'envoyez pas l'en-tête. - Le nom de l'en-tête est insensible à la casse, comme tout en-tête HTTP.
app: un nom fixe par logiciel, pas par installation ni par client. Nos propres applications utilisent des valeurs réservées :IES,SyncEngine,ClientPortal,PowerBI,WooCommerce,Therefore,AgentService,OnlineERPBackend. Pour la vôtre, choisissez un nom court et stable et gardez-le d'une version à l'autre.intent: un vocabulaire à vous, stable, qui nomme la fonctionnalité en cours (« importer les clients », « synchroniser les factures »), pas la requête ni l'entité. La valeur change quand la fonctionnalité change, pas à chaque appel. Ce n'est pas un texte libre : pas de phrase, pas de description.user: l'identifiant que l'utilisateur vous a donné pour cette application, ou un identifiant interne (support:simonpour une personne du support). Jamais un mot de passe.
Le construire
const jeton = /^[A-Za-z*][A-Za-z0-9_\-.:%*/]*$/;
const valeur = (v) => (jeton.test(v) ? v : `"${v.replace(/[\\"]/g, "\\$&")}"`);
const conexioAgent = (cles) =>
Object.entries(cles)
.filter(([, v]) => v) // jamais de valeur vide : la clé est omise
.map(([k, v]) => `${k}=${valeur(v)}`)
.join(", ");
conexioAgent({ app: "IES", ver: "3.2.0.1000", intent: "import-data" });
// → 'app=IES, ver="3.2.0.1000", intent=import-data'
User-Agent est déjà occupé par les bibliothèques HTTP et un navigateur ou un webview interdit
de le modifier depuis fetch : il ne peut pas porter une identité fiable. D'où un en-tête
dédié. Un seul plutôt qu'un par question : ajouter une clé plus tard ne touche ni la
documentation des en-têtes, ni l'infrastructure, ni les lecteurs existants. Pas de préfixe X- :
cette convention est dépréciée depuis la RFC 6648.
traceparent : relier tous les appels d'une même opération
traceparent est l'en-tête standard du W3C Trace Context.
Il reste un en-tête à part, hors de conexio-agent : on l'utilise tel quel plutôt qu'un
identifiant maison, parce que les piles .NET le lisent et le propagent nativement, et que
n'importe quel outil de traçage (OpenTelemetry, APM) s'y branche sans adaptateur.
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
│ │ │ │
│ trace-id (32 hex) parent-id (16 hex) flags
version
| Partie | Longueur | Ce que c'est |
|---|---|---|
version | 2 caractères | toujours 00 |
trace-id | 32 caractères hexadécimaux (16 octets) | le lot : un identifiant par opération logique — un clic « Importer », une synchronisation, un traitement de nuit. Toutes les requêtes de l'opération portent le même trace-id, y compris chaque page d'une pagination. |
parent-id | 16 caractères hexadécimaux (8 octets) | la requête : un identifiant neuf à chaque requête HTTP (souvent appelé span-id). |
flags | 2 caractères | 01 (sampled) : vous demandez que la trace soit conservée. |
Règles : hexadécimal minuscule seulement, longueurs exactes, et jamais un identifiant composé uniquement de zéros (invalide selon le W3C : il serait ignoré).
Le générer
- .NET : rien à coder pour le transport. Démarrez une
Activityau début de l'opération ;HttpClientajoute alorstraceparentlui-même à chaque requête, avec le trace-id de l'activité et un identifiant neuf par appel (propagation W3C par défaut depuis .NET 5). - JavaScript, ou toute autre pile : 16 octets aléatoires pour le trace-id, 8 pour le
parent-id, en hexadécimal minuscule, assemblés avec
00-devant et-01derrière. Prenez une source aléatoire correcte (crypto.getRandomValues,RandomNumberGenerator…), tirez le trace-id une fois par opération et le parent-id à chaque requête.
const hex = (n) => Array.from(crypto.getRandomValues(new Uint8Array(n)), (b) => b.toString(16).padStart(2, "0")).join("");
const traceId = hex(16); // une fois par opération (un lot)
const traceparent = () => `00-${traceId}-${hex(8)}-01`; // à chaque requête
Le journaliser chez vous : c'est ce qui rend le support possible
Écrivez le trace-id dans votre journal au début de chaque opération (« Début de l'importation — trace 4bf92f3577b34da6a3ce929d0e0e4736 »). Quand un utilisateur vous signale un problème, vous retrouvez la ligne, vous nous transmettez le trace-id, et il désigne exactement les appels du lot. Sans ce pas, le trace-id voyage mais personne ne peut le retrouver.
Exemple complet d'un appel
Une requête d'importation de clients envoyée par Solution IES, avec l'authentification habituelle et la carte d'identité (clé factice) :
GET /api/Entity/Customer?$top=100 HTTP/1.1
Host: gateway.conexio.dev
Authorization: Basic base64(CODE_LICENCE:api_key_xxxxxxxx)
COMPANY_CODE: PROD_01
conexio-agent: app=IES, ver="3.2.0.1000", intent=import-data
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
La page suivante de la même importation garde le même trace-id et prend un parent-id
neuf ; conexio-agent ne change pas :
GET /api/Entity/Customer?$top=100&$skip=100 HTTP/1.1
Host: gateway.conexio.dev
Authorization: Basic base64(CODE_LICENCE:api_key_xxxxxxxx)
COMPANY_CODE: PROD_01
conexio-agent: app=IES, ver="3.2.0.1000", intent=import-data
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-3c1f0a8e5b7d9a24-01
La même première requête avec curl :
curl 'https://gateway.conexio.dev/api/Entity/Customer?$top=100' \
-u 'CODE_LICENCE:api_key_xxxxxxxx' \
-H 'COMPANY_CODE: PROD_01' \
-H 'conexio-agent: app=IES, ver="3.2.0.1000", intent=import-data' \
-H 'traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01'
Pas de clé user dans cet exemple : Solution IES ne connaît pas l'utilisateur d'Excel et
omet donc la clé, plutôt que de l'envoyer vide.
Ce que fait Solution IES (implémentation de référence)
Le complément Excel Solution IES envoie la carte d'identité ainsi :
| Clé ou en-tête | Ce qu'envoie Solution IES |
|---|---|
app | IES |
ver | la version du complément |
intent | la fenêtre en cours, déduite du nom de sa page : import-data, import_gl_transactions, verify_gl_accounts… |
user | omise — Excel n'expose pas l'utilisateur, la clé n'est jamais envoyée vide |
traceparent | un trace-id par importation (créé au lancement — bouton « Importer les données » —, libéré à la fin), un parent-id neuf à chaque requête, pages de pagination comprises |
- Les valeurs sont nettoyées avant l'envoi (caractères permis, 64 caractères au plus).
- Le trace-id est écrit dans le journal du classeur (table
IES_LOG, onglet cachéIESDATA_LOG) sur la ligne « Début de l'importation … - trace … ». Pour le support : demander le classeur, lire le trace-id, le croiser avec les journaux de la plateforme.
Ce que la plateforme en fait
La passerelle. Les en-têtes la traversent et arrivent à l'API : rien n'est filtré, rien
n'est validé, rien n'est rejeté — une valeur absente ou mal formée n'a aucun effet sur la
réponse. La passerelle inscrit conexio-agent dans son journal à chaque appel (ou « aucun »
quand l'en-tête manque), sur la même ligne que le trace-id reçu dans traceparent : un
trace-id que vous nous transmettez retrouve les appels du lot.
Prochainement. L'API lira aussi conexio-agent et le conservera avec chaque tâche ; les
statistiques d'usage par application et par version en découleront.
Les envoyer dès maintenant a un intérêt immédiat : les versions de votre application déjà déployées chez vos clients sont identifiées dès qu'elles passent la passerelle, et votre propre journal porte déjà le trace-id.
Voir aussi
- S'authentifier à l'API — Basic Auth et le header
COMPANY_CODE, qui restent la seule autorisation. - Composer une requête —
$select,$orderby,$expand. - Tester l'API dans votre outil — Postman, Apidog, Insomnia… ; ajoutez-y les en-têtes pour reproduire fidèlement les appels de votre application.
- Dépannage — problèmes fréquents.
- RFC 8941 — les champs structurés HTTP, format de
conexio-agent. - W3C Trace Context — la spécification de
traceparent.