Les tickets dans Codenica API

Pour travailler avec les tickets via l’API, commencez par créer une clé API dans les paramètres de Codenica. Si vous ne l’avez pas encore créée, ouvrez dans un nouvel onglet l’article Codenica API - introduction. Vous y trouverez la création des clés, les limites de licence et les règles d’authentification communes à l’API.

Un ticket est un objet du Service Desk. En plus des informations de base comme le sujet, la description et le demandeur, il peut contenir la priorité, l’impact, l’urgence, la gravité, le statut, les données SLA, les informations de résolution, des relations avec d’autres objets et des fichiers. L’API propose également des actions propres aux tickets : épinglage, classement comme spam, réouverture, évaluation, demande d’escalade et décision d’approbation.

Les exemples utilisent les noms techniques des champs et des routes, car ce sont les valeurs exactes à envoyer dans les requêtes. Remplacez les textes d’exemple par les données de votre application.


Tickets - adresse de l’API

Toutes les opérations sur les tickets sont effectuées à l’adresse suivante :

{BASE_URL}/api/v1/tickets

Avec Codenica Cloud, utilisez l’adresse publique attribuée à votre installation. L’exemple ci-dessous utilise une adresse d’entreprise fictive :

https://votre-entreprise.codenica.com/api/v1/tickets

Dans une installation On-Premise, l’adresse par défaut enregistrée par Codenica Discovery est :

http://codenica.local:5150/api/v1/tickets

Si l’administrateur a publié l’installation à une autre adresse, utilisez cette adresse exacte, par exemple :

https://api.votre-entreprise.example/api/v1/tickets

N’utilisez localhost que si l’application d’intégration s’exécute sur le même ordinateur que l’API. N’ajoutez pas tenantId aux requêtes. La bonne base de données est sélectionnée à partir de l’adresse à laquelle vous vous connectez.


Tickets - clé API et limites de licence

Créez la clé dans Codenica, sous Paramètres - API - API Keys. Le secret n’est affiché qu’une seule fois, juste après la création ou la rotation de la clé. Enregistrez immédiatement les deux valeurs dans le coffre de secrets utilisé par l’intégration.

Le nombre de clés dépend de la licence attribuée à l’installation :

Licence
Nombre maximal de clés
Accès à Codenica API
Starter
0
Indisponible
Plus
50
Disponible
Enterprise
100
Disponible

Il est préférable de créer une clé distincte pour chaque intégration et chaque environnement, par exemple une clé pour la production, une pour les tests et une pour l’automatisation. Lors de la création, sélectionnez uniquement les périmètres nécessaires à cette connexion. La clé utilisée dans cet article doit disposer au minimum de tickets:read, tickets:write et des autres périmètres requis par les opérations prévues.


Tickets - authentification et requêtes sécurisées

L’intégration s’authentifie avec deux en-têtes. Elle n’a besoin ni du JWT de l’administrateur ni des cookies du panneau Codenica.

export BASE_URL="https://votre-entreprise.codenica.com"
export CLIENT_ID="cna_example"
export CLIENT_SECRET="cns_example"

curl --request GET "$BASE_URL/api/v1/tickets?page=1&pageSize=25" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Ne placez pas la clé dans le code de l’application, un dépôt, les journaux ou les messages d’erreur. Les valeurs CLIENT_ID et CLIENT_SECRET des exemples sont symboliques. En production, lisez-les depuis des variables d’environnement ou un coffre de secrets dédié.

La réponse de l’API contient l’identifiant de la requête dans meta.requestId. Conservez-le dans les journaux techniques, car il aide à retrouver une requête précise lors d’un diagnostic. N’enregistrez pas le secret de la clé avec cet identifiant.


Tickets - vérifier le contexte de connexion

Avant la première opération sur les tickets, vérifiez que l’adresse, la clé et les périmètres sont correctement configurés. Le endpoint de contexte renvoie notamment la version de l’API, l’identifiant de la base, l’identité de l’appelant, les périmètres et les capacités disponibles pour la clé.

curl --request GET "$BASE_URL/api/v1/context" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Dans une réponse valide, vérifiez :

  • data.apiVersion - elle doit indiquer la version v1 ;
  • data.contractVersion - la version du contrat utilisée par l’intégration ;
  • data.tenant.id et data.tenant.resolvedDomain - la base de données et l’adresse reconnue ;
  • data.caller.authentication - la valeur api_key ;
  • data.caller.scopes - les périmètres attribués à la clé ;
  • data.capabilities.resources - la présence de la ressource tickets ;
  • les limites de pagination, d’opérations batch et de requêtes par minute.

S’il manque un périmètre à cette étape, modifiez les autorisations de la clé dans les paramètres ou créez une nouvelle clé. N’essayez pas d’envoyer les périmètres dans la requête elle-même.


Tickets - périmètres d’autorisation

Les périmètres suivants sont nécessaires pour gérer les tickets complètement :

tickets:read
tickets:write
tickets:delete
tickets:schema
tickets:stats
tickets:relationships:read
tickets:relationships:write
tickets:users:read
tickets:users:write
tickets:files:read
tickets:files:write
tickets:technical:read
tickets:technical:write
tickets:pin:write
tickets:spam:write
tickets:reopen:write
tickets:rating:write
tickets:escalation:write
tickets:approval:write

Toutes les intégrations n’ont pas besoin de l’ensemble complet. Une intégration en lecture seule peut utiliser tickets:read. Pour lire le schéma, les statistiques et les valeurs des dictionnaires, ajoutez selon les besoins tickets:schema et tickets:stats. La lecture des relations, des utilisateurs et des fichiers exige les périmètres correspondants :relationships:read, :users:read et :files:read.

Pour utiliser les décisions d’approbation d’un ticket, vous avez besoin de tickets:approval:write. Si l’intégration crée et gère aussi elle-même des objets d’approbation, elle doit également disposer des périmètres liés à approvals. N’accordez pas de droits d’écriture uniquement parce qu’ils sont pratiques pendant le premier test.


Tickets - schéma et champs

Le schéma permet de récupérer la configuration actuelle des champs de votre base de données. C’est particulièrement important pour les valeurs de dictionnaire comme le statut, la priorité, l’impact, l’urgence, la gravité, le type et la catégorie.

curl --request GET "$BASE_URL/api/v1/tickets/schema" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Dans la réponse, recherchez les champs marqués required, writable, technical et hasAutoGeneration. La création d’un ticket exige au minimum subject et requesterEmail. N’enregistrez les autres champs que s’ils sont disponibles et nécessaires à votre processus.

Groupe de champs
Exemples de champs
Utilisation
Base
subject, requesterEmail, description, comments
Contenu et demandeur
Classification
type, category, priority, impact, urgency, severity, status
Routage du service
Organisation
location, department, teams, services
Lieu et équipes
Intégration
externalNumber, referenceNumber, link, tags
Identifiants du système externe

Les champs sla, rating, feedback, pin, isSpam et les dates liées aux actions sont gérés par le système ou par des endpoints dédiés. Ne supposez pas qu’un PATCH classique permet de les modifier.


Tickets - routes principales

Les routes les plus utilisées sont les suivantes :

  • GET /api/v1/tickets - liste des tickets ;
  • GET /api/v1/tickets/{id} - un ticket ;
  • POST /api/v1/tickets - créer un ticket ;
  • PATCH /api/v1/tickets/{id} - mise à jour partielle ;
  • DELETE /api/v1/tickets/{id} - suppression ;
  • GET /api/v1/tickets/schema - schéma des champs ;
  • GET /api/v1/tickets/stats - statistiques ;
  • GET /api/v1/tickets/values - valeurs utilisées dans les filtres ;
  • POST /api/v1/tickets:batch - plusieurs opérations dans une requête.

Les relations, les utilisateurs, les fichiers et les actions possèdent des routes distinctes, décrites dans la suite. Cette séparation permet d’accorder à l’intégration exactement les autorisations dont elle a besoin.


Tickets - listes et pagination

Lisez la liste avec GET. Il est recommandé d’indiquer le numéro et la taille de la page, même si vous prévoyez d’abord peu d’enregistrements.

curl --request GET "$BASE_URL/api/v1/tickets?page=1&pageSize=25" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

La réponse contient un objet data avec items, page, pageSize, totalItems, totalPages et hasNextPage. Lorsque hasNextPage vaut true, demandez la page suivante.

curl --request GET "$BASE_URL/api/v1/tickets?page=2&pageSize=25&sort=dateUpdated&direction=desc" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Le tri dépend du champ pris en charge par l’API. Pour une synchronisation, triez sur dateUpdated dans l’ordre croissant ou décroissant et mémorisez le dernier enregistrement traité.


Tickets - recherche et filtres

L’API permet de combiner la recherche textuelle et les filtres de champs. Utilisez search pour une recherche générale et filter pour préciser un opérateur et une valeur.

curl --get "$BASE_URL/api/v1/tickets" \
  --data-urlencode "page=1" \
  --data-urlencode "pageSize=25" \
  --data-urlencode "search=VPN" \
  --data-urlencode "filter=status:eq:Open" \
  --data-urlencode "filter=priority:eq:High" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Exemples de filtres utiles pour les tickets :

  • filter=status:eq:Closed - tickets fermés ;
  • filter=priority:eq:High - priorité élevée ;
  • filter=subject:contains:VPN - sujet contenant le texte indiqué ;
  • filter=description:notEmpty: - tickets avec une description ;
  • filter=isSpam:eq:false - tickets qui ne sont pas marqués comme spam.

Récupérez les valeurs du statut, de la priorité et des autres dictionnaires dans la configuration de votre base via l’endpoint values. Ne supposez pas que les mêmes noms existent dans toutes les installations.


Tickets - champs de réponse et extensions

Pour une liste de base, conservez l’ensemble de champs par défaut. Demandez des champs supplémentaires avec fields et les données associées avec include.

curl --get "$BASE_URL/api/v1/tickets" \
  --data-urlencode "fields=id,itemType,subject,status,priority,requesterEmail,dateUpdated" \
  --data-urlencode "include=relationships,users,files" \
  --data-urlencode "page=1" \
  --data-urlencode "pageSize=10" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Utilisez fields=* pour obtenir le modèle complet. Les extensions peuvent nécessiter des périmètres supplémentaires. Si l’intégration n’a pas accès aux utilisateurs, aux relations ou aux fichiers, retirez l’élément correspondant de include ou accordez l’autorisation appropriée.

Lors d’une synchronisation, prêtez attention à id, itemType, attributes et meta. L’identifiant de l’objet reste stable, tandis que meta.etag sert à effectuer des mises à jour sûres.


Tickets - statistiques et valeurs des champs

Les statistiques sont utiles, par exemple, pour compter les tickets par priorité. Elles ne modifient pas les données.

curl --get "$BASE_URL/api/v1/tickets/stats" \
  --data-urlencode "field=priority" \
  --data-urlencode "limit=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Demandez les valeurs d’un champ avec une recherche facultative :

curl --get "$BASE_URL/api/v1/tickets/values" \
  --data-urlencode "field=priority" \
  --data-urlencode "search=High" \
  --data-urlencode "limit=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Avant d’envoyer un nouveau ticket, récupérez les valeurs disponibles dans cette même base. L’intégration n’enverra ainsi pas une valeur que la configuration locale ne reconnaît pas.


Tickets - création

Créez un ticket avec la méthode POST. Le plus petit ensemble utile comprend itemType, un sujet et l’adresse e-mail du demandeur. Choisissez les autres données selon votre processus d’assistance.

curl --request POST "$BASE_URL/api/v1/tickets" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: ticket-create-ERP-2026-001" \
  --data '{
    "itemType": "ticket",
    "attributes": {
      "customId": "ERP-TICKET-2026-001",
      "subject": "VPN indisponible pour le service financier",
      "requesterEmail": "[email protected]",
      "description": "La connexion VPN est interrompue après quelques minutes d’utilisation.",
      "comments": "Ticket créé depuis le système ERP.",
      "source": "ERP",
      "type": "Incident",
      "category": "Network",
      "status": "Open",
      "priority": "High",
      "impact": "Department",
      "urgency": "High",
      "severity": "Major",
      "services": "VPN",
      "tags": "vpn;finance;integration",
      "externalNumber": "ERP-4581",
      "referenceNumber": "INC-2026-001",
      "currency": "PLN",
      "estimatedCost": 150.00
    }
  }'

Les valeurs de dictionnaire de cet exemple sont indicatives. Remplacez-les par les valeurs renvoyées par le schéma et l’endpoint values de votre base. Une création réussie renvoie 201 Created, data.id et l’ETag courant dans l’en-tête ainsi que dans data.meta.etag. Enregistrez ces valeurs, car elles seront nécessaires pour les opérations suivantes.


Tickets - idempotence des opérations d’écriture

Chaque requête qui crée, modifie ou supprime des données doit contenir un en-tête Idempotency-Key unique. Cela évite de créer deux fois un ticket lorsque l’application répète une requête après une interruption de connexion.

curl --request POST "$BASE_URL/api/v1/tickets" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: ticket-create-ERP-2026-001" \
  --data '{
    "itemType": "ticket",
    "attributes": {
      "subject": "VPN indisponible pour le service financier",
      "requesterEmail": "[email protected]"
    }
  }'

Répéter la même requête avec la même méthode, la même route, le même contenu et la même clé d’idempotence doit renvoyer le même enregistrement. Une nouvelle opération doit utiliser une nouvelle clé. N’utilisez pas une clé permanente pour tous les tickets.

Conservez la clé d’idempotence dans l’intégration avec l’état de son traitement. Si vous modifiez le contenu de la requête, utilisez une nouvelle clé, même si elle concerne le même ticket.


Tickets - lire un enregistrement

Après avoir créé ou trouvé l’identifiant du ticket, lisez-le à l’aide de son UUID :

export TICKET_ID="TICKET_UUID"

curl --get "$BASE_URL/api/v1/tickets/$TICKET_ID" \
  --data-urlencode "fields=*" \
  --data-urlencode "include=relationships,users,files" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Dans la réponse, lisez data.attributes et data.meta.etag. L’ETag peut changer après une modification des données, des relations, des utilisateurs ou des fichiers, ainsi qu’après une action. Avant une écriture, utilisez l’ETag courant et non une valeur conservée lors d’une lecture précédente.


Tickets - modification et protection par ETag

Effectuez une mise à jour avec PATCH. Envoyez uniquement les champs à modifier et l’ETag lu sur la version actuelle du ticket.

curl --request PATCH "$BASE_URL/api/v1/tickets/$TICKET_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-update-ERP-2026-001" \
  --data '{
    "attributes": {
      "status": "In Progress",
      "priority": "High",
      "comments": "L’équipe réseau analyse l’interruption de la session VPN.",
      "resolutionSummary": ""
    }
  }'

Une mise à jour réussie renvoie 200 OK et un nouvel ETag. Modifiez les champs gérés par des actions, comme isSpam, pin et rating, avec leurs endpoints dédiés. N’essayez pas de contourner cette séparation avec un PATCH classique.

Lorsque vous mettez à jour un délai, un coût ou des données d’intégration, conservez le codage des types renvoyé par le schéma. Envoyez les dates au format ISO 8601 et les nombres décimaux comme des nombres JSON.


Tickets - ETag obsolète ou absent

L’API bloque une écriture fondée sur une version obsolète de l’enregistrement. Si deux processus travaillent en même temps, le second ne peut pas écraser les modifications du premier sans nouvelle tentative explicite.

Un ETag obsolète renvoie 412 Precondition Failed avec le code if_match_failed. L’absence de l’en-tête If-Match renvoie 428 Precondition Required avec le code if_match_required.

curl --request PATCH "$BASE_URL/api/v1/tickets/$TICKET_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-update-retry-ERP-2026-001" \
  --data '{
    "attributes": {
      "comments": "Nouvelle tentative après lecture de la version actuelle."
    }
  }'

Après l’une de ces erreurs, relisez le ticket, vérifiez que la modification reste nécessaire, puis envoyez-la avec un nouvel ETag et une nouvelle clé d’idempotence. Ne désactivez pas la protection ETag dans l’intégration.


Tickets - relations avec les objets

Un ticket peut être lié aux objets visibles dans le schéma des relations, notamment aux actifs, documents, autres tickets, changements, problèmes, versions, notes, approbations, tâches et demandes d’achat. Le catalogue disponible peut dépendre de la configuration et des périmètres de la clé. Vérifiez donc relationshipTargets dans le schéma avant d’enregistrer une relation.

Lire les relations :

curl --request GET "$BASE_URL/api/v1/tickets/$TICKET_ID/relationships?page=1&pageSize=50" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Ajouter une relation avec un actif peut se faire ainsi :

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/relationships" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-relation-asset-ERP-2026-001" \
  --data '{
    "targetId": "ASSET_UUID",
    "targetDataSet": "assets",
    "targetItemType": "computer",
    "relationshipType": "related"
  }'

Pour ajouter plusieurs relations dans une seule requête, utilisez l’opération batch :

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/relationships:batch" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-relationship-batch-ERP-2026-001" \
  --data '{
    "add": [
      {
        "targetId": "OTHER_TICKET_UUID",
        "targetDataSet": "tickets",
        "targetItemType": "ticket",
        "relationshipType": "related"
      },
      {
        "targetId": "DOCUMENT_UUID",
        "targetDataSet": "documents",
        "targetItemType": "document",
        "relationshipType": "related"
      }
    ],
    "remove": []
  }'

La valeur de targetItemType doit correspondre au type réel de l’objet indiqué. L’ETag du ticket est mis à jour après l’ajout ou la suppression d’une relation. La suppression s’effectue avec le nom de la collection et l’identifiant de l’objet, généralement avec le paramètre relationshipType :

curl --request DELETE "$BASE_URL/api/v1/tickets/assets/$ASSET_ID?relationshipType=related" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-relation-remove-ERP-2026-001"

Tickets - relations avec les utilisateurs et les clients

Les relations avec les utilisateurs sont séparées des relations avec les objets. Vous pouvez notamment affecter un collaborateur comme agent, ajouter un observateur avec le type watcher, indiquer l’utilisateur demandeur avec appUserRequester ou un client avec clientRequester.

Liste des relations avec les utilisateurs :

curl --get "$BASE_URL/api/v1/tickets/$TICKET_ID/user-relationships" \
  --data-urlencode "relationshipType=agent" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Affecter un collaborateur :

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/user-relationships" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-agent-ERP-2026-001" \
  --data '{
    "targetId": "USER_UUID",
    "targetDataSet": "users",
    "relationshipType": "agent"
  }'

Modifiez plusieurs relations utilisateurs dans une seule requête :

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/user-relationships:batch" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-user-relationship-batch-ERP-2026-001" \
  --data '{
    "add": [
      {
        "targetId": "WATCHER_USER_UUID",
        "targetDataSet": "users",
        "relationshipType": "watcher"
      }
    ],
    "remove": []
  }'

L’ajout d’un observateur suit le même format, avec le type watcher. Enregistrez une relation avec un client avec targetDataSet égal à clients et le type clientRequester. Le périmètre tickets:users:write ne donne pas accès à tous les utilisateurs et ne contourne pas leurs autorisations.

La suppression d’une affectation exige le type de relation dans le paramètre de requête :

curl --request DELETE "$BASE_URL/api/v1/tickets/$TICKET_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: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-agent-remove-ERP-2026-001"

Tickets - fichiers

Les fichiers disposent de leurs propres routes. Pour envoyer un fichier, vous avez besoin de l’ETag actuel du ticket, d’un en-tête d’idempotence et d’une requête multipart.

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/files?relationshipType=documentation" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-file-ERP-2026-001" \
  --form "[email protected];type=text/plain"

Un envoi réussi renvoie 201 Created et les informations du fichier, notamment son identifiant et le chemin downloadUrl. Lisez la liste des fichiers ainsi :

curl --request GET "$BASE_URL/api/v1/tickets/$TICKET_ID/files?page=1&pageSize=50" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Le contenu du fichier est binaire. Enregistrez donc la réponse dans un fichier :

curl --request GET "$BASE_URL/api/v1/tickets/$TICKET_ID/files/$FILE_ID/content" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --output fichier-telecharge.txt

Vous pouvez joindre un fichier existant à un autre ticket avec POST /api/v1/tickets/{id}/files/{fileId}. Avant de le supprimer, vérifiez son identifiant et utilisez l’ETag du ticket. Supprimez un fichier avec DELETE /api/v1/tickets/{id}/files/{fileId}. Les tickets ne disposent pas d’une action distincte pour sélectionner un fichier principal.

Joindre un fichier existant à un autre ticket :

curl --request POST "$BASE_URL/api/v1/tickets/$OTHER_TICKET_ID/files/$FILE_ID?relationshipType=manual" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $OTHER_TICKET_ETAG" \
  --header "Idempotency-Key: ticket-file-attach-ERP-2026-001"

Supprimer un fichier du ticket actuel :

curl --request DELETE "$BASE_URL/api/v1/tickets/$TICKET_ID/files/$FILE_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-file-delete-ERP-2026-001"

Tickets - épinglage, spam et réouverture

Certaines propriétés d’un ticket sont modifiées par des actions dédiées. Chaque action exige l’ETag actuel et sa propre clé d’idempotence.

Épingler un ticket :

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/pin" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-pin-ERP-2026-001" \
  --data '{"pin":2}'

Retirer l’épingle en envoyant null :

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/pin" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-unpin-ERP-2026-001" \
  --data '{"pin":null}'

Marquer un ticket comme spam :

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/spam" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-spam-ERP-2026-001" \
  --data '{"isSpam":true}'

Annulez ce marquage avec la même route et le contenu {"isSpam":false}. Pour rouvrir un ticket fermé :

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/reopen" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-reopen-ERP-2026-001"

Ces opérations nécessitent respectivement tickets:pin:write, tickets:spam:write ou tickets:reopen:write. Après chaque action réussie, enregistrez le nouvel ETag renvoyé par l’API.


Tickets - évaluation et demande d’escalade

Après le traitement d’un ticket, vous pouvez enregistrer une évaluation et le commentaire de la personne qui évalue. La note est comprise entre 0 et 5.

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/rating" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-rating-ERP-2026-001" \
  --data '{
    "rating": 4,
    "feedback": "Le problème a été résolu et les échanges avec l’équipe ont été fluides.",
    "isEscalationRequested": true,
    "escalationRequestReason": "Merci de vérifier davantage la stabilité de la connexion VPN."
  }'

Si vous enregistrez uniquement une note, omettez les champs d’escalade. Si vous ajoutez une demande d’escalade, vous avez également besoin de tickets:escalation:write. La note seule exige tickets:rating:write. Après l’enregistrement, les valeurs apparaissent comme des champs en lecture seule, notamment rating, feedback, dateRating, dateFeedback, dateEscalationRequest et escalationRequestReason.


Tickets - décision d’approbation

Si une approbation est associée à un ticket, l’approbateur désigné peut prendre sa décision directement via la route du ticket. Il doit disposer de tickets:approval:write et être affecté à cette approbation.

export APPROVAL_ID="APPROVAL_UUID"

curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/approvals/$APPROVAL_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-approval-ERP-2026-001" \
  --data '{
    "approve": true,
    "remark": "La modification a été vérifiée et peut être déployée."
  }'

Pour refuser, envoyez approve à false avec votre propre commentaire. APPROVAL_ID est l’identifiant de l’approbation, et non celui d’un utilisateur. Si l’intégration crée elle-même les approbations, elle utilise la ressource approvals, indique l’approbateur et relie l’approbation au ticket. Après la décision, relisez le ticket et enregistrez son nouvel ETag.


Tickets - opérations batch, suppression et erreurs

Envoyez plusieurs opérations avec POST /api/v1/tickets:batch. Chaque élément décrit une opération create, update ou delete. Une mise à jour et une suppression exigent chacune leur propre ifMatch, car chaque enregistrement peut avoir une version différente.

curl --request POST "$BASE_URL/api/v1/tickets:batch" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: tickets-batch-ERP-2026-001" \
  --data '{
    "items": [
      {
        "operation": "create",
        "create": {
          "itemType": "ticket",
          "attributes": {
            "subject": "Accès impossible à l’imprimante",
            "requesterEmail": "[email protected]",
            "description": "L’imprimante ne répond pas aux demandes d’impression.",
            "source": "ERP"
          }
        }
      },
      {
        "operation": "update",
        "id": "TICKET_UUID",
        "ifMatch": "\"CURRENT_ETAG\"",
        "update": {
          "attributes": {
            "priority": "Normal"
          }
        }
      }
    ]
  }'

La réponse peut avoir le statut 200 ou 207 Multi-Status lorsque certains éléments échouent. Traitez chaque élément de la réponse selon son index, son opération, son statut et son champ error. Ne supposez pas qu’un élément en erreur annule tous les autres.

La suppression d’un ticket nécessite d’abord la lecture de son ETag actuel :

curl --request DELETE "$BASE_URL/api/v1/tickets/$TICKET_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $TICKET_ETAG" \
  --header "Idempotency-Key: ticket-delete-ERP-2026-001"

Après 200 OK, vérifiez avec une nouvelle lecture que le ticket renvoie 404 et le code ticket_not_found. Les réponses d’erreur courantes sont notamment : 400 pour des données invalides, 401 pour une authentification absente, 403 pour un périmètre manquant, 404 pour un enregistrement inexistant, 409 pour un conflit, 412 pour un ETag obsolète, 428 pour un ETag ou une clé d’idempotence manquante et 429 après dépassement de la limite. Une réponse problem contient notamment title, detail, code et requestId. Conservez ces informations dans les journaux et ne répétez que les opérations qui peuvent l’être sans risque.

Un ordre de travail pratique est le suivant : vérifier le contexte, lire le schéma et les valeurs, lire ou créer un ticket, enregistrer son ETag, effectuer les modifications avec l’idempotence et l’ETag actuel, puis relire l’état après chaque action. À la fin, vérifiez la synchronisation avec une liste filtrée par customId ou externalNumber.