Les problèmes dans Codenica API
Pour travailler avec les problèmes 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 problems et le type d'un objet individuel est problem. Un problème sert à enregistrer la cause ou l'origine d'incidents récurrents. En plus des données descriptives, il comporte les champs de diagnostic isKnown, symptoms, rootCause et impactInfo.
Les sections suivantes présentent l'adresse, les scopes, le schéma, les listes, le filtrage, la création, la modification, l'ETag, les opérations batch, les relations, les utilisateurs, les fichiers, les actions de workflow, l'escalade, l'approbation et la suppression des problèmes.
Les exemples utilisent le préfixe PUBLIC-API-PROBLEM-20260905131727. Dans votre intégration, remplacez-le par votre propre identifiant et adaptez les adresses e-mail, les identifiants et les valeurs de champs aux données de votre base.
Problèmes - adresse de l'API et choix du déploiement
Toutes les routes relatives aux problèmes commencent par :
{BASE_URL}/api/v1/problemsDans Codenica Cloud, utilisez le domaine public attribué à l'installation concernée :
export BASE_URL="https://twoja-firma.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 un domaine d'entreprise, derrière un reverse proxy, avec HTTPS ou sur un autre port, utilisez l'adresse exacte fournie pour cette installation :
export BASE_URL="https://api.twoja-firma.example"N'utilisez pas localhost si l'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 base appropriée est sélectionnée à partir de l'adresse de l'hôte à laquelle l'intégration se connecte.
Problèmes - 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 pouvoir limiter ses scopes, faire tourner son secret ou supprimer son accès indépendamment.
La durée de validité par défaut est de 90 jours si vous ne définissez pas une autre date dans le panneau. La durée maximale est de 5 ans. Les clés expirées ou inactives ne consomment pas de slot actif, mais restent visibles jusqu'à l'utilisation de l'option Supprimer. La suppression de l'enregistrement est définitive.
Problèmes - 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_twoj_client_id"
export CLIENT_SECRET="cns_twoj_client_secret"
curl --request GET --url "$BASE_URL/api/v1/problems?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 de diagnostiquer une requête précise, mais ne remplace pas l'identifiant du problème et ne doit pas être utilisé comme secret.
Problèmes - vérification du contexte de connexion
Récupérez le contexte avant le premier enregistrement. 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"Dans la réponse, vérifiez :
data.apiVersionetdata.contractVersion;data.tenant.id,data.tenant.nameetdata.tenant.resolvedDomain;data.caller.authenticationégal àapi_key;- la présence de
problemsdansdata.capabilities.resources; - les scopes associés à la clé ;
- les limites de pages, de batch, de fichiers et de requêtes.
Si le contexte indique une autre base ou ne contient pas un scope nécessaire, interrompez l'intégration et corrigez l'adresse ou la clé. Les scopes ne peuvent pas être ajoutés à une requête individuelle.
Problèmes - scopes d'autorisation
La prise en charge complète des problèmes nécessite les scopes correspondant aux opérations utilisées :
problems:read
problems:write
problems:delete
problems:schema
problems:stats
problems:relationships:read
problems:relationships:write
problems:users:read
problems:users:write
problems:files:read
problems:files:write
problems:technical:read
problems:technical:write
problems:pin:write
problems:spam:write
problems:reopen:write
problems:rating:write
problems:escalation:write
problems:approval:writePour une simple lecture, problems:read suffit. Le schéma et les statistiques nécessitent les scopes distincts problems:schema et problems:stats. La lecture des relations, des utilisateurs et des fichiers exige les scopes de lecture correspondants. Les opérations d'écriture utilisent les scopes :write associés.
Les relations avec les autres modules nécessitent également l'accès en lecture au module cible, par exemple assets:read, documents:read, tickets:read ou solutions:read. Pour créer une approbation et enregistrer sa décision, ajoutez les scopes requis par le module approvals lui-même. Accordez les scopes selon le principe du moindre privilège.
Problèmes - schéma et champs de diagnostic
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 :
curl --request GET --url "$BASE_URL/api/v1/problems/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 et les cibles de relations disponibles.
Un enregistrement de problème exige actuellement au minimum subject et requesterEmail. Les problèmes disposent de leur propre groupe de diagnostic :
subject, requesterEmail, description, commentstype, status, priority, impact, urgency, severityisKnown, symptoms, rootCause, impactInfosource, services, tags, externalNumber, referenceNumberLes champs pin et isSpam sont techniques et se modifient par des actions dédiées. Les champs système et les champs en lecture seule, notamment les données d'évaluation et d'escalade, ne doivent pas être envoyés dans un PATCH ordinaire. Les problèmes ne prennent pas en charge les champs de coût currency, estimatedCost et totalValue présents dans d'autres modules.
Problèmes - routes principales
Les routes de problèmes les plus utilisées sont les suivantes :
GET /api/v1/problems- liste des problèmes ;GET /api/v1/problems/{id}- problème individuel ;POST /api/v1/problems- création ;PATCH /api/v1/problems/{id}- modification partielle ;DELETE /api/v1/problems/{id}- suppression ;GET /api/v1/problems/schema- schéma des champs et des relations ;GET /api/v1/problems/stats- statistiques ;GET /api/v1/problems/values- valeurs utilisées dans les filtres ;POST /api/v1/problems:batch- opérations de création, de modification et de suppression.
Les relations, les utilisateurs, les fichiers, les actions de workflow et les approbations disposent de routes séparées. L'intégration peut ainsi recevoir uniquement les autorisations dont elle a réellement besoin.
Problèmes - listes et pagination
Récupérez la liste page par page. Même si le nombre d'enregistrements est faible, indiquez explicitement le numéro et la taille de la page :
curl --request GET --url "$BASE_URL/api/v1/problems?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/problems?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-delà de la limite renvoyée dans le contexte.
Problèmes - recherche, filtres et tri
Vous pouvez combiner les paramètres de liste. L'exemple suivant recherche un enregistrement par son identifiant, limite le résultat au type problem et aux problèmes connus, puis le trie par date de mise à jour :
curl --get --url "$BASE_URL/api/v1/problems" \
--data-urlencode "itemType=problem" \
--data-urlencode "customId=PUBLIC-API-PROBLEM-20260905131727-SOURCE" \
--data-urlencode "isKnown=true" \
--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 une synchronisation quotidienne, les paramètres search, status, priority, subject, requesterEmail, source, externalNumber, referenceNumber, symptoms, rootCause, impactInfo, createdAfter, createdBefore, updatedAfter et updatedBefore sont également utiles lorsqu'ils sont disponibles dans le schéma actuel.
Un filtre structurel suit 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/problems" \
--data-urlencode "filter=status:eq:Closed" \
--data-urlencode "filter=rootCause:contains:connection" \
--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 le dictionnaire est identique dans deux bases.
Problèmes - sélection des champs et données incluses
Le paramètre fields limite la réponse aux champs nécessaires à l'intégration. Le paramètre include ajoute les données associées :
curl --get --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--data-urlencode "fields=subject,requesterEmail,status,priority,isKnown,symptoms,rootCause,impactInfo" \
--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 pas le contrôle d'accès et ne révèle pas les champs techniques pour lesquels la clé n'a aucune autorisation.
Dans la réponse, prêtez attention à data.id, data.itemType, data.attributes et data.meta. Lisez les champs techniques tels que pin ou isSpam, mais modifiez-les avec les actions dédiées décrites plus loin.
Problèmes - statistiques et valeurs de dictionnaire
Les statistiques permettent par exemple de compter les problèmes selon le champ isKnown. Il s'agit d'une opération de lecture qui ne modifie pas les enregistrements :
curl --get --url "$BASE_URL/api/v1/problems/stats" \
--data-urlencode "field=isKnown" \
--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 rootCause pour construire des suggestions ou des filtres :
curl --get --url "$BASE_URL/api/v1/problems/values" \
--data-urlencode "field=rootCause" \
--data-urlencode "search=connection" \
--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 dans le body. C'est particulièrement important pour status, priority, type et les champs de diagnostic configurés dans la base concernée.
Problèmes - création d'un enregistrement
Créez un nouveau problème avec POST /api/v1/problems. Placez le type technique problem dans le body et les champs inscriptibles dans attributes. L'exemple contient les données descriptives, la classification, les informations d'intégration et tout le groupe de diagnostic :
export IDEMPOTENCY_KEY="public-api-problem-create-20260905131727"
curl --request POST --url "$BASE_URL/api/v1/problems" \
--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: $IDEMPOTENCY_KEY" \
--data-raw '{
"itemType": "problem",
"attributes": {
"customId": "PUBLIC-API-PROBLEM-20260905131727-SOURCE",
"subject": "Problème d'intégration Codenica API",
"requesterEmail": "[email protected]",
"description": "Problème créé par l'intégration Codenica API.",
"comments": "Exemple de diagnostic pour le module Problems.",
"source": "Codenica API",
"type": "Standard",
"status": "Closed",
"priority": "High",
"impact": "Medium",
"urgency": "High",
"severity": "High",
"services": "Codenica API",
"tags": "codenica-api,problem",
"externalNumber": "EXT-CODENICA-API-PROBLEM-20260905131727",
"referenceNumber": "REF-CODENICA-API-PROBLEM-20260905131727",
"isKnown": true,
"symptoms": "Les utilisateurs ne peuvent pas terminer la synchronisation.",
"rootCause": "Erreur de connexion au service externe.",
"impactInfo": "La synchronisation du groupe de données concerné est retardée."
},
"customValues": [
{
"name": "description",
"valuePattern": "[problem-test] PUBLIC-API-PROBLEM-20260905131727"
}
]
}'Le minimum requis est subject et requesterEmail, sauf si le schéma impose d'autres exigences. Une création réussie renvoie HTTP 201, l'identifiant data.id et un ETag 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 l'objet.
Problèmes - idempotence de la création
La répétition de la même requête avec le même Idempotency-Key doit renvoyer le même résultat logique et non créer un deuxième problème :
curl --request POST --url "$BASE_URL/api/v1/problems" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-problem-create-20260905131727" \
--data-binary @problem.jsonAprès un résultat réseau incertain, vous pouvez répéter la même clé uniquement pour cette même requête. N'utilisez pas une seule clé pour deux opérations différentes. Générez une nouvelle clé pour un nouveau body.
Idempotency-Key est obligatoire pour toute requête qui modifie des données, notamment pour une modification, une relation, un fichier, une action de workflow ou une suppression. La réutilisation de la même clé avec une autre route ou un autre body provoque un conflit d'idempotence.
Problèmes - lecture et ETag
Pour lire un problème individuel avec ses données incluses, utilisez :
curl --get --url "$BASE_URL/api/v1/problems/{PROBLEM_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'un problème précis. N'utilisez pas l'ETag obtenu pour un problème afin d'en modifier un autre.
Problèmes - modification avec If-Match
La modification est partielle. Envoyez uniquement les champs à changer :
curl --request PATCH --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-update-20260905131727" \
--data-raw '{
"attributes": {
"description": "Description mise à jour par l'intégration.",
"status": "Closed",
"priority": "High",
"isKnown": false,
"symptoms": "Symptômes après une nouvelle observation.",
"rootCause": "Analyse actualisée de la cause racine.",
"impactInfo": "Impact après application de la solution de contournement."
}
}'Ne modifiez pas dans un PATCH ordinaire les champs en lecture seule, notamment rating, dateRating, dateFeedback, dateReopened et dateEscalated. L'épinglage, le spam, la réouverture, l'évaluation, l'escalade et l'approbation ont leurs propres endpoints.
Après une modification réussie, vous recevez HTTP 200 et un nouvel ETag. Enregistrez-le avant l'opération suivante.
Problèmes - contrôle d'un If-Match obsolète
Toute mutation, à l'exception de la création, exige l'ETag actuel. L'absence de l'en-tête et une valeur obsolète sont refusées :
curl --request PATCH --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-problem-missing-if-match-20260905131727" \
--data-raw '{"attributes":{"isKnown":false}}'L'absence de If-Match renvoie HTTP 428 avec le code if_match_required. Si vous envoyez un ETag plus ancien, vous recevez HTTP 412 avec le code if_match_failed. Une requête refusée ne doit pas modifier le problème.
Après HTTP 412, récupérez à nouveau l'enregistrement, lisez le nouvel ETag et décidez seulement ensuite s'il est possible de retenter la modification. Ne remplacez pas aveuglément les changements réalisés par un autre utilisateur ou processus.
Problèmes - opérations batch
Le batch sert à traiter plusieurs éléments indépendants. Une requête peut contenir des opérations de create, update et delete :
curl --request POST --url "$BASE_URL/api/v1/problems:batch" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-problem-batch-20260905131727" \
--data-raw '{
"items": [
{
"operation": "create",
"create": {
"itemType": "problem",
"attributes": {
"customId": "PUBLIC-API-PROBLEM-20260905131727-BATCH-A",
"subject": "Problème du batch A",
"requesterEmail": "[email protected]",
"source": "Codenica API",
"type": "Standard",
"status": "Open",
"priority": "Medium",
"isKnown": true,
"symptoms": "Symptômes du problème A",
"rootCause": "Cause racine du problème A",
"impactInfo": "Impact du problème A"
}
}
},
{
"operation": "update",
"id": "PROBLEM_UUID",
"ifMatch": "\"CURRENT_ETAG\"",
"update": {
"attributes": {
"isKnown": false,
"rootCause": "Nouvelle analyse de la cause racine"
}
}
},
{
"operation": "delete",
"id": "OTHER_PROBLEM_UUID",
"ifMatch": "\"OTHER_CURRENT_ETAG\""
}
]
}'Pour les opérations batch update et delete, utilisez l'ETag de l'enregistrement concerné. La clé d'idempotence identifie toute la requête batch et non un élément individuel. Vérifiez la réponse élément par élément, selon son index, son statut, son identifiant et son erreur. Une réussite complète renvoie généralement HTTP 200, tandis qu'un résultat partiel renvoie HTTP 207 Multi-Status. Un batch n'est pas une transaction all-or-nothing.
Problèmes - relations avec des objets
Les cibles de relations disponibles sont renvoyées par /api/v1/problems/schema. Le contrat actuel peut notamment inclure :
assets
documents
changes
tickets
problems
solutions
releases
notes
approvals
worktasks
requesteditemsLa présence d'une cible dans le schéma ne signifie pas qu'un enregistrement accessible existe dans la base concernée. Avant d'ajouter une relation, vérifiez l'identifiant, targetDataSet, targetItemType et l'autorisation de lecture de la cible.
Pour assets, documents, problems, changes, tickets, solutions et releases, utilisez un relationshipType autorisé par le schéma, par exemple related. Pour notes, approvals, worktasks et requesteditems, laissez relationshipType à null. Ne forcez pas related lorsqu'il n'est pas pris en charge.
Ajout de plusieurs relations :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_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: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-relationships-20260905131727" \
--data-raw '{
"add": [
{
"targetId": "ASSET_UUID",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
},
{
"targetId": "DOCUMENT_UUID",
"targetDataSet": "documents",
"targetItemType": "invoice",
"relationshipType": "related"
},
{
"targetId": "NOTE_UUID",
"targetDataSet": "notes",
"targetItemType": "note",
"relationshipType": null
}
],
"remove": []
}'La réponse HTTP 200 contient les compteurs added, removed et skipped. skipped n'est pas une erreur de transport : après l'opération, récupérez donc la collection des relations et vérifiez son contenu.
Problèmes - lecture et suppression des relations
Récupérez la liste des relations ainsi :
curl --request GET --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/relationships?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Supprimez une relation individuelle avec l'ETag actuel du problème source. Pour une cible qui conserve relationshipType, indiquez-le dans la query string :
curl --request DELETE --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/relationships/tickets/{TICKET_ID}?relationshipType=related" \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-relationship-delete-20260905131727"Pour une cible telle que notes, dont le schéma indique qu'elle n'utilise pas de type de relation, omettez le paramètre relationshipType. Vous pouvez également supprimer une relation par une modification partielle :
curl --request PATCH --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-relationship-patch-20260905131727" \
--data-raw '{
"relationshipsToRemove": [
{
"targetId": "TICKET_UUID",
"targetDataSet": "tickets",
"targetItemType": "ticket",
"relationshipType": "related"
}
]
}'La suppression d'une relation ne supprime pas l'enregistrement qui en était la cible. Après chaque changement, récupérez à nouveau la collection et enregistrez le nouvel ETag du problème.
Problèmes - relations avec les utilisateurs
Un problème peut avoir les relations utilisateur suivantes :
agent- personne responsable du traitement ;watcher- observateur ;appUserRequester- utilisateur de l'application à l'origine du signalement.
Pour Problems, ne supposez pas l'existence d'une relation clientRequester. Les cibles sont des utilisateurs actifs et sont soumises aux contrôles d'accès liés à la localisation et au service.
Attribuer un agent :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_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: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-agent-20260905131727" \
--data-raw '{
"targetId": "USER_UUID",
"targetDataSet": "users",
"relationshipType": "agent"
}'Ajouter un observateur par batch :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_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: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-watcher-20260905131727" \
--data-raw '{
"add": [
{
"targetId": "WATCHER_USER_UUID",
"targetDataSet": "users",
"relationshipType": "watcher"
}
],
"remove": []
}'Lire et supprimer les relations :
curl --request GET --url "$BASE_URL/api/v1/problems/{PROBLEM_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/problems/{PROBLEM_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: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-agent-delete-20260905131727"Vous pouvez également supprimer un observateur par batch en laissant add vide et en plaçant l'entrée dans remove. Relisez le nouvel ETag après chaque changement.
Problèmes - fichiers
Avant toute opération sur un fichier, lisez le problème actuel et son ETag. L'envoi d'un fichier nécessite une requête multipart/form-data :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/files?relationshipType=documentation" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-file-one-20260905131727" \
--form "[email protected];type=text/plain"Liste des fichiers :
curl --request GET --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/files?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Un é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. Dans Problems, isMain vaut toujours false.
Téléchargez le contenu sous forme de données binaires :
curl --request GET --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/files/{FILE_ID}/content" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--output problem-evidence.txtVous pouvez joindre un fichier existant à un autre problème. L'ETag concerne alors le problème cible :
curl --request POST --url "$BASE_URL/api/v1/problems/{OTHER_PROBLEM_ID}/files/{FILE_ID}?relationshipType=manual" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $OTHER_PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-file-attach-20260905131727"Supprimer un fichier :
curl --request DELETE --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/files/{FILE_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-file-delete-20260905131727"Lisez la limite de taille des fichiers dans context avant l'envoi. Ne chargez pas un fichier volumineux en mémoire avant d'avoir vérifié cette limite.
Problèmes - épinglage, spam et réouverture
L'épinglage, le marquage comme spam et la réouverture sont des actions distinctes. Chaque action exige l'ETag actuel et une nouvelle clé d'idempotence.
Épingler un problème :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/pin" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-pin-20260905131727" \
--data-raw '{"pin":2}'La valeur de pin peut être un nombre de 0 à 3 ou null, selon le schéma. Marquer et désactiver le marquage spam :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/spam" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-spam-on-20260905131727" \
--data-raw '{"isSpam":true}'
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/spam" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-spam-off-20260905131727" \
--data-raw '{"isSpam":false}'Rouvrir un problème fermé :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/reopen" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-reopen-20260905131727"Les scopes nécessaires sont respectivement problems:pin:write, problems:spam:write et problems:reopen:write. Après chaque action, relisez le problème et enregistrez le nouvel ETag.
Problèmes - évaluation et escalade
Enregistrez une évaluation via un endpoint séparé. Vous pouvez y joindre une demande d'escalade :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/rating" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-rating-20260905131727" \
--data-raw '{
"rating": 4,
"feedback": "Évaluation issue de l'intégration Codenica API.",
"isEscalationRequested": true,
"escalationRequestReason": "Le problème nécessite une analyse par l'équipe de deuxième niveau."
}'La note va de 0 à 5 et nécessite le scope problems:rating:write. L'ajout d'une demande d'escalade nécessite également problems:escalation:write et l'autorisation appropriée pour l'utilisateur. Si vous enregistrez uniquement une note, omettez les champs d'escalade. Après l'enregistrement, relisez notamment rating, feedback, les dates d'évaluation et escalationRequestReason.
Problèmes - approbation et décision
Vous pouvez créer une approbation comme objet approval distinct et la relier au problème. La personne indiquée dans approverId doit être autorisée à prendre la décision :
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-problem-approval-create-20260905131727" \
--data-raw '{
"itemType": "approval",
"approverId": "APPROVER_USER_UUID",
"attributes": {
"customId": "PUBLIC-API-PROBLEM-20260905131727-APPROVAL",
"category": "Codenica API",
"description": "Approbation de l'analyse du problème."
},
"relationships": [
{
"targetId": "PROBLEM_UUID",
"targetDataSet": "problems",
"targetItemType": "problem"
}
]
}'Après la création, lisez l'approbation et enregistrez la décision via la route du problème. APPROVAL_ID est l'identifiant de l'approbation, pas celui d'un utilisateur :
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_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: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-approval-decision-20260905131727" \
--data-raw '{
"approve": true,
"remark": "Approuvé par l'intégration Codenica API."
}'Pour refuser, envoyez approve égal à false avec votre propre commentaire. Après la décision, relisez l'approbation et vérifiez son statut ou sa date de décision. Actualisez ensuite le problème, car la décision peut modifier son ETag et l'état du processus.
Problèmes - suppression d'un enregistrement
Avant la suppression, récupérez à nouveau le problème et utilisez son ETag actuel :
curl --request DELETE --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-delete-20260905131727"Après HTTP 200, exécutez un GET de contrôle avec le même UUID. Attendez HTTP 404 et le code problem_not_found, ou un autre code indiqué dans le contrat. Si le problème possède des relations, des fichiers ou une approbation, vérifiez les conséquences dans le schéma et les exigences de votre base avant de continuer.
La suppression d'un problème ne doit pas remplacer l'archivage de l'historique. Si l'enregistrement doit rester dans la documentation, modifiez son statut ou transférez les données vers un système conçu pour conserver l'historique.
Problèmes - erreurs, limites et sécurité
Les erreurs sont renvoyées au format application/problem+json. Exemple de réponse :
{
"type": "https://docs.codenica.com/errors/problem_not_found",
"title": "Problem not found.",
"status": 404,
"detail": "The problem does not exist or is outside the caller's access scope.",
"instance": "/api/v1/problems/PROBLEM_UUID",
"code": "problem_not_found",
"requestId": "request-id-from-response"
}Dans la logique d'intégration, appuyez-vous principalement sur status et code. Le champ detail s'adresse aux personnes et sa formulation peut changer.
Lisez les en-têtes X-RateLimit-Limit et X-RateLimit-Remaining. Après 429, appliquez un délai progressif et respectez l'éventuel Retry-After. Dans les journaux, enregistrez la méthode, l'endpoint, le statut et requestId, mais jamais le Client Secret ni les en-têtes d'authentification complets.
Les données de problèmes peuvent contenir des informations opérationnelles, personnelles et de diagnostic. Limitez les champs, utilisez HTTPS et restreignez l'accès de l'intégration à la base concernée.
Problèmes - déroulement de l'intégration
- Définissez
BASE_URLpour l'installation Cloud ou On-Premise appropriée. - Créez une clé distincte dans Paramètres - API - API Keys et sélectionnez les scopes minimum.
- Placez le Client ID et le Client Secret dans un stockage sécurisé.
- Envoyez
GET /api/v1/contextet vérifiez la base, le caller et les limites. - Récupérez
GET /api/v1/problems/schemaet mappez les champs de diagnostic. - Récupérez la liste des problèmes ou créez-en un avec
POSTet unIdempotency-Keyunique. - Enregistrez l'UUID du problème et son ETag.
- Actualisez l'ETag avant chaque mutation et utilisez une nouvelle clé d'idempotence.
- Ajoutez les relations, les utilisateurs et les fichiers uniquement après avoir vérifié leurs cibles dans le schéma.
- Exécutez l'épinglage, le spam, l'évaluation, l'escalade, la réouverture et les décisions d'approbation comme des opérations séparées.
- En cas de
412, récupérez l'enregistrement, résolvez le conflit et relancez l'opération en connaissance de cause. - Avec un batch, vérifiez le résultat de chaque élément, car une erreur partielle ne rétablit pas nécessairement les réussites.
- Gérez
429, enregistrezrequestIdsans secret et supprimez la clé lorsque l'intégration n'est plus utilisée. - Avant la suppression, confirmez l'ETag actuel et vérifiez ensuite HTTP
404.
Ce déroulement permet de synchroniser les problèmes et leur analyse avec un autre système sans dépendre de la structure interne de la base. Si la configuration des champs, l'adresse de l'installation ou les scopes de la clé changent, relisez le contexte et le schéma.
