Solutions dans Codenica API
Commencez à travailler avec les solutions via Codenica API en créant une clé dans les paramètres de Codenica. Si vous n'avez pas encore créé de clé, 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 des requêtes.
Le nom technique du module est solutions et le type d'un objet individuel est solution. Une solution est une entrée de la base de connaissances. Elle peut contenir une procédure, une description, des références et des fichiers complémentaires. Il ne s'agit pas d'un objet de workflow comme un ticket, un changement, un problème ou une release : ne lui transférez donc pas leurs champs de statut, de priorité ou d'escalade.
Les sections suivantes présentent l'adresse de l'API, les scopes, le contexte, le schéma, les champs, les listes, le filtrage, la création, l'idempotence, l'ETag, la modification, les opérations batch, les relations avec les problèmes, les informations sur l'auteur et l'éditeur, les fichiers, les évaluations et la suppression.
Les exemples utilisent l'identifiant PUBLIC-API-SOLUTION-20260905134845. 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.
Solutions - adresse de l'API et choix de l'installation
Toutes les routes relatives aux solutions commencent par :
{BASE_URL}/api/v1/solutionsBASE_URL désigne l'adresse du serveur Codenica sans le suffixe final /api/v1. Avec Codenica Cloud, utilisez le domaine public attribué à l'entreprise 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 un domaine d'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. La bonne base est sélectionnée à partir de l'adresse utilisée par l'intégration. N'envoyez pas tenantId dans le body ni dans la query string.
Solutions - clé API et limites de licence
Créez une clé API dans Codenica, à l'emplacement 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é. À ce moment-là, enregistrez 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. La licence Starter ne comprend pas Codenica API. Créez une clé distincte pour chaque application et chaque environnement afin de pouvoir gérer indépendamment ses scopes, faire tourner son secret ou supprimer son accès.
La suppression d'une clé supprime son enregistrement et libère une place dans la limite. Lorsque sa date d'expiration est dépassée, la clé n'authentifie plus les requêtes, mais reste dans la liste jusqu'à sa suppression. Si aucune date de fin n'est définie lors de la création, la durée de validité par défaut est de 90 jours. La durée maximale de validité d'une clé est de 5 ans.
Solutions - 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_your_client_id"
export CLIENT_SECRET="cns_your_client_secret"
curl --request GET --url "$BASE_URL/api/v1/solutions?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 du shell ou dans les journaux. En dehors des tests locaux, utilisez HTTPS.
Conservez le meta.requestId de la réponse. Il permet de retrouver une requête précise lors d'un diagnostic, mais ne remplace pas l'identifiant de la solution et ne doit pas être traité comme un secret.
Solutions - vérifier le contexte de connexion
Avant le premier enregistrement, lisez le contexte. Vous vérifierez ainsi que l'adresse correspond à la base voulue et que la clé sélectionnée 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 les valeurs suivantes 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
solutionsdansdata.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 ajoutés à une requête individuelle.
Solutions - scopes et autorisations
La prise en charge complète des solutions nécessite les scopes correspondant aux opérations utilisées par votre intégration :
solutions:read
solutions:write
solutions:delete
solutions:schema
solutions:stats
solutions:relationships:read
solutions:relationships:write
solutions:users:read
solutions:files:read
solutions:files:write
solutions:technical:read
solutions:technical:write
solutions:rating:write
problems:read
users:readPour une simple lecture, solutions:read suffit. Le schéma et les statistiques utilisent les scopes distincts solutions:schema et solutions:stats. La lecture des relations, des auteurs, des éditeurs et des fichiers nécessite les scopes de lecture correspondants. Les opérations d'écriture utilisent les scopes :write associés.
solutions:relationships:readetsolutions:relationships:writecouvrent les relations d'objet avec les problèmes ;solutions:users:readetusers:readcouvrent les informations sur l'auteur et l'éditeur, selon la configuration ;solutions:files:readetsolutions:files:writecouvrent la liste, l'envoi, l'association et la suppression des fichiers ;solutions:rating:writeest nécessaire pour envoyer ou retirer votre propre évaluation ;- n'utilisez les scopes techniques que si l'intégration a besoin de champs marqués comme techniques dans le schéma.
Le scope problems:read est nécessaire lorsque l'intégration recherche un problème à utiliser comme cible de relation. Le module Solutions ne crée ni ne supprime ce problème. N'accordez que les scopes réellement nécessaires.
Solutions - schéma et champs
Le schéma indique quels champs peuvent être lus et écrits dans la base sélectionnée. Récupérez-le avant de construire un formulaire ou une correspondance de champs :
curl --request GET --url "$BASE_URL/api/v1/solutions/schema" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La réponse contient notamment data.itemType, data.fields et data.relationshipTargets. La valeur fixe de itemType pour ce module est solution. Pour chaque champ, vérifiez readable, writable, required, technical, unique et maxLength. Ne construisez pas votre correspondance uniquement à partir des exemples de cet article.
Solutions - champs modifiables et champs système
Lors de la création, vous devez fournir title et category. Le catalogue public des champs métier comprend :
customId
title
description
location
department
type
tags
section
category
visibilityLongueurs maximales définies dans le schéma public :
Les valeurs suivantes sont en lecture seule et ne doivent pas figurer dans un payload PATCH ordinaire :
helpful
notHelpful
totalFiles
creator
updater
importId
importSource
dateImportedid et itemType font partie de l'enveloppe de la ressource. dateCreated et dateUpdated sont des données système. N'essayez pas de les modifier via attributes.
Solutions - endpoints principaux
Les routes principales du module solutions sont :
GET /api/v1/solutions
POST /api/v1/solutions
GET /api/v1/solutions/{SOLUTION_ID}
PATCH /api/v1/solutions/{SOLUTION_ID}
DELETE /api/v1/solutions/{SOLUTION_ID}
GET /api/v1/solutions/schema
GET /api/v1/solutions/stats
GET /api/v1/solutions/values
GET /api/v1/solutions/{SOLUTION_ID}/relationships
POST /api/v1/solutions/{SOLUTION_ID}/relationships
POST /api/v1/solutions/{SOLUTION_ID}/relationships:batch
GET /api/v1/solutions/{SOLUTION_ID}/user-relationships
GET /api/v1/solutions/{SOLUTION_ID}/files
POST /api/v1/solutions/{SOLUTION_ID}/files
GET /api/v1/solutions/{SOLUTION_ID}/files/{FILE_ID}/content
POST /api/v1/solutions/{SOLUTION_ID}/ratingToutes les routes nécessitent une authentification. Les opérations qui modifient les données nécessitent également Idempotency-Key, tandis que les opérations protégées par version nécessitent le If-Match actuel. Consultez le schéma et la réponse du contexte pour connaître les exigences exactes de l'opération appelée.
Solutions - listes et pagination
La liste est paginée. Cet exemple récupère la première page et trie les solutions par titre :
curl --request GET --url "$BASE_URL/api/v1/solutions?itemType=solution&page=1&pageSize=25&sort=title&direction=asc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La réponse contient notamment :
data.items
data.page
data.pageSize
data.totalItems
data.totalPages
data.hasNextPageRécupérez les pages suivantes tant que data.hasNextPage vaut true. Ne considérez pas le nombre de lignes de la première page comme la liste complète. Adaptez pageSize à la limite renvoyée par le contexte au lieu de demander systématiquement la valeur maximale.
Solutions - recherche, filtres et tri
Vous pouvez notamment filtrer par ids, customId, title, description, location, department, type, tags, section, category, visibility, helpful, notHelpful, createdAfter, createdBefore, updatedAfter et updatedBefore. Encodez dans l'URL les valeurs contenant des espaces, des virgules ou des caractères spéciaux.
Exemple : lister les solutions de la catégorie Public API :
curl --request GET --url "$BASE_URL/api/v1/solutions?category=Public%20API&page=1&pageSize=25&sort=title&direction=asc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Le paramètre search recherche dans les données textuelles de la solution, notamment le titre, la description, le type, les tags, la section, la catégorie, la visibilité, le lieu et le service :
curl --request GET --url "$BASE_URL/api/v1/solutions?search=backup&page=1&pageSize=25" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Triez uniquement sur un champ exposé par le schéma. Ne supposez pas que chaque champ affiché dans le formulaire peut être utilisé comme paramètre sort.
Solutions - projection des champs et données incluses
Si l'intégration n'a besoin que d'une partie de la ressource, limitez la réponse avec fields :
curl --request GET --url "$BASE_URL/api/v1/solutions?customId=PUBLIC-API-SOLUTION-20260905134845-SOURCE&fields=title%2Ccategory%2Cvisibility&page=1&pageSize=10" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Vous pouvez récupérer un enregistrement avec ses fichiers, ses relations et les informations sur son auteur ou son éditeur :
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}?fields=title%2Ccategory%2Cdescription%2Cvisibility&include=files%2Crelationships%2Cusers" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Les valeurs include autorisées sont files, relationships et users. Chacune nécessite le scope correspondant. fields=* demande tous les champs disponibles, mais les champs techniques apparaissent uniquement si le scope technique concerné est accordé.
Solutions - statistiques et valeurs des champs
Les statistiques servent à compter les enregistrements et à les regrouper par champ :
curl --request GET --url "$BASE_URL/api/v1/solutions/stats?field=category&limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La réponse contient notamment total, field et un tableau values. La valeur category=Public API peut servir de filtre pratique pour les données de démonstration.
Pour obtenir les valeurs distinctes d'un champ, utilisez la route values :
curl --request GET --url "$BASE_URL/api/v1/solutions/values?field=visibility&search=internal&limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"limit doit rester dans la plage prise en charge par l'API. Pour ces endpoints, la plage actuelle va de 1 à 500. Les requêtes de statistiques et de valeurs de champs sont en lecture seule et ne modifient pas les solutions.
Solutions - créer un enregistrement
Lors de la création, placez le type technique solution dans le body et les champs modifiables dans attributes. Le payload minimal exige title et category :
{
"itemType": "solution",
"attributes": {
"customId": "PUBLIC-API-SOLUTION-20260905134845-SOURCE",
"title": "PUBLIC-API-SOLUTION-20260905134845 integration knowledge article",
"description": "Created through the Codenica Public API Solutions flow.",
"location": "Warsaw",
"department": "IT",
"type": "How-to",
"tags": "public-api,solution,integration",
"section": "Integrations",
"category": "Public API",
"visibility": "team"
}
}Enregistrez le contenu sous solution-create.json et envoyez-le :
curl --request POST --url "$BASE_URL/api/v1/solutions" \
--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-solution-create-20260905134845" \
--data-binary @solution-create.jsonUne création réussie renvoie 201 Created. La réponse contient l'UUID de la solution, data.itemType=solution, les attributs enregistrés, les dates système et data.meta.etag. Dans la plupart des intégrations, laissez le système attribuer l'id.
Solutions - 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 solution :
curl --request POST --url "$BASE_URL/api/v1/solutions" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-solution-create-20260905134845" \
--data-binary @solution-create.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 solution 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.
Solutions - lire un enregistrement et utiliser l'ETag
Avant une modification, un changement de relation, une opération sur un fichier ou une évaluation, récupérez l'enregistrement actuel :
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}?fields=title%2Ccategory%2Cdescription%2Cvisibility%2Ctags" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"L'ETag est renvoyé dans l'en-tête HTTP et dans l'enveloppe de la réponse :
ETag: "..."
data.meta.etag: "..."
meta.etag: "..."Enregistrez la valeur de la réponse dans CURRENT_ETAG et utilisez-la dans la prochaine requête qui modifie les données. Après une modification réussie, récupérez un nouvel ETag. L'ancien ETag n'est plus à jour.
Solutions - mise à jour partielle avec If-Match
PATCH ne modifie que les champs transmis dans attributes. Cet exemple met à jour la description, la visibilité, les tags et la section :
{
"attributes": {
"description": "Updated through the Solutions Public API flow.",
"visibility": "internal",
"tags": "public-api,solution,updated",
"section": "Updated integrations"
}
}curl --request PATCH --url "$BASE_URL/api/v1/solutions/{SOLUTION_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-solution-update-20260905134845" \
--data-binary @solution-update.jsonUne mise à jour réussie renvoie 200 et un nouvel ETag. N'envoyez pas dans un PATCH ordinaire les champs en lecture seule ni les données techniques gérées par des endpoints distincts.
Solutions - ETag obsolète et If-Match absent
Si deux processus ont lu la même solution et que l'un d'eux a enregistré une modification en premier, le second dispose d'un ETag obsolète. Une tentative d'écriture avec cette valeur est refusée :
HTTP 412 Precondition Failed
code: if_match_failedAprès HTTP 412, relisez l'enregistrement, décidez comment réunir les modifications, puis envoyez un nouveau PATCH. La requête refusée à cause d'un ETag obsolète ne doit pas modifier les données.
Une mutation sans l'en-tête requis renvoie :
HTTP 428 Precondition Required
code: if_match_requiredN'essayez pas de contourner cette exigence en envoyant une valeur vide. Lisez d'abord l'enregistrement actuel et utilisez son ETag exact.
Solutions - opérations batch
Un batch permet d'exécuter plusieurs opérations indépendantes dans une seule requête. Cet exemple crée deux solutions :
{
"items": [
{
"operation": "create",
"create": {
"itemType": "solution",
"attributes": {
"customId": "PUBLIC-API-SOLUTION-BATCH-A",
"title": "Batch Solution A",
"category": "Public API",
"description": "Batch-created Solution A",
"type": "How-to",
"visibility": "team"
}
}
},
{
"operation": "create",
"create": {
"itemType": "solution",
"attributes": {
"customId": "PUBLIC-API-SOLUTION-BATCH-B",
"title": "Batch Solution B",
"category": "Public API",
"description": "Batch-created Solution B",
"type": "Reference",
"visibility": "team"
}
}
}
]
}curl --request POST --url "$BASE_URL/api/v1/solutions: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-solution-batch-create-20260905134845" \
--data-binary @solutions-batch.jsonPour une modification, l'élément contient operation=update, id, ifMatch et update.attributes :
{
"items": [
{
"operation": "update",
"id": "{SOLUTION_A_ID}",
"ifMatch": "{SOLUTION_A_ETAG}",
"update": {
"attributes": {
"description": "Batch update A"
}
}
}
]
}Pour une suppression, l'élément contient operation=delete, id et la valeur actuelle de ifMatch. La réponse peut contenir succeeded et failed ; un résultat partiel peut aussi utiliser HTTP 207 Multi-Status. Vérifiez chaque élément séparément. Un batch n'est pas une transaction.
Solutions - relations uniquement avec les problèmes
Les solutions prennent en charge les relations d'objet uniquement avec le module Problèmes. Une cible typique renvoyée par le schéma est :
targetDataSet: problems
targetItemType: problemNe supposez pas qu'une solution peut être reliée par ces endpoints à un actif, un document, un client, un fournisseur, un ticket, un changement ou une release. Si le schéma de la base sélectionnée ne renvoie pas une cible, l'intégration ne doit pas l'utiliser.
Commencez par rechercher un problème lisible à l'aide d'un champ de tri public :
curl --request GET --url "$BASE_URL/api/v1/problems?itemType=problem&page=1&pageSize=10&sort=subject&direction=asc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Le parcours de démonstration utilise l'identifiant du problème 9793181f-a225-4928-8062-80d6e69cb792. Votre intégration doit rechercher une cible actuelle et ne pas considérer cet UUID comme une valeur permanente.
Solutions - ajouter, lire et supprimer des relations
Le body d'un ajout direct de relation peut être le suivant :
{
"targetId": "9793181f-a225-4928-8062-80d6e69cb792",
"targetDataSet": "problems",
"targetItemType": "problem",
"relationshipType": "related"
}Lisez l'ETag actuel de la solution avant chaque mutation :
curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_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-solution-problem-relation-add-20260905135119" \
--data-binary @solution-problem-relation.jsonUn ajout réussi renvoie 201 Created. Lisez la relation avec une route distincte :
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/relationships?targetDataSet=problems&targetItemType=problem&page=1&pageSize=50" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La suppression directe nécessite l'ETag actuel et l'identifiant de la cible :
curl --request DELETE --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/relationships/problems/9793181f-a225-4928-8062-80d6e69cb792?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-solution-problem-relation-delete-20260905135119"Une suppression réussie renvoie 200 avec data=true. Relisez la collection après l'opération.
Solutions - relations batch avec les problèmes
Utilisez la route relationships:batch pour ajouter et supprimer des relations dans une même requête :
{
"add": [
{
"targetId": "9793181f-a225-4928-8062-80d6e69cb792",
"targetDataSet": "problems",
"targetItemType": "problem",
"relationshipType": "related"
}
],
"remove": []
}curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_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-solution-problem-relation-batch-add-20260905135119" \
--data-binary @solution-problem-relation-batch.jsonPour supprimer une relation via batch, laissez add vide et placez l'élément dans remove :
{
"add": [],
"remove": [
{
"targetId": "9793181f-a225-4928-8062-80d6e69cb792",
"targetDataSet": "problems",
"targetItemType": "problem",
"relationshipType": "related"
}
]
}La réponse contient les compteurs added, removed et skipped. Après un ajout, vérifiez added=1 ; après une suppression, vérifiez removed=1. Utilisez un ETag récent avant toute écriture suivante.
Solutions - relations d'auteur et d'éditeur
Dans ce module, les relations utilisateur sont des métadonnées sur l'auteur et le dernier éditeur. Les types pris en charge sont author et editor :
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/user-relationships?page=1&pageSize=50" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Un élément de liste peut contenir :
{
"targetId": "8e9cbff3-340f-41f6-97ec-6997bb915829",
"targetDataSet": "users",
"relationshipType": "author",
"displayName": "Fred Savage",
"email": "[email protected]",
"role": "Administrator"
}Les relations author et editor sont lues à partir des champs creator et updater de la solution. Le module public Solutions ne fournit pas d'endpoints pour les ajouter, les modifier ou les supprimer. N'essayez pas de créer des relations agent, watcher, appUserRequester ou clientRequester : ces types appartiennent à d'autres objets.
Solutions - fichiers
Avant chaque opération sur un fichier, lisez la solution actuelle et son ETag. Listez les fichiers avec :
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_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 peut contenir id, name, fileName, contentType, size, width, height, relationshipType, isMain et downloadUrl. Pour les solutions, isMain vaut toujours false. Le module ne fournit pas d'endpoint set-main : n'essayez donc pas de désigner un fichier principal.
L'envoi d'un fichier utilise le format multipart/form-data :
curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_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-solution-file-20260905134845" \
--form "[email protected];type=text/plain"Un upload réussi renvoie 201 Created et une ressource fichier. L'exemple utilise solution-one.txt de type text/plain. L'upload modifie la version de la solution : récupérez donc le nouvel ETag ensuite.
Téléchargez le contenu via le chemin authentifié :
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/files/{FILE_ID}/content" \
--header "Accept: application/octet-stream" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--output solution-one-downloaded.txtTraitez downloadUrl comme un chemin d'API, et non comme un lien public anonyme. Si un fichier existe déjà dans le même espace de fichiers, vous pouvez l'associer à une autre solution :
curl --request POST --url "$BASE_URL/api/v1/solutions/{TARGET_SOLUTION_ID}/files/{FILE_ID}?relationshipType=manual" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $TARGET_CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-file-attach-20260905134845"Pour une association, utilisez l'ETag de la solution cible, et non celui de l'enregistrement d'origine du fichier. La suppression d'un fichier nécessite l'ETag actuel :
curl --request DELETE --url "$BASE_URL/api/v1/solutions/{SOLUTION_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-solution-file-delete-20260905134845"Après avoir reçu 200, relisez la liste des fichiers pour confirmer que le fichier n'est plus renvoyé.
Solutions - évaluer l'utilité
L'évaluation est une mutation distincte. Vous pouvez marquer une solution comme utile, inutile ou retirer votre propre évaluation :
{
"rating": 1
}1- utile ;0- inutile ;-1- retirer votre propre évaluation.
Marquer une solution comme utile :
curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_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-solution-rating-helpful-20260905134845" \
--data '{"rating":1}'Retirer votre propre évaluation :
curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/rating" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $RATING_CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-rating-reset-20260905134845" \
--data '{"rating":-1}'Les deux opérations nécessitent un ETag. La réponse contient les compteurs actuels helpful et notHelpful ainsi qu'un nouvel ETag. Ne modifiez pas helpful ou notHelpful dans un PATCH ordinaire.
Solutions - supprimer un enregistrement
La suppression est irréversible. Lisez donc d'abord l'enregistrement et obtenez son ETag actuel :
curl --request DELETE --url "$BASE_URL/api/v1/solutions/{SOLUTION_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-solution-delete-20260905134845"Une réponse réussie renvoie 200 avec data=true. Effectuez ensuite un GET de vérification et contrôlez une liste filtrée :
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"
curl --request GET --url "$BASE_URL/api/v1/solutions?customId=PUBLIC-API-SOLUTION-20260905134845-SOURCE&page=1&pageSize=10" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Après la suppression, le GET individuel renvoie 404 Not Found avec le code solution_not_found, tandis que la liste filtrée doit contenir totalItems=0. Vérifiez ou nettoyez les relations et les fichiers avant de supprimer un enregistrement si l'intégration doit conserver une trace d'audit.
Solutions - erreurs, limites et sécurité
Les erreurs de l'API utilisent le format Problem Details. Les champs principaux sont status, code, detail et requestId :
{
"type": "https://docs.codenica.com/errors/if_match_failed",
"title": "Precondition failed.",
"status": 412,
"detail": "The supplied ETag is not the current solution version.",
"instance": "/api/v1/solutions/{SOLUTION_ID}",
"code": "if_match_failed",
"requestId": "..."
}code et detailLisez les en-têtes X-RateLimit-Limit et X-RateLimit-Remaining. Après un 429, respectez Retry-After lorsqu'il est renvoyé et utilisez des relances contrôlées avec des délais croissants.
Les solutions peuvent contenir des données opérationnelles et des instructions internes. Limitez les champs sélectionnés, utilisez HTTPS et restreignez la clé à la base concernée. Stockez 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 demandes d'assistance.
Solutions - séquence d'intégration
- Déterminez l'adresse réelle Cloud ou On-Premise et définissez
BASE_URL. - Créez une clé distincte pour l'application et l'environnement dans Paramètres - API - API Keys.
- Accordez uniquement les scopes nécessaires à la lecture, à l'écriture, aux relations, aux fichiers ou aux évaluations.
- Envoyez
GET /api/v1/contextet vérifiez la base, le caller, les scopes et les limites. - Récupérez
GET /api/v1/solutions/schemaet construisez la correspondance des champs. - Récupérez une liste ou recherchez une solution existante.
- Créez un enregistrement avec
POSTet unIdempotency-Keyunique. - Enregistrez l'UUID et l'ETag de la réponse.
- Actualisez l'ETag avant chaque modification, relation, opération sur un fichier, évaluation ou suppression.
- Créez des relations d'objet uniquement avec un problème renvoyé par le schéma.
- Lisez seulement les relations d'auteur et d'éditeur, car le module public ne fournit pas d'endpoints d'écriture pour ces relations.
- Après chaque mutation, relisez le résultat et enregistrez le nouvel ETag.
- En cas de
412, récupérez l'enregistrement, résolvez le conflit, puis seulement relancez l'opération. - Pour un batch, contrôlez chaque élément, car une erreur partielle n'annule pas les éléments réussis.
- Avant la suppression, confirmez l'ETag actuel puis vérifiez
404et une listecustomIdvide.
Cette séquence permet de synchroniser les solutions de la base de connaissances avec un autre système sans dépendre d'hypothèses sur les champs, les relations ou les données système.
