Guide complet : comment utiliser l’API REST JIRA pour récupérer et créer des tickets

Benoit Costa

L’API REST JIRA représente un levier essentiel pour automatiser la gestion de projets et synchroniser vos workflows avec d’autres applications. Que vous développiez une plateforme interne, un tableau de bord personnalisé ou un système de ticketing hybride, maîtriser cette API vous permet de récupérer, créer et modifier des tickets sans intervention manuelle. Ce guide pratique détaille les méthodes d’authentification sécurisées, les requêtes de récupération avancées et les étapes de création de tickets via l’API REST JIRA.

💡 Notre conseil

Avant de plonger dans les appels API, assurez-vous de disposer d’un environnement de test JIRA (sandbox) pour éviter toute altération de données de production. Générez un jeton d’API dédié à vos tests et documentez chaque requête pour faciliter le debugging.

🔐 Configurer l’authentification pour l’API JIRA

Avant toute interaction avec l’API REST JIRA, vous devez établir un mécanisme d’authentification robuste. JIRA supporte plusieurs méthodes : l’authentification basique (nom d’utilisateur + mot de passe), OAuth 2.0 et les jetons d’API (tokens). Pour des raisons de sécurité et de simplicité, nous recommandons l’usage de jetons d’API personnels, qui offrent un contrôle granulaire sur les permissions et évitent d’exposer vos identifiants principaux.

Voici comment générer et utiliser un jeton d’API sur JIRA Cloud (Atlassian Cloud) :

1
Connexion au compte
Rendez-vous sur id.atlassian.com et connectez-vous avec votre compte Atlassian (email + mot de passe ou SSO).
2
Accès à la gestion des jetons
Dans le menu Security, cliquez sur Create and manage API tokens. Cette section liste tous vos jetons actifs et vous permet d’en créer de nouveaux.
3
Génération du jeton
Cliquez sur Create API token, attribuez-lui un nom explicite (ex. « Jeton script Python JIRA ») pour faciliter son identification ultérieure.
4
Copie et stockage sécurisé
Le jeton ne s’affiche qu’une seule fois. Copiez-le immédiatement et stockez-le dans un gestionnaire de secrets (ex. Vault, AWS Secrets Manager) ou une variable d’environnement chiffrée. Ne le partagez jamais dans un dépôt Git public.

Une fois le jeton généré, l’API JIRA attend une authentification HTTP Basic où le nom d’utilisateur est votre adresse email Atlassian et le mot de passe est le jeton d’API. En pratique, vous devez encoder ces informations en Base64 et les inclure dans l’en-tête Authorization de chaque requête HTTP.

Exemple d’en-tête d’authentification (pseudo-code) :

import base64

email = "votre.email@example.com"
api_token = "VoTreJeT0nAp1S3cr3T"
auth_string = f"{email}:{api_token}"
auth_b64 = base64.b64encode(auth_string.encode()).decode()

headers = {
    "Authorization": f"Basic {auth_b64}",
    "Content-Type": "application/json"
}

⚠️ À garder en tête

Les jetons d’API n’expirent pas automatiquement, mais vous pouvez les révoquer à tout moment depuis votre profil Atlassian. Renouvelez vos tokens régulièrement (tous les 6 mois minimum) et supprimez ceux qui ne sont plus utilisés pour limiter les risques d’accès non autorisé.

Pour les instances JIRA Server ou Data Center (auto-hébergées), l’authentification peut également utiliser des jetons personnels ou l’authentification basique classique. Consultez la documentation de votre version spécifique pour connaître les méthodes prises en charge.

🔍 Récupérer des tickets via l’API JIRA

La récupération de tickets (issues) constitue l’un des use cases les plus fréquents de l’API REST JIRA. Que vous souhaitiez afficher des statistiques dans un tableau de bord, synchroniser des données avec un CRM ou auditer l’activité d’un projet, l’endpoint /rest/api/2/search (ou /rest/api/3/search pour JIRA Cloud v3) vous permet d’interroger vos issues avec une grande flexibilité.

Syntaxe de base et paramètres de recherche

L’endpoint de recherche accepte une requête GET avec plusieurs paramètres optionnels dans l’URL :

GET https://votre-domaine.atlassian.net/rest/api/2/search?jql=query&startAt=offset&maxResults=limit&fields=champs
Paramètre Description Exemple de valeur
jql Requête en JIRA Query Language pour filtrer les issues project=DEMO AND status="In Progress"
startAt Index de départ pour la pagination (0-based) 0 (par défaut)
maxResults Nombre maximum d’issues retournées (limite souvent 50 ou 100) 50
fields Liste des champs à inclure dans la réponse (séparés par des virgules) id,key,summary,status,assignee
expand Sections supplémentaires à inclure (ex. changelog, renderedFields) changelog

Le paramètre jql (JIRA Query Language) est particulièrement puissant : il fonctionne comme un mini-langage de requête SQL, vous permettant de combiner des conditions sur les projets, les statuts, les assignés, les priorités, les dates, etc. Quelques exemples courants :

  • project = DEMO : tous les tickets du projet DEMO
  • assignee = currentUser() : tickets assignés à l’utilisateur authentifié
  • status IN ("To Do", "In Progress") : tickets en cours ou à faire
  • created >= -7d : tickets créés dans les 7 derniers jours
  • priority = High AND labels = urgent : tickets prioritaires avec le label « urgent »

Exemple de requête complète (Python)

import requests
import json
import base64

# Configuration
JIRA_URL = "https://votre-domaine.atlassian.net"
EMAIL = "votre.email@example.com"
API_TOKEN = "VoTreJeT0nAp1S3cr3T"

# Authentification
auth_string = f"{EMAIL}:{API_TOKEN}"
auth_b64 = base64.b64encode(auth_string.encode()).decode()

headers = {
    "Authorization": f"Basic {auth_b64}",
    "Content-Type": "application/json"
}

# Requête de recherche
params = {
    "jql": "project = DEMO AND status = 'In Progress'",
    "maxResults": 20,
    "fields": "id,key,summary,status,assignee,priority"
}

response = requests.get(
    f"{JIRA_URL}/rest/api/2/search",
    headers=headers,
    params=params
)

if response.status_code == 200:
    data = response.json()
    print(f"Total issues trouvées : {data['total']}")
    for issue in data['issues']:
        print(f"- {issue['key']}: {issue['fields']['summary']}")
else:
    print(f"Erreur {response.status_code}: {response.text}")

La réponse JSON contient un objet avec les clés suivantes :

  • total : nombre total d’issues correspondant à la requête JQL (utile pour la pagination)
  • startAt : index de départ actuel
  • maxResults : nombre maximal d’issues retournées dans cette page
  • issues : tableau d’objets, chaque objet représentant un ticket avec ses champs

✅ À retenir

Pour éviter de surcharger l’API JIRA, implémentez toujours une logique de pagination (boucle sur startAt jusqu’à ce que startAt + maxResults >= total). Limitez vos requêtes à 50–100 résultats par page et ajoutez un délai entre les appels (rate limiting) pour rester en dessous des quotas Atlassian.

Filtrer les champs retournés pour optimiser les performances

Par défaut, JIRA retourne tous les champs d’un ticket, ce qui peut alourdir la réponse (plusieurs kilo-octets par issue). En spécifiant explicitement les champs nécessaires via le paramètre fields, vous réduisez le volume de données transférées et accélérez le traitement côté client.

Exemple pour ne récupérer que la clé, le résumé et le statut :

GET /rest/api/2/search?jql=project=DEMO&fields=key,summary,status

Vous pouvez également utiliser fields=*all pour obtenir tous les champs système et personnalisés, ou fields=-description pour exclure un champ spécifique (pratique si les descriptions sont volumineuses).

« En moyenne, une requête JIRA bien optimisée (JQL précis + champs filtrés) peut être 3 à 5 fois plus rapide qu’une requête générique retournant tous les champs de tous les tickets d’un projet. »

— Analyse de performance API JIRA, Atlassian Community

🎯 Création de tickets avec l’API JIRA

Créer un ticket programmatiquement via l’API REST JIRA permet d’automatiser des workflows complexes : intégration de formulaires web, alertes depuis des outils de monitoring (ex. PagerDuty, Datadog), synchronisation avec un CRM ou un système de ticketing externe. L’endpoint de création est simple mais exige de respecter le schéma de champs requis par votre configuration JIRA.

Endpoint et structure de base

Pour créer un nouveau ticket, envoyez une requête POST à :

POST https://votre-domaine.atlassian.net/rest/api/2/issue

Le corps de la requête doit être un objet JSON contenant une clé fields, elle-même composée des métadonnées du ticket. Voici un exemple minimal pour créer un bug dans le projet DEMO :

{
  "fields": {
    "project": {
      "key": "DEMO"
    },
    "summary": "Erreur 500 lors de la soumission du formulaire de contact",
    "description": "Lorsque l'utilisateur clique sur 'Envoyer' dans le formulaire de contact, le serveur retourne une erreur 500. Les logs backend indiquent un timeout de connexion à la base de données.",
    "issuetype": {
      "name": "Bug"
    }
  }
}

Si la création réussit (code HTTP 201 Created), JIRA retourne un objet JSON contenant l’id, la key et l’self (URL) du ticket nouvellement créé. Exemple de réponse :

{
  "id": "10042",
  "key": "DEMO-123",
  "self": "https://votre-domaine.atlassian.net/rest/api/2/issue/10042"
}

Champs obligatoires et optionnels

Les champs requis varient selon la configuration de votre instance JIRA (écrans de création personnalisés, validateurs, workflows). Utilisez l’endpoint /rest/api/2/issue/createmeta pour interroger dynamiquement les champs obligatoires d’un type d’issue dans un projet donné :

GET /rest/api/2/issue/createmeta?projectKeys=DEMO&issuetypeNames=Bug&expand=projects.issuetypes.fields

Cet appel retourne un JSON détaillé listant tous les champs disponibles, leurs types (string, array, object), leurs valeurs autorisées (pour les champs à choix multiples) et leur caractère obligatoire (required: true).

Voici un tableau récapitulatif des champs les plus courants :

Champ Type Description Exemple de valeur
project Objet Clé ou ID du projet cible {"key": "DEMO"}
summary Chaîne Titre court du ticket (max 255 caractères) « Bug d’affichage mobile »
description Chaîne ou objet ADF Description détaillée (texte brut ou Atlassian Document Format) « Le menu déroulant ne s’affiche pas… »
issuetype Objet Type de ticket (Bug, Tâche, Story, Epic…) {"name": "Bug"}
priority Objet Niveau de priorité (Highest, High, Medium, Low, Lowest) {"name": "High"}
assignee Objet Utilisateur assigné (accountId pour JIRA Cloud) {"accountId": "5b10a2844c20165..."}
labels Tableau Étiquettes pour catégoriser le ticket ["urgent", "mobile"]
components Tableau d’objets Composants du projet (ex. Frontend, Backend) [{"name": "Frontend"}]
duedate Chaîne (ISO 8601) Date d’échéance au format YYYY-MM-DD « 2025-06-30 »

3 sec

temps moyen de création d’un ticket via l’API JIRA (optimisé)

Exemple de création avancée (avec champs optionnels)

import requests
import json
import base64

JIRA_URL = "https://votre-domaine.atlassian.net"
EMAIL = "votre.email@example.com"
API_TOKEN = "VoTreJeT0nAp1S3cr3T"

auth_string = f"{EMAIL}:{API_TOKEN}"
auth_b64 = base64.b64encode(auth_string.encode()).decode()

headers = {
    "Authorization": f"Basic {auth_b64}",
    "Content-Type": "application/json"
}

payload = {
    "fields": {
        "project": {"key": "DEMO"},
        "summary": "Optimiser les performances de la page d'accueil",
        "description": "La page d'accueil met plus de 5 secondes à charger sur mobile (4G). Identifier les ressources bloquantes et implémenter le lazy loading.",
        "issuetype": {"name": "Task"},
        "priority": {"name": "Medium"},
        "assignee": {"accountId": "5b10a2844c20165700ede21g"},
        "labels": ["performance", "frontend"],
        "components": [{"name": "Frontend"}],
        "duedate": "2025-07-15"
    }
}

response = requests.post(
    f"{JIRA_URL}/rest/api/2/issue",
    headers=headers,
    data=json.dumps(payload)
)

if response.status_code == 201:
    issue = response.json()
    print(f"Ticket créé : {issue['key']} (ID: {issue['id']})")
    print(f"URL : {issue['self']}")
else:
    print(f"Erreur {response.status_code}: {response.text}")

En cas d’erreur (code 400), JIRA retourne un objet JSON détaillant les champs manquants ou invalides. Exemple :

{
  "errorMessages": [],
  "errors": {
    "priority": "Le champ 'priority' est requis.",
    "assignee": "L'utilisateur spécifié n'existe pas."
  }
}

Analysez ce retour pour corriger votre payload avant de réessayer.

✅ Avantages de l’API pour la création ❌ Limites à anticiper
• Automatisation complète (webhooks, intégrations tierces)
• Validation immédiate des données
• Traçabilité et audit via logs
• Scalabilité (création en masse via scripts)
• Nécessite une gestion d’erreurs robuste
• Dépendance aux schémas de champs JIRA (changements fréquents)
• Rate limiting sur JIRA Cloud (limite de requêtes par minute)

Bonnes pratiques et optimisations

Pour exploiter pleinement l’API REST JIRA en production, adoptez ces bonnes pratiques :

  • Gestion des erreurs : implémentez des retries avec backoff exponentiel en cas d’erreur 429 (rate limit) ou 503 (service indisponible). Utilisez des bibliothèques comme tenacity (Python) ou axios-retry (JavaScript).
  • Cache des métadonnées : stockez localement les résultats de /rest/api/2/issue/createmeta et /rest/api/2/project pour éviter des appels répétés. Rafraîchissez le cache toutes les 24 heures ou lorsqu’un échec survient.
  • Batch processing : pour créer plusieurs tickets, utilisez l’endpoint /rest/api/2/issue/bulk qui permet de soumettre jusqu’à 50 issues en une seule requête (gain de temps et de quotas).
  • Webhooks vs polling : au lieu d’interroger régulièrement l’API pour déte