Les releases dans Codenica API
Pour travailler avec les releases via Codenica API, commencez par créer une clé dans les paramètres de Codenica. Si aucune clé n'a encore été créée, ouvrez dans un nouvel onglet Codenica API - introduction. Vous y trouverez les règles communes relatives à l'émission des clés, au stockage du secret et à l'authentification.
Le nom technique du module est releases et le type d'un objet individuel est release. Une release décrit la publication ou la mise en production planifiée de changements dans un environnement informatique. En plus des données descriptives, elle possède son propre groupe de champs pour la préparation du build, les tests, leurs résultats et le plan de mise en production.
Les sections suivantes présentent l'adresse, les scopes, le schéma, les listes, le filtrage, la création, la modification, les ETag, les opérations batch, les relations, les utilisateurs, les fichiers, les actions de workflow, les approbations et la suppression des releases.
Les exemples utilisent l'identifiant PUBLIC-API-RELEASE-20260905133117. Remplacez-le par votre propre identifiant et adaptez les adresses e-mail, les identifiants et les valeurs des champs aux données de votre base.
Releases - adresse de l'API et choix de l'installation
Toutes les routes relatives aux releases commencent par :
{BASE_URL}/api/v1/releasesAvec Codenica Cloud, utilisez l'adresse publique attribuée à la base concernée :
export BASE_URL="https://votre-entreprise.codenica.com"Dans l'installation On-Premise par défaut, l'adresse enregistrée localement par Codenica Discovery est :
export BASE_URL="http://codenica.local:5150"Si l'administrateur a publié l'installation sous le domaine de l'entreprise, via un reverse proxy, avec HTTPS ou sur un autre port, utilisez l'adresse exacte communiquée pour cette installation :
export BASE_URL="https://api.votre-entreprise.example"N'utilisez pas localhost lorsque le programme d'intégration s'exécute sur un autre ordinateur que l'API. N'envoyez pas tenantId dans le body ni dans la query string. La bonne base est sélectionnée à partir de l'adresse utilisée par l'intégration.
Releases - clé API et limites de licence
Créez une clé API dans Codenica, dans Paramètres - API - API Keys. Le secret n'est affiché qu'une seule fois, immédiatement après la création ou la rotation de la clé. Enregistrez alors le Client ID et le Client Secret dans le stockage sécurisé utilisé par l'intégration.
Codenica API est disponible avec les licences Plus et Enterprise. Plus permet de créer jusqu'à 50 clés actives et Enterprise jusqu'à 100. Starter ne donne pas accès à Codenica API. Créez une clé distincte pour chaque application et chaque environnement afin de gérer séparément ses scopes, la rotation de son secret et son accès.
Les clés expirées ou inactives restent visibles jusqu'à l'utilisation de l'option Supprimer, mais elles ne consomment pas de place active dans la limite. La suppression d'une clé est définitive. Si vous ne définissez pas de date de fin, la période d'activité par défaut est de 90 jours et la période maximale d'une clé est de 5 ans.
Releases - authentification et requêtes sécurisées
Authentifiez chaque requête Codenica API avec les deux en-têtes de la clé :
export CLIENT_ID="cna_votre_client_id"
export CLIENT_SECRET="cns_votre_client_secret"
curl --request GET --url "$BASE_URL/api/v1/releases?page=1&pageSize=25" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Une intégration externe n'a pas besoin du JWT de l'administrateur ni des cookies du panneau Codenica. Ne placez pas la clé dans un dépôt, dans du code livré au navigateur, dans une URL, dans l'historique des commandes ou dans les journaux. En dehors des tests locaux, utilisez HTTPS.
Conservez meta.requestId dans la réponse. Il permet d'analyser une requête précise, mais ne remplace pas l'identifiant de la release et ne doit pas être utilisé comme secret.
Releases - vérifier le contexte de la connexion
Lisez le contexte avant la première écriture. Vous pourrez ainsi vérifier que l'adresse mène à la bonne base et que la clé choisie possède les scopes nécessaires :
curl --request GET --url "$BASE_URL/api/v1/context" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Vérifiez dans la réponse :
data.apiVersionetdata.contractVersion;data.tenant.id,data.tenant.nameetdata.tenant.resolvedDomain;data.caller.authenticationégal àapi_key;- la présence de
releasesdansdata.capabilities.resources; - les scopes attribués à la clé ;
- les limites de pagination, de batch, de fichiers et de requêtes.
Si le contexte indique une autre base ou ne contient pas un scope nécessaire, arrêtez l'intégration et corrigez l'adresse ou la clé. Les scopes ne peuvent pas être accordés par une requête individuelle.
Releases - scopes d'autorisation
Choisissez les scopes de la clé en fonction des opérations que l'intégration doit effectuer. La prise en charge complète des releases peut utiliser l'ensemble suivant :
releases:read
releases:write
releases:delete
releases:schema
releases:stats
releases:relationships:read
releases:relationships:write
releases:users:read
releases:users:write
releases:files:read
releases:files:write
releases:technical:read
releases:technical:write
releases:pin:write
releases:spam:write
releases:reopen:write
releases:rating:write
releases:escalation:write
releases:approval:writePour une lecture ordinaire, releases:read est nécessaire. Le schéma et les statistiques nécessitent respectivement releases:schema et releases:stats. Les relations, les utilisateurs et les fichiers disposent de scopes de lecture et d'écriture distincts. Les actions pin, spam, reopen, rating, escalation et approval nécessitent leurs propres scopes opérationnels.
Une relation avec un autre objet nécessite également l'accès en lecture au module indiqué, par exemple assets:read, documents:read, tickets:read ou notes:read. Accordez les scopes selon le principe du moindre privilège.
Releases - schéma et champs de planification
Le schéma indique quels champs peuvent être lus et écrits dans une base donnée. Récupérez-le avant de préparer un formulaire ou une correspondance de champs :
curl --request GET --url "$BASE_URL/api/v1/releases/schema" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Pour chaque champ, vérifiez notamment readable, writable, required, technical, unique et maxLength. Le schéma renvoie également les dictionnaires, les cibles de relations disponibles et les actions.
À ce jour, l'écriture minimale d'une release exige les champs subject et requesterEmail. Les releases disposent d'un groupe supplémentaire de champs décrivant la préparation et le plan de mise en production :
datePlannedStartdatePlannedEndbuildPlantestPlantestResultsimplementationPlanTransmettez les champs de date au format ISO 8601. Ne copiez pas dans une requête de release les champs de diagnostic de problems ni les champs financiers d'autres modules. Comparez toujours le payload avec le schéma Releases.
Releases - endpoints essentiels
Les routes de release les plus utilisées sont les suivantes :
GET /api/v1/releases- liste des releases ;GET /api/v1/releases/{id}- une release ;POST /api/v1/releases- création ;PATCH /api/v1/releases/{id}- modification partielle ;DELETE /api/v1/releases/{id}- suppression ;GET /api/v1/releases/schema- schéma des champs et des relations ;GET /api/v1/releases/stats- statistiques ;GET /api/v1/releases/values- valeurs utilisées par les filtres ;POST /api/v1/releases:batch- opérations de création, de modification et de suppression.
Les relations, les utilisateurs, les fichiers, les actions de workflow et les approbations possèdent leurs propres routes. L'intégration peut ainsi recevoir uniquement les autorisations dont elle a réellement besoin.
Releases - liste et pagination
Récupérez la liste page par page. Même pour un petit nombre d'enregistrements, indiquez explicitement le numéro et la taille de la page :
curl --request GET --url "$BASE_URL/api/v1/releases?page=1&pageSize=25" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La réponse contient data.items ainsi que page, pageSize, totalItems, totalPages et hasNextPage. Récupérez les pages suivantes tant que hasNextPage vaut true :
curl --request GET --url "$BASE_URL/api/v1/releases?page=2&pageSize=25&sort=dateUpdated&direction=desc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Pour une synchronisation, le tri par dateUpdated et la mémorisation des derniers enregistrements traités sont généralement les plus pratiques. Ne définissez pas pageSize au-dessus de la limite renvoyée dans le contexte.
Releases - recherche, filtres et tri
Vous pouvez combiner les paramètres de la liste. L'exemple suivant recherche une release par son identifiant d'intégration, limite le résultat au type release et à un statut, sélectionne les champs puis trie selon la date de modification :
curl --get --url "$BASE_URL/api/v1/releases" \
--data-urlencode "itemType=release" \
--data-urlencode "customId=PUBLIC-API-RELEASE-20260905133117-SOURCE" \
--data-urlencode "status=Closed" \
--data-urlencode "sort=dateUpdated" \
--data-urlencode "direction=desc" \
--data-urlencode "page=1" \
--data-urlencode "pageSize=25" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Pour la synchronisation quotidienne, les paramètres search, status, priority, subject, requesterEmail, source, externalNumber, referenceNumber, createdAfter, createdBefore, updatedAfter et updatedBefore sont également utiles lorsqu'ils sont disponibles dans le schéma actuel.
Un filtre structuré utilise le format field:operator:value. Les opérateurs disponibles sont eq, ne, in, contains, startsWith, endsWith, empty, notEmpty, gt, gte, lt et lte :
curl --get --url "$BASE_URL/api/v1/releases" \
--data-urlencode "filter=status:eq:Closed" \
--data-urlencode "filter=buildPlan:contains:package" \
--data-urlencode "page=1" \
--data-urlencode "pageSize=25" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Encodez les valeurs textuelles et les dates conformément aux règles des URL. Ne supposez pas que les dictionnaires sont identiques dans deux bases.
Releases - sélectionner les champs et inclure les données
Le paramètre fields limite la réponse aux champs nécessaires à l'intégration. Le paramètre include ajoute les données liées :
curl --get --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--data-urlencode "fields=subject,requesterEmail,status,priority,datePlannedStart,datePlannedEnd,buildPlan,testPlan,testResults,implementationPlan" \
--data-urlencode "include=files,relationships,users" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Pour lire le modèle complet, vous pouvez utiliser fields=*. L'inclusion des fichiers, des relations et des utilisateurs nécessite les scopes de lecture correspondants. fields ne contourne ni le contrôle d'accès ni la protection des champs techniques pour lesquels la clé n'a pas d'autorisation.
Dans la réponse, prêtez attention à data.id, data.itemType, data.attributes et data.meta. Lisez les champs techniques comme pin ou isSpam, mais modifiez-les avec les actions dédiées décrites plus loin.
Releases - statistiques et valeurs des dictionnaires
Les statistiques permettent par exemple de vérifier la répartition des releases par statut. Il s'agit d'une opération de lecture qui ne modifie pas les enregistrements :
curl --get --url "$BASE_URL/api/v1/releases/stats" \
--data-urlencode "field=status" \
--data-urlencode "limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Récupérez séparément les valeurs du champ buildPlan lorsque vous devez construire des suggestions ou des filtres :
curl --get --url "$BASE_URL/api/v1/releases/values" \
--data-urlencode "field=buildPlan" \
--data-urlencode "limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Récupérez d'abord le dictionnaire, puis envoyez la valeur choisie dans le body. C'est particulièrement important pour status, priority, type et les champs de planification configurés dans la base concernée.
Releases - créer un enregistrement
Créez une release avec POST /api/v1/releases. Placez le type technique release dans le body et les champs inscriptibles dans attributes. L'exemple contient des données descriptives, la classification, les identifiants d'intégration et tout le groupe de planification :
curl --request POST --url "$BASE_URL/api/v1/releases" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-release-create-20260905133117" \
--data-raw '{
"itemType": "release",
"attributes": {
"customId": "PUBLIC-API-RELEASE-20260905133117-SOURCE",
"subject": "Release d'intégration Codenica API",
"requesterEmail": "[email protected]",
"description": "Release créée par l'intégration Codenica Public API.",
"comments": "Exemple de plan de mise en production pour le module Releases.",
"source": "Public API",
"type": "Standard",
"status": "Closed",
"priority": "High",
"impact": "Medium",
"urgency": "High",
"severity": "High",
"services": "Codenica Public API",
"tags": "public-api,release",
"externalNumber": "EXT-PUBLIC-API-RELEASE-20260905133117",
"referenceNumber": "REF-PUBLIC-API-RELEASE-20260905133117",
"datePlannedStart": "2026-09-05T08:00:00Z",
"datePlannedEnd": "2026-09-05T10:00:00Z",
"buildPlan": "Préparation du package de release.",
"testPlan": "Tests fonctionnels avant la mise en production.",
"testResults": "Tests de démonstration terminés avec succès.",
"implementationPlan": "Déploiement progressif avec possibilité de retour en arrière."
},
"customValues": [
{
"name": "description",
"valuePattern": "[release-integration] PUBLIC-API-RELEASE-20260905133117"
}
]
}'Le minimum correspond à subject et requesterEmail, sauf si le schéma impose des exigences supplémentaires. Après la création, enregistrez data.id et l'ETag renvoyé dans l'en-tête ainsi que dans data.meta.etag. Le secret de la clé ne fait pas partie de la réponse de la release.
Releases - relancer la création en toute sécurité
Si le résultat d'une requête est incertain, répétez exactement le même payload avec le même Idempotency-Key. L'intégration ne créera ainsi pas une seconde release :
curl --request POST --url "$BASE_URL/api/v1/releases" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-release-create-20260905133117" \
--data-binary @release.jsonUtilisez la même clé uniquement pour la même intention et le même body. Générez une nouvelle clé pour une nouvelle release ou un nouveau payload. Après un timeout, ne changez pas la clé avant d'avoir vérifié que la première écriture s'est terminée sur le serveur.
Releases - lire un enregistrement et son ETag
Lisez une release avec tous ses champs et les données incluses :
curl --get --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--data-urlencode "fields=*" \
--data-urlencode "include=files,relationships,users" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Conservez l'ETag de l'en-tête de réponse. Il doit correspondre à data.meta.etag et à meta.etag dans l'enveloppe de réponse. Après chaque écriture, action, modification de relation ou opération sur un fichier, récupérez ou relisez le nouvel ETag.
Un ETag représente la version d'une release précise. N'utilisez pas l'ETag lu pour une release afin d'en modifier une autre.
Releases - modifier avec If-Match
Les modifications sont partielles. Envoyez uniquement les champs à changer et placez l'ETag actuel dans l'en-tête If-Match :
curl --request PATCH --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-update-20260905133117" \
--data-raw '{
"attributes": {
"description": "Description mise à jour par l'intégration.",
"status": "Closed",
"priority": "High",
"datePlannedStart": "2026-09-05T09:00:00Z",
"datePlannedEnd": "2026-09-05T11:00:00Z",
"buildPlan": "Plan de préparation du package mis à jour.",
"testPlan": "Scénario de test mis à jour.",
"testResults": "Résultats des tests après correction.",
"implementationPlan": "Plan de mise en production mis à jour."
}
}'Un If-Match valide renvoie HTTP 200 et un nouvel ETag. N'envoyez pas dans un PATCH ordinaire des champs en lecture seule ni des champs techniques gérés par des actions dédiées.
Releases - gérer un If-Match obsolète
Une release peut être modifiée simultanément depuis le panneau ou par une autre intégration. L'API la protège contre les écrasements accidentels :
curl --request PATCH --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "ancien-etag"' \
--header "Idempotency-Key: public-api-release-stale-update-20260905133117" \
--data-raw '{"attributes":{"description":"Cette modification nécessite une nouvelle lecture."}}'- 428 Precondition Required avec le code
if_match_requiredsignifie que l'en-têteIf-Matchrequis est absent. - 412 Precondition Failed avec le code
if_match_failedsignifie que l'ETag fourni n'est plus actuel.
Une requête rejetée ne doit pas modifier la release. Après HTTP 412, relisez l'enregistrement, récupérez le nouvel ETag et décidez si vous souhaitez recommencer la modification. N'écrasez pas sans contrôle les changements effectués par une autre personne ou un autre processus.
Releases - opérations batch
L'endpoint batch permet de traiter plusieurs éléments indépendants dans une seule requête. L'exemple suivant crée deux releases :
curl --request POST --url "$BASE_URL/api/v1/releases:batch" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-release-batch-create-20260905133117" \
--data-raw '{
"items": [
{
"operation": "create",
"create": {
"itemType": "release",
"attributes": {
"customId": "PUBLIC-API-RELEASE-20260905133117-BATCH-A",
"subject": "Release batch A",
"requesterEmail": "[email protected]",
"source": "Public API",
"type": "Standard",
"status": "Open",
"priority": "Medium",
"datePlannedStart": "2026-09-05T11:00:00Z",
"datePlannedEnd": "2026-09-05T12:00:00Z",
"buildPlan": "Plan de build de la release A",
"testPlan": "Plan de test de la release A",
"testResults": "Résultats des tests de la release A",
"implementationPlan": "Plan de mise en production de la release A"
}
}
},
{
"operation": "create",
"create": {
"itemType": "release",
"attributes": {
"customId": "PUBLIC-API-RELEASE-20260905133117-BATCH-B",
"subject": "Release batch B",
"requesterEmail": "[email protected]",
"source": "Public API",
"type": "Standard",
"status": "Open",
"priority": "Low",
"datePlannedStart": "2026-09-05T13:00:00Z",
"datePlannedEnd": "2026-09-05T14:00:00Z",
"buildPlan": "Plan de build de la release B",
"testPlan": "Plan de test de la release B",
"testResults": "Résultats des tests de la release B",
"implementationPlan": "Plan de mise en production de la release B"
}
}
}
]
}'Vérifiez la réponse batch élément par élément. Ne considérez pas HTTP 200 comme la preuve de la réussite de chaque élément. Contrôlez succeeded, failed, les identifiants et les erreurs de chaque élément.
La modification et la suppression utilisent le même endpoint :
{
"items": [
{
"operation": "update",
"id": "{RELEASE_ID}",
"ifMatch": "\"{CURRENT_ETAG}\"",
"update": {
"attributes": {
"datePlannedStart": "2026-09-05T09:30:00Z",
"buildPlan": "Plan de préparation du package mis à jour"
}
}
},
{
"operation": "delete",
"id": "{OTHER_RELEASE_ID}",
"ifMatch": "\"{OTHER_CURRENT_ETAG}\""
}
]
}Pour une modification ou une suppression, utilisez l'ETag lu pour l'enregistrement concerné. La clé d'idempotence identifie toute la requête batch, et non un élément individuel. Un batch n'est pas une transaction : traitez donc le résultat de chaque élément séparément.
Releases - relations avec les objets
Les cibles de relations disponibles sont renvoyées par /api/v1/releases/schema. Le schéma peut notamment indiquer les collections assets, documents, changes, tickets, problems, releases, notes, approvals, worktasks et requesteditems.
La présence d'une cible dans le schéma ne signifie pas qu'un enregistrement utilisable existe dans la base actuelle. Avant d'ajouter une relation, vérifiez les autorisations, l'identifiant cible et son itemType. Pour assets, documents, tickets, changes, problems et releases, utilisez le type de relation renvoyé par le schéma, par exemple related. Pour notes, approvals, worktasks et requesteditems, relationshipType peut être null. Ne forcez pas related lorsque le schéma ne le précise pas.
Ajouter plusieurs relations avec batch :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/relationships:batch" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-relationship-batch-20260905133117" \
--data-raw '{
"add": [
{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
},
{
"targetId": "{DOCUMENT_ID}",
"targetDataSet": "documents",
"targetItemType": "document",
"relationshipType": "related"
},
{
"targetId": "{NOTE_ID}",
"targetDataSet": "notes",
"targetItemType": "note",
"relationshipType": null
}
],
"remove": []
}'La réponse HTTP 200 contient les compteurs added, removed et skipped. Après l'opération, récupérez la collection des relations et vérifiez que le résultat correspond à ce qui était attendu.
Releases - lire et supprimer des relations
Récupérez la collection des relations avec sa route dédiée :
curl --request GET --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/relationships?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Vous pouvez ajouter une relation sans batch, puis la supprimer avec l'ETag actuel :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/relationships" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-relationship-20260905133117" \
--data-raw '{"targetId":"{TICKET_ID}","targetDataSet":"tickets","targetItemType":"ticket","relationshipType":"related"}'
curl --request DELETE --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/relationships/tickets/{TICKET_ID}?relationshipType=related" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-relationship-delete-20260905133117"Si le schéma renvoie relationshipType: null pour une cible, omettez le paramètre relationshipType de la route de suppression. Vous pouvez également supprimer des relations avec une modification partielle de la release :
curl --request PATCH --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-relationship-patch-20260905133117" \
--data-raw '{"relationshipsToRemove":[{"targetId":"{TICKET_ID}","targetDataSet":"tickets","targetItemType":"ticket","relationshipType":"related"}]}'Après une modification des relations, relisez la release ou la collection des relations. L'ETag peut changer ; n'utilisez donc pas l'ancien ETag pour l'action suivante.
Releases - relations avec les utilisateurs
Une release peut posséder les relations utilisateur agent, watcher et appUserRequester. La première désigne la personne responsable du traitement, la deuxième un observateur et la troisième l'utilisateur applicatif qui a soumis la release. N'ajoutez pas de relations qui ne sont pas renvoyées par le schéma.
Attribuer un agent :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/user-relationships" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-agent-20260905133117" \
--data-raw '{"targetId":"{USER_ID}","targetDataSet":"users","relationshipType":"agent"}'Ajouter un observateur avec batch :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/user-relationships:batch" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-watcher-20260905133117" \
--data-raw '{"add":[{"targetId":"{WATCHER_ID}","targetDataSet":"users","relationshipType":"watcher"}],"remove":[]}'Lire et supprimer des relations :
curl --request GET --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/user-relationships?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"
curl --request DELETE --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/user-relationships/users/{USER_ID}?relationshipType=agent" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-agent-delete-20260905133117"Vous pouvez également supprimer un watcher via user-relationships:batch en envoyant un tableau add vide et une entrée dans remove. Relisez le nouvel ETag après chaque modification.
Releases - fichiers
Avant toute opération sur un fichier, relisez la release actuelle et son ETag. L'envoi d'un fichier nécessite le format multipart/form-data :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/files?relationshipType=documentation" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-file-20260905133117" \
--form "[email protected];type=text/plain"Liste des fichiers et téléchargement du contenu :
curl --request GET --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/files?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"
curl --request GET --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/files/{FILE_ID}/content" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--output release-evidence.txtUn élément de la liste contient notamment id, name, fileName, contentType, size, relationshipType, isMain et downloadUrl. Considérez downloadUrl comme un chemin d'API et non comme un lien public anonyme.
Vous pouvez rattacher un fichier existant à une autre release, puis supprimer sa relation :
curl --request POST --url "$BASE_URL/api/v1/releases/{OTHER_RELEASE_ID}/files/{FILE_ID}?relationshipType=manual" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{OTHER_RELEASE_CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-file-attach-20260905133117"
curl --request DELETE --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/files/{FILE_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-file-delete-20260905133117"Avant la suppression, vérifiez la release, le fileId et l'ETag actuel. Obtenez la limite de taille dans le contexte. Ne chargez pas un fichier en mémoire avant d'avoir vérifié cette limite.
Releases - épinglage, spam et réouverture
Les actions de workflow disposent d'endpoints distincts. Ne les remplacez pas par un PATCH ordinaire lorsque l'API fournit une action dédiée. Chacune nécessite l'ETag actuel et sa propre clé d'idempotence.
Épingler une release et la marquer comme spam :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/pin" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-pin-20260905133117" \
--data-raw '{"pin":2}'
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/spam" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-spam-on-20260905133117" \
--data-raw '{"isSpam":true}'Pour annuler le marquage spam, envoyez {"isSpam":false} sur la même route. Rouvrez une release ainsi :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/reopen" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-reopen-20260905133117"Les actions peuvent modifier l'ETag. Après chacune d'elles, lisez la réponse et la release actuelle avant de lancer l'action suivante.
Releases - évaluation et escalade
Une évaluation peut transmettre un retour et enregistrer en même temps une demande d'escalade :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/rating" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-rating-20260905133117" \
--data-raw '{
"rating": 4,
"feedback": "Évaluation envoyée par une intégration Public API.",
"isEscalationRequested": true,
"escalationRequestReason": "La release nécessite l'analyse de l'équipe de deuxième niveau."
}'Pour une simple évaluation, vous avez besoin de releases:rating:write ; une demande d'escalade nécessite également releases:escalation:write. Après l'opération, relisez la release et vérifiez les champs d'évaluation et d'escalade enregistrés. Ne supposez pas que HTTP 200 signifie à lui seul que toutes les valeurs ont été sauvegardées.
Releases - approbation et décision
Une approbation est un objet distinct qui peut être lié à une release. Sa création nécessite les scopes du module approvals et releases:approval:write :
curl --request POST --url "$BASE_URL/api/v1/approvals" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-release-approval-create-20260905133117" \
--data-raw '{
"itemType": "approval",
"approverId": "{APPROVER_USER_ID}",
"attributes": {
"customId": "PUBLIC-API-RELEASE-20260905133117-APPROVAL",
"category": "Public API",
"description": "Approbation du plan de release."
},
"relationships": [
{
"targetId": "{RELEASE_ID}",
"targetDataSet": "releases",
"targetItemType": "release"
}
]
}'Après la création, lisez l'approbation avec son endpoint, puis enregistrez la décision avec l'endpoint de la release :
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/approvals/{APPROVAL_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-approval-decision-20260905133117" \
--data-raw '{"approve":true,"remark":"Le plan de release a été approuvé par l'intégration Public API."}'Après la décision, relisez l'approbation et vérifiez son statut ou dateApproved. Vous confirmerez ainsi que la décision a été enregistrée, et pas seulement que le serveur a accepté la requête.
Releases - supprimer un enregistrement
La suppression nécessite l'ETag actuel et une clé d'idempotence :
curl --request DELETE --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-delete-20260905133117"Après HTTP 200, effectuez un GET de vérification. La release supprimée doit renvoyer HTTP 404 avec le code release_not_found ou l'équivalent indiqué dans le contrat. Si l'objet possède des relations ou des fichiers, vérifiez les conséquences dans le schéma et dans la politique de votre base avant de le supprimer.
Releases - erreurs, limites et sécurité
Les réponses réussies renvoient les données dans data ; les informations techniques comme requestId et parfois l'ETag apparaissent dans meta. Les erreurs utilisent le format Problem Details avec status, code, detail et requestId.
400- body, paramètre ou valeur de champ invalide ;401- authentification absente ou invalide ;403- scope manquant ou accès à la base refusé ;404- la release, le fichier ou la cible de relation n'existe pas ou n'est pas visible ;409- conflit de données ou d'idempotence ;412- ETag obsolète ;413- upload ou body trop volumineux ;428- ETag ou Idempotency-Key requis ;429- limite de requêtes dépassée ;500ou503- erreur du serveur ou indisponibilité temporaire.
Respectez les limites renvoyées dans le contexte pour pageSize, les éléments batch, les fichiers, les relations et le rate limit. Lisez X-RateLimit-Limit, X-RateLimit-Remaining et, pour 429, Retry-After. Utilisez des relances contrôlées avec un délai croissant.
Pour les opérations qui modifient les données, utilisez toujours un Idempotency-Key unique, l'If-Match actuel lorsque l'endpoint l'exige et le nouvel ETag après une modification réussie. Après un timeout, reconstituez d'abord le résultat avec un GET ou répétez la même requête avec la même clé. Conservez le Client ID et le Client Secret en dehors du code source, ne les écrivez pas dans les journaux et ne les envoyez pas dans des conversations ou des tickets.
Releases - ordre des opérations d'intégration
- Déterminez l'adresse Cloud correcte ou l'adresse réelle de l'installation On-Premise.
- Créez une clé distincte pour l'application et l'environnement dans Paramètres - API - API Keys.
- Accordez uniquement les scopes nécessaires aux releases et aux relations prévues.
- Envoyez
GET /api/v1/contextet vérifiez la base, le caller, les scopes et les limites. - Récupérez
GET /api/v1/releases/schemaet construisez la correspondance des champs. - Récupérez la liste avec pagination, recherche ou filtres.
- Créez une release avec
POSTet un nouvelIdempotency-Key. - Enregistrez l'UUID et l'ETag.
- Avant chaque modification, relisez l'enregistrement actuel et son ETag.
- Effectuez les modifications, relations, opérations sur les fichiers et actions de workflow avec l'ETag concerné et une nouvelle clé d'idempotence.
- Après chaque mutation réussie, enregistrez le nouvel ETag et relisez le résultat.
- Après
412, relisez l'enregistrement, résolvez le conflit et ne relancez l'opération qu'ensuite. - Pour un grand nombre de changements, utilisez batch, mais vérifiez le statut de chaque élément car un batch n'est pas une transaction.
- Pour une approbation, vérifiez son état après la décision.
- Lors de la suppression, utilisez l'ETag actuel et confirmez ensuite HTTP 404 avec un GET.
Ce déroulement permet de synchroniser la planification et la mise en production des releases sans dépendre d'hypothèses fortuites sur les champs, les relations ou l'adresse de l'installation.
