Les actifs dans Codenica API
Vous trouverez ci-dessous des exemples pratiques pour travailler avec les actifs enregistrés dans Codenica. Dans l'API publique, le nom technique de cet objet est assets. Un actif peut représenter un ordinateur, un appareil, un logiciel, une licence ou tout autre élément d'inventaire disponible dans votre base de données.
Avant d'envoyer votre première requête, créez la clé API décrite dans l'article Codenica API - introduction. Les sections suivantes couvrent tout le cycle de travail avec les actifs : vérification du schéma et listes, création et modification, relations et fichiers, opérations batch et suppression.
- lecture d'actifs individuels et de listes paginées ;
- recherche et filtrage des champs d'inventaire ;
- création d'enregistrements et mises à jour partielles ;
- protection des modifications avec ETag et nouvelles tentatives sûres avec Idempotency-Key ;
- liaison des actifs avec d'autres actifs et objets Codenica ;
- envoi, téléchargement, rattachement et suppression de fichiers ;
- lecture des statistiques et des valeurs de champs et traitement de plusieurs opérations dans une seule requête.
Les exemples utilisent itemType=computer. Chaque base de données peut proposer des champs différents. Lisez le schéma du type utilisé avant d'enregistrer des données.
Actifs - adresse de l'API et choix du déploiement
Envoyez les requêtes à l'adresse publique où votre installation Codenica est accessible. N'utilisez pas l'adresse de la base de données, celle d'un conteneur ou un port accessible uniquement depuis l'intérieur du serveur. Les chemins des actifs commencent par :
{BASE_URL}/api/v1/assetsAvec Codenica Cloud, utilisez le domaine public associé à votre installation :
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 On-Premise avec un domaine d'entreprise, un reverse proxy, HTTPS ou un autre port externe, utilisez l'adresse exacte communiquée pour cette installation :
export BASE_URL="https://api.votre-entreprise.example"N'essayez pas de choisir la base de données avec un champ supplémentaire dans la chaîne de requête ou le body. La bonne base est sélectionnée à partir de l'adresse de l'hôte. N'utilisez pas localhost lorsque l'application d'intégration fonctionne sur un autre ordinateur que l'API. En production, utilisez HTTPS lorsque l'installation est publiée avec un certificat.
Actifs - scopes de la clé API
Créez la clé API dans Codenica, sous Paramètres - API - API Keys. Pour une intégration qui travaille avec les actifs, sélectionnez uniquement les scopes nécessaires. L'accès à l'API n'étend pas les permissions de l'utilisateur représenté par la clé ni l'accès aux données configuré dans votre base.
Scopes de base pour les actifs :
assets:read- lister et lire les actifs ;assets:write- créer et modifier les actifs ;assets:delete- supprimer les actifs ;assets:schema- lire les champs, leurs propriétés et les cibles de relations ;assets:stats- statistiques et valeurs de champs utilisées pour le filtrage ;assets:relationships:read- lire les relations ;assets:relationships:write- ajouter et supprimer des relations ;assets:files:read- lister et télécharger les fichiers ;assets:files:write- envoyer, rattacher, choisir le fichier principal et supprimer des fichiers ;assets:technical:read- lire les champs marqués comme techniques ;assets:technical:write- écrire les champs techniques modifiables ;assets:secrets:write- écrire les champs secrets lorsque le schéma les expose.
Les champs techniques et secrets ne sont pas nécessaires pour les lectures ou mises à jour ordinaires de l'inventaire. Les secrets ne sont enregistrés que si le scope approprié est présent et ne sont pas renvoyés dans les réponses.
Après la création, copiez le Client ID et le Client Secret dans le coffre sécurisé utilisé par l'application d'intégration. Le secret n'est affiché qu'au moment de la création ou de la rotation de la clé. L'application externe utilise ces deux valeurs, et non la session du panneau ou un Bearer JWT.
Actifs - authentification et contexte
Envoyez les deux en-têtes de clé API avec chaque requête :
export CLIENT_ID="cna_votre_client_id"
export CLIENT_SECRET="cns_votre_client_secret"
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"Avant de commencer l'intégration proprement dite, lisez /api/v1/context. Vérifiez que la réponse concerne la bonne base de données, que caller.authentication vaut api_key et que les scopes contiennent les opérations nécessaires.
Dans l'objet capabilities, confirmez que assets est disponible et lisez les limites, notamment maxPageSize, maxUploadBytes et la limite de requêtes. Conservez meta.requestId. Cet identifiant permet de retrouver une requête précise dans les journaux ou lors d'un échange avec l'administrateur.
Si le contexte correspond à une autre base ou ne contient pas un scope requis, arrêtez l'intégration et corrigez la clé ou l'adresse de l'API. N'essayez pas de changer de base avec les données envoyées dans le body.
Actifs - schéma des champs et des relations
Le schéma indique ce qui peut être lu et enregistré dans la base utilisée. Récupérez-le pour le type d'actif nécessaire :
curl --request GET --url "$BASE_URL/api/v1/assets/schema?itemType=computer" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Pour chaque champ, vérifiez au minimum :
- le nom et le type de données ;
readableetwritable;required;technicalet, s'il existe,secretWriteOnly;- les valeurs de
options; - la longueur maximale et l'unicité ;
- la génération automatique et les exigences supplémentaires de la base.
Le schéma peut varier selon itemType et la configuration de l'inventaire. Par exemple, le champ category peut accepter des valeurs différentes dans deux bases. Ne construisez pas l'intégration en supposant que la liste des champs ou des options est fixe.
Le schéma contient aussi le catalogue des cibles de relations. Avant d'envoyer une relation, vérifiez que le type d'objet choisi, son targetItemType et le type de relation correspondent à la réponse.
Actifs - points d'accès disponibles
La carte ci-dessous réunit les principaux chemins utilisés par une intégration. Remplacez {id}, {targetDataSet}, {targetId} et {fileId} par les identifiants appropriés.
GET /api/v1/assets- liste des actifs ;GET /api/v1/assets/schema- schéma ;GET /api/v1/assets/stats- statistiques ;GET /api/v1/assets/values- valeurs de champs ;GET /api/v1/assets/{id}- actif individuel ;POST /api/v1/assets- création ;PATCH /api/v1/assets/{id}- mise à jour partielle ;DELETE /api/v1/assets/{id}- suppression ;POST /api/v1/assets:batch- opérations de création, mise à jour et suppression ;GET /api/v1/assets/{id}/relationships- liste des relations ;POST /api/v1/assets/{id}/relationships- ajout d'une relation ;POST /api/v1/assets/{id}/relationships:batch- modification groupée des relations ;DELETE /api/v1/assets/{id}/relationships/{targetDataSet}/{targetId}- suppression d'une relation ;GET /api/v1/assets/{id}/files- liste des fichiers ;POST /api/v1/assets/{id}/files- envoi d'un fichier ;POST /api/v1/assets/{id}/files/{fileId}- rattachement d'un fichier existant ;PUT /api/v1/assets/{id}/files/{fileId}/main- choix du fichier principal ;DELETE /api/v1/assets/{id}/files/{fileId}- suppression d'un fichier ;GET /api/v1/assets/{id}/files/{fileId}/content- téléchargement du contenu.
Le scope requis pour chaque chemin découle du nom de l'opération. Si vous recevez 403, vérifiez d'abord les scopes de la clé et les permissions de l'utilisateur qui lui est associé.
Actifs - listes et pagination
Lisez la liste page par page. Cette requête renvoie les vingt premiers actifs visibles de type computer :
curl --request GET --url "$BASE_URL/api/v1/assets?itemType=computer&page=1&pageSize=20" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Une réponse de collection a une structure proche de celle-ci :
{
"data": {
"items": [
{
"id": "11111111-1111-1111-1111-111111111111",
"itemType": "computer",
"attributes": {
"customId": "CND-OFFICE-PC-01",
"name": "Ordinateur de bureau 01",
"category": "Hardware"
},
"meta": {
"dateUpdated": "2026-09-07T10:00:00Z",
"etag": "\"etag-v1\""
}
}
],
"page": 1,
"pageSize": 20,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false
},
"meta": {
"requestId": "request-id-from-response"
}
}Ne supposez pas que la première page contient toutes les données. Continuez tant que hasNextPage vaut true ou utilisez totalPages. Ne définissez pas pageSize au-dessus de la limite renvoyée dans le contexte.
Actifs - recherche et filtres
Utilisez search pour une recherche simple. Pour sélectionner les champs plus précisément, utilisez les paramètres courts ou le paramètre filter :
curl --request GET --url "$BASE_URL/api/v1/assets?itemType=computer&search=office&page=1&pageSize=50" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"
curl --request GET --url "$BASE_URL/api/v1/assets?customId=CND-OFFICE-PC-01" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"
curl --request GET --url "$BASE_URL/api/v1/assets?filter=category:contains:Hardware" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Vous pouvez notamment utiliser itemType, ids, search, name, category, status, location, department, manufacturer, model, serialNumber, inventoryNumber, customId, tag, createdAfter, createdBefore, updatedAfter et updatedBefore.
Le paramètre filter accepte notamment les opérateurs suivants :
eq- égal à ;ne- différent de ;in- l'une des valeurs fournies ;contains- contient un fragment ;startsWithetendsWith- commence ou se termine par le texte fourni ;emptyetnotEmpty- champ vide ou non vide ;gt,gte,lt,lte- comparaisons.
filter=status:eq:In service
filter=serialNumber:contains:ABC
filter=category:in:Hardware,Software
filter=description:notEmpty:Si une valeur contient des espaces ou des caractères spéciaux, encodez-la selon les règles d'URL. Pour filtrer avec des identifiants, rappelez-vous que ids limite le résultat aux UUID indiqués.
Actifs - sélection des champs et données incluses
Le paramètre fields limite les champs renvoyés dans la réponse. Il est utile lorsque l'intégration n'a besoin que de quelques valeurs :
curl --request GET --url "$BASE_URL/api/v1/assets?fields=id,itemType,name,category,status" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Utilisez include pour lire les données liées. Pour les actifs, les valeurs disponibles sont files et relationships :
curl --request GET --url "$BASE_URL/api/v1/assets/$ASSET_ID?include=files,relationships" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Les scopes nécessaires aux données incluses doivent être autorisés par la clé. Si la clé ne possède pas assets:files:read ou assets:relationships:read, lisez l'enregistrement sans l'inclusion concernée ou élargissez la clé selon le principe du moindre privilège.
fields=* ne révèle pas les champs secrets. Ne considérez pas la sélection de champs comme un moyen de contourner les permissions. Les champs techniques et secrets apparaissent uniquement si les scopes et le schéma l'autorisent.
Actifs - création d'un enregistrement
Utilisez POST /api/v1/assets pour créer un enregistrement. Envoyez le type technique itemType et les champs modifiables dans l'objet attributes. Cet exemple crée un ordinateur de bureau :
export IDEMPOTENCY_KEY="asset-create-20260907-0001"
curl --request POST --url "$BASE_URL/api/v1/assets" \
--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": "computer",
"attributes": {
"customId": "CND-OFFICE-PC-01",
"name": "Ordinateur de bureau 01",
"category": "Hardware",
"manufacturer": "Lenovo",
"model": "ThinkCentre",
"location": "Paris",
"status": "In service"
}
}'Dans le modèle de base, name et category sont au moins requis, mais votre base peut imposer d'autres exigences, valeurs de liste ou règles d'unicité. Comparez toujours le body avec le schéma actuel.
Une réponse réussie a le statut 201 Created. Enregistrez data.id, data.meta.etag et l'en-tête HTTP ETag. Exemple de fragment de réponse :
{
"data": {
"id": "11111111-1111-1111-1111-111111111111",
"itemType": "computer",
"attributes": {
"customId": "CND-OFFICE-PC-01",
"name": "Ordinateur de bureau 01",
"category": "Hardware"
},
"meta": {
"customId": "CND-OFFICE-PC-01",
"dateCreated": "2026-09-07T10:00:00Z",
"dateUpdated": "2026-09-07T10:00:00Z",
"etag": "\"etag-v1\""
}
},
"meta": {
"requestId": "request-id-from-response",
"etag": "\"etag-v1\""
}
}N'envoyez pas votre propre id, sauf si le schéma et l'intégration exigent un UUID contrôlé. Si vous utilisez votre propre identifiant, il doit être libre et respecter les exigences de l'API.
Actifs - nouvelle tentative sûre après une création
Après un timeout, vous ne savez peut-être pas si le serveur a créé l'enregistrement. Ne créez pas immédiatement une nouvelle clé d'idempotence. Envoyez exactement la même requête avec le même Idempotency-Key et un body identique :
curl --request POST --url "$BASE_URL/api/v1/assets" \
--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": "computer",
"attributes": {
"customId": "CND-OFFICE-PC-01",
"name": "Ordinateur de bureau 01",
"category": "Hardware",
"manufacturer": "Lenovo",
"model": "ThinkCentre",
"location": "Paris",
"status": "In service"
}
}'Répéter exactement la même opération reproduit la première réponse et ne crée pas de deuxième enregistrement. La même clé ne doit pas ensuite décrire un autre body, un autre endpoint ou une autre intention. Une telle réutilisation renvoie 422 idempotency_key_reused.
L'idempotence s'applique également aux autres requêtes qui modifient les données : mises à jour, changements de relations, opérations sur les fichiers et suppressions. Utilisez une nouvelle valeur pour chaque nouvelle intention.
Actifs - lecture d'un enregistrement
Après avoir créé ou trouvé un actif, lisez-le avec son UUID :
export ASSET_ID="11111111-1111-1111-1111-111111111111"
curl --request GET --url "$BASE_URL/api/v1/assets/$ASSET_ID?include=files,relationships" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La réponse contient id, le itemType technique, les champs dans attributes et les métadonnées dans meta. Vous trouverez l'ETag dans l'en-tête HTTP et généralement aussi dans data.meta.etag et dans l'enveloppe meta.etag.
Relisez l'actif avant chaque modification. Cela concerne les champs, les relations, l'envoi d'un fichier, le choix du fichier principal, la suppression d'un fichier et la suppression de l'enregistrement complet. L'opération s'appuie ainsi sur la version actuelle plutôt que sur une valeur conservée en mémoire par l'intégration.
Actifs - mise à jour partielle avec ETag
PATCH ne modifie que les champs présents dans le body. Il n'est pas nécessaire d'envoyer l'enregistrement complet. Ajoutez l'ETag obtenu lors de la dernière lecture et une nouvelle clé d'idempotence :
export ASSET_ETAG='"etag-v1"'
export IDEMPOTENCY_KEY="asset-update-20260907-0001"
curl --request PATCH --url "$BASE_URL/api/v1/assets/$ASSET_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 "Idempotency-Key: $IDEMPOTENCY_KEY" \
--header "If-Match: $ASSET_ETAG" \
--data-raw '{
"attributes": {
"name": "Ordinateur de bureau 01 - mis à jour",
"description": "Actif mis à jour par l'intégration."
}
}'Après réussite, la réponse a le statut 200 OK et contient un nouvel ETag. Remplacez l'ancienne valeur avant l'opération suivante. L'envoi de null efface un champ si celui-ci n'est pas obligatoire et si le schéma autorise une valeur vide.
Le body doit contenir une véritable modification d'un champ modifiable, d'une valeur personnalisée ou d'une relation. Un champ en lecture seule, technique ou secret peut nécessiter un scope ou un endpoint séparé.
Actifs - protection contre une version obsolète
ETag empêche qu'un enregistrement soit écrasé par une modification effectuée entre-temps par une autre personne ou intégration. Deux situations doivent être traitées séparément :
428 if_match_required- l'en-têteIf-Matchrequis ou, pour une modification,Idempotency-Keyest absent ;412 if_match_failed- l'ETag fourni n'est plus actuel.
Exemple de réponse avec un ETag obsolète :
{
"type": "https://docs.codenica.com/errors/if_match_failed",
"title": "Precondition failed.",
"status": 412,
"detail": "The supplied ETag is not the current asset version.",
"instance": "/api/v1/assets/11111111-1111-1111-1111-111111111111",
"code": "if_match_failed",
"requestId": "request-id-from-response"
}Après 412, relisez l'actif, comparez les valeurs actuelles avec la modification souhaitée, puis envoyez seulement ensuite un nouveau PATCH avec le nouvel ETag. Ne répétez pas indéfiniment la même requête avec un ETag obsolète. Une valeur précise dans If-Match est la méthode recommandée pour une intégration. La valeur * correspond à un scénario contrôlé et ne doit pas remplacer le contrôle de version lors d'une synchronisation ordinaire.
Actifs - ajout de relations
Une relation relie un actif à un autre objet visible. Les cibles disponibles comprennent :
assets, clients, documents, tickets, changes, problems, releases,
notes, worktasks, confirmations, requesteditemsCet exemple relie deux ordinateurs. Si vous envoyez targetItemType, sa valeur doit correspondre au type réel de la cible :
export TARGET_ASSET_ID="22222222-2222-2222-2222-222222222222"
export IDEMPOTENCY_KEY="asset-relation-add-20260907-0001"
curl --request POST --url "$BASE_URL/api/v1/assets/$ASSET_ID/relationships" \
--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" \
--header "If-Match: $ASSET_ETAG" \
--data-raw '{
"targetId": "22222222-2222-2222-2222-222222222222",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
}'La cible doit exister et être visible pour l'utilisateur associé à la clé. Un actif ne peut pas pointer vers lui-même. Selon la cible, l'API peut enregistrer relationshipType. Pour notes, worktasks et requesteditems, n'envoyez pas ce champ, car le modèle actuel de ces relations ne le conserve pas.
L'ajout d'une relation modifie la version de l'actif source. Après une réponse 201 Created, relisez la source et utilisez son nouvel ETag pour la modification suivante.
Actifs - lecture et suppression des relations
Lisez les relations via l'endpoint de collection, en limitant si nécessaire le résultat à un ensemble de cibles :
curl --request GET --url "$BASE_URL/api/v1/assets/$ASSET_ID/relationships?targetDataSet=assets&page=1&pageSize=50" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Un élément de relation peut contenir notamment targetId, targetDataSet, targetItemType, relationshipType, customId et name. La lecture d'une relation ne renvoie pas l'objet cible complet, sauf si vous effectuez une lecture séparée ou utilisez include=relationships.
Pour supprimer une relation, vous avez besoin d'un ETag récent de la source :
export IDEMPOTENCY_KEY="asset-relation-delete-20260907-0001"
curl --request DELETE --url "$BASE_URL/api/v1/assets/$ASSET_ID/relationships/assets/$TARGET_ASSET_ID?relationshipType=related" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: $IDEMPOTENCY_KEY" \
--header "If-Match: $ASSET_ETAG"Une suppression réussie renvoie 200 OK avec data: true. Lorsqu'une relation est supprimée via l'endpoint direct, la valeur de relationshipType dans la requête doit correspondre à la relation visée. Relisez la collection et l'actif source après l'opération.
Actifs - modification groupée des relations
Utilisez relationships:batch lorsque vous devez ajouter ou supprimer plusieurs relations. Une même requête peut contenir les tableaux add et remove :
export IDEMPOTENCY_KEY="asset-relations-batch-20260907-0001"
curl --request POST --url "$BASE_URL/api/v1/assets/$ASSET_ID/relationships: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: $IDEMPOTENCY_KEY" \
--header "If-Match: $ASSET_ETAG" \
--data-raw '{
"add": [
{
"targetId": "22222222-2222-2222-2222-222222222222",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
}
],
"remove": [
{
"targetId": "33333333-3333-3333-3333-333333333333",
"targetDataSet": "clients",
"relationshipType": "owner"
}
]
}'La réponse 200 OK contient les compteurs added, removed et skipped. Une relation déjà présente peut être comptée comme skipped si vous la renvoyez. Un batch de relations modifie également l'ETag de la source : relisez donc l'actif après l'opération.
Pour les éléments qui concernent notes, worktasks et requesteditems, omettez relationshipType. Chaque cible doit être visible et correspondre au catalogue de relations renvoyé par le schéma.
Actifs - liste et envoi de fichiers
Les fichiers sont enregistrés avec l'actif et disposent de leurs propres identifiants. Vous pouvez d'abord lire la liste actuelle :
curl --request GET --url "$BASE_URL/api/v1/assets/$ASSET_ID/files?page=1&pageSize=50" \
--header "Accept: application/json" \
--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.
L'envoi utilise multipart/form-data. Pour modifier l'actif, vous avez besoin d'un ETag récent et d'une nouvelle clé d'idempotence :
curl --request POST --url "$BASE_URL/api/v1/assets/$ASSET_ID/files?makeMain=true&relationshipType=documentation" \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: asset-file-upload-20260907-0001" \
--header "If-Match: $ASSET_ETAG" \
--form "file=@./asset-manual.txt;type=text/plain"makeMain=true désigne le fichier envoyé comme fichier principal. Le paramètre relationshipType décrit l'usage du fichier, par exemple documentation ou manual. La limite d'envoi par défaut est de 20 MiB, mais vérifiez la valeur actuelle de maxUploadBytes dans le contexte.
Le nom du fichier ne doit pas contenir de chemin ni de segment ... N'enregistrez pas de secrets dans le nom, les métadonnées ou le contenu du fichier, sauf si cela est nécessaire.
L'envoi renvoie 201 Created et un objet fichier. Relisez l'actif après l'opération, car son ETag a changé.
Actifs - téléchargement et choix du fichier principal
Téléchargez le contenu avec l'endpoint /content. La réponse contient des données binaires et non une enveloppe JSON :
export FILE_ID="44444444-4444-4444-4444-444444444444"
curl --request GET --url "$BASE_URL/api/v1/assets/$ASSET_ID/files/$FILE_ID/content" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--output ./asset-file-download.txtDans un objet fichier, downloadUrl est une adresse relative. Ajoutez-y l'hôte du déploiement et utilisez les mêmes en-têtes d'authentification.
Si un actif possède plusieurs fichiers, vous pouvez choisir le fichier principal. Cette opération modifie l'actif et exige son ETag actuel :
curl --request PUT --url "$BASE_URL/api/v1/assets/$ASSET_ID/files/$FILE_ID/main" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: asset-set-main-20260907-0001" \
--header "If-Match: $ASSET_ETAG"Une réponse réussie a le statut 200 OK et renvoie généralement data: true. Relisez la liste des fichiers et vérifiez que l'élément choisi possède isMain=true et que l'ancien fichier principal possède isMain=false. Lisez ensuite le nouvel ETag de l'actif.
Dans l'interface, un petit fichier peut être arrondi à 0 MB. Vérifiez sa taille réelle dans le champ size ou en comptant les octets téléchargés.
Actifs - rattachement d'un fichier existant
Si un fichier est déjà enregistré dans le système, vous pouvez le rattacher à un autre actif sans envoyer à nouveau son contenu :
export TARGET_ASSET_ID="55555555-5555-5555-5555-555555555555"
export TARGET_ASSET_ETAG='"target-etag-v1"'
curl --request POST --url "$BASE_URL/api/v1/assets/$TARGET_ASSET_ID/files/$FILE_ID?makeMain=true&relationshipType=manual" \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: asset-attach-file-20260907-0001" \
--header "If-Match: $TARGET_ASSET_ETAG"Une réponse 201 Created contient l'identifiant du fichier rattaché et ses métadonnées. Si vous avez utilisé makeMain=true, relisez la liste et vérifiez que isMain vaut true.
Le rattachement modifie également la version de l'actif cible. Lisez l'ETag actuel de la cible avant l'opération suivante sur ses fichiers. Ne supprimez un fichier d'un actif qu'après avoir vérifié qu'il n'est plus nécessaire à cet endroit ni dans ses autres relations.
Actifs - suppression d'un fichier
La suppression d'un fichier modifie l'actif. Lisez son ETag actuel et utilisez une clé d'idempotence distincte :
curl --request DELETE --url "$BASE_URL/api/v1/assets/$ASSET_ID/files/$FILE_ID" \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: asset-file-delete-20260907-0001" \
--header "If-Match: $ASSET_ETAG"Une réponse réussie a le statut 200 OK et contient data: true. Après chaque suppression, relisez la liste des fichiers et l'ETag de l'actif. Si vous supprimez plusieurs fichiers, l'ETag de l'opération suivante doit provenir de la modification précédente déjà terminée.
La suppression d'un fichier ne supprime pas l'actif entier. Une tentative de téléchargement du contenu supprimé renvoie 404 file_not_found. Si un fichier est rattaché à plusieurs actifs, vérifiez avant la suppression que vous agissez sur la bonne relation et qu'il n'est plus nécessaire.
Actifs - statistiques et valeurs de champs
L'endpoint stats aide à construire un résumé des données visibles. Vous pouvez limiter le résultat à un type d'actif et indiquer le champ dont vous voulez les valeurs :
curl --request GET --url "$BASE_URL/api/v1/assets/stats?itemType=computer&field=category&limit=20" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La réponse peut contenir le nombre total d'actifs visibles, une répartition par itemType, le nom du champ et ses valeurs :
{
"data": {
"total": 11,
"byItemType": {
"computer": 11
},
"field": "category",
"values": [
"Laptop",
"Desktop",
"Hardware"
]
},
"meta": {
"requestId": "request-id-from-response"
}
}L'endpoint values renvoie des valeurs utiles pour construire des listes de filtres :
curl --request GET --url "$BASE_URL/api/v1/assets/values?field=category&itemType=computer&search=hard&limit=20" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Avec la recherche hard, le résultat peut contenir Hardware. Ces deux endpoints sont en lecture seule, exigent assets:stats et ne nécessitent pas d'ETag. Les résultats incluent uniquement les données visibles par l'utilisateur.
Actifs - opérations batch
Batch permet de combiner création, mise à jour et suppression dans une seule requête. Chaque élément possède sa propre opération, et update ainsi que delete transmettent leur ETag dans le champ ifMatch :
curl --request POST --url "$BASE_URL/api/v1/assets: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: assets-batch-20260907-0001" \
--data-raw '{
"items": [
{
"operation": "create",
"create": {
"itemType": "computer",
"attributes": {
"customId": "CND-BATCH-PC-01",
"name": "Ordinateur créé par lot",
"category": "Hardware"
}
}
},
{
"operation": "update",
"id": "11111111-1111-1111-1111-111111111111",
"ifMatch": "\"current-etag\"",
"update": {
"attributes": {
"description": "Description mise à jour par lot."
}
}
},
{
"operation": "delete",
"id": "22222222-2222-2222-2222-222222222222",
"ifMatch": "\"current-etag\""
}
]
}'Si tous les éléments réussissent, la réponse a le statut 200 OK. Le résultat contient succeeded, failed et le résultat de chaque élément avec son index, son operation et son status.
Batch n'est pas une transaction tout ou rien. En cas de réussite partielle, l'API renvoie 207 Multi-Status et ne revient pas sur les éléments réussis. Vérifiez chaque élément. Si le batch crée de nouveaux enregistrements, enregistrez leurs ID et ETag dans les résultats individuels.
Chaque élément exige le scope correspondant à son opération. Une requête batch n'élargit pas les permissions de la clé.
Actifs - suppression d'un enregistrement
Relisez l'actif avant de le supprimer et utilisez son ETag actuel :
export IDEMPOTENCY_KEY="asset-delete-20260907-0001"
curl --request DELETE --url "$BASE_URL/api/v1/assets/$ASSET_ID" \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: $IDEMPOTENCY_KEY" \
--header "If-Match: $ASSET_ETAG"Une suppression réussie renvoie 200 OK avec data: true. Une lecture ultérieure de l'UUID renvoie 404 asset_not_found. La suppression exécute le nettoyage de domaine prévu, mais l'API publique ne supprime pas automatiquement les objets métier liés, comme les documents, les tickets ou les clients.
Après la suppression, retirez l'identifiant de l'index local de l'intégration ou marquez l'enregistrement comme inactif. N'essayez pas de modifier à nouveau l'UUID supprimé.
Actifs - erreurs, limites et sécurité
Les erreurs de l'API utilisent le format Problem Details avec des champs Codenica supplémentaires :
{
"type": "https://docs.codenica.com/errors/asset_not_found",
"title": "Asset not found.",
"status": 404,
"detail": "The asset does not exist or is outside the caller's access scope.",
"instance": "/api/v1/assets/11111111-1111-1111-1111-111111111111",
"code": "asset_not_found",
"requestId": "request-id-from-response"
}Dans la logique de l'application, utilisez surtout status et code. Le texte de detail est une indication destinée à l'utilisateur et peut changer.
400- body, paramètre ou valeur de champ incorrect ;401- authentification absente ou incorrecte ;403- scope ou permission utilisateur manquant ;404- actif, fichier ou cible de relation inexistant ou non visible ;409- conflit de données ou d'état métier ;412- ETag obsolète ;413- envoi 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.
Lisez X-RateLimit-Limit, X-RateLimit-Remaining et, pour 429, Retry-After. Utilisez des nouvelles tentatives contrôlées avec des délais croissants. N'enregistrez jamais le Client Secret dans un dépôt, une URL, du code envoyé au navigateur, l'historique des commandes ou les journaux.
Actifs - cycle complet d'intégration
- Déterminez l'adresse correcte de l'API. En On-Premise, vérifiez que l'intégration peut atteindre
http://codenica.local:5150ou l'adresse publiée par l'administrateur. - Créez une clé API distincte pour cette intégration et sélectionnez les scopes minimaux.
- Conservez le Client ID et le Client Secret dans un coffre sécurisé.
- Envoyez
GET /api/v1/contextet vérifiez que la réponse concerne la bonne base de données, puis contrôlez le caller, les scopes et les limites. - Envoyez
GET /api/v1/assets/schema?itemType=computeret adaptez le body aux champs actuels. - Lisez la liste avec pagination, recherche ou filtres.
- Créez un actif avec
POSTet une nouvelle valeurIdempotency-Key. - Enregistrez l'UUID et l'ETag.
- Relisez l'enregistrement actuel avant chaque modification.
- Effectuez les mises à jour, relations, opérations sur les fichiers et suppressions avec un ETag précis et une nouvelle clé d'idempotence.
- Après chaque modification réussie, enregistrez le nouvel ETag et relisez le résultat si nécessaire.
- Après
412, relisez l'enregistrement, résolvez le conflit, puis seulement ensuite recommencez l'opération. - Pour un grand nombre de modifications, utilisez batch, mais vérifiez chaque élément, car batch n'est pas une transaction.
- Gérez
429et ne journalisez jamais les secrets. - Supprimez la clé API lorsque l'intégration n'est plus utilisée.
Cette méthode permet à l'intégration d'utiliser les données d'inventaire sans dépendre de la structure interne de la base. Si la configuration des champs, les permissions ou l'adresse de déploiement changent, relisez le contexte et le schéma au lieu de vous appuyer sur d'anciennes hypothèses.
