OTOBO / Znuny Web Services – API REST

Dans ce guide détaillé, vous apprendrez comment activer, configurer et intégrer l'API REST OTOBO (partie de l'Interface Générique) dans vos propres applications.
1. Architecture & Fondamentaux
OTOBO fournit son Interface Générique via des services Web REST et SOAP. L'API REST communique via HTTP(S)/JSON et permet :
- Opérations sur les tickets : Création, récupération, modification, suppression
- Opérations sur les articles : Publication, gestion des pièces jointes
- Historique & Recherche : Historique des tickets et requêtes de recherche complexes
Note : Une installation standard ne contient pas de services Web préconfigurés – vous les créez vous-même dans le module Admin « Processus & Automatisation → Services Web ».
2. Configuration
2.1 Activation de l'Interface Générique
- Dans la zone Admin → SysConfig → GenericInterface.Transport, passez à REST (HTTP).
- Sous AdminGenericInterfaceTransportHTTPREST, configurez les timeouts, l'en-tête hôte et le niveau de débogage.
- Dans GenericInterface.Operation, créez et activez les opérations souhaitées (par ex.
TicketCreate,TicketSearch,TicketGet,TicketUpdate,TicketDelete,TicketHistoryGet).
2.2 URL de Base & Authentification
URL de Base
https://VOTRE-SERVEUR/otobo/nph-genericinterface.pl/Webservice/<VotreServiceName>/Authentification
- Cookies de session OTOBO
- Clés API / Tokens (à créer via SysConfig)
- Utilisez toujours HTTPS !
3. Points d'Accès & Méthodes HTTP (Détail)
Pour chaque point d'accès, vous trouverez ici un aperçu détaillé des paramètres, des réponses possibles et des exemples pratiques.
3.1 TicketCreate (POST)
URL : /Webservice/<ServiceName>/TicketCreateMéthode : POST
Description : Crée un nouveau ticket et génère immédiatement un article.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| SessionID | Integer | Oui¹ | ID de session ou UserLogin+Password |
| UserLogin | String | Oui² | Login de l'agent (en combinaison avec Password) |
| Password | String | Oui² | Mot de passe (en combinaison avec UserLogin) |
| Ticket.Title | String | Oui | Sujet du ticket |
| Ticket.Queue | String | Oui | Nom de la queue ou Ticket.QueueID |
| Ticket.State | String | Oui | État initial (par ex. new) |
| Ticket.Priority | String | Oui | Priorité (par ex. 3 normal) |
| Ticket.CustomerUser | String | Oui | E-mail ou login du client |
| Article.Subject | String | Oui | Sujet du premier article |
| Article.Body | String | Oui | Contenu du premier article |
| Article.MimeType | String | Oui | text/plain ou text/html |
¹ Soit SessionID, soit UserLogin+Password requis. ² Si aucun token SessionID n'est fourni.
Exemple de Requête :
POST /Webservice/MyConnectorREST/TicketCreate HTTP/1.1
Host: demo.otobo.org
Content-Type: application/json
X-API-Key: abc123
{
"Data": {
"SessionID": 42,
"Ticket": {
"Title": "Nouvelle Commande",
"Queue": "Sales",
"State": "new",
"Priority": "3 normal",
"CustomerUser": "max.mustermann@example.com"
},
"Article": {
"Subject": "Demande d'achat – Produit XY",
"Body": "Merci de fournir une offre de prix…",
"MimeType": "text/plain"
}
}
}Exemple de Réponse :
{
"Success": 1,
"ErrorMessage": "",
"Data": {
"TicketID": "12345",
"ArticleID": "67890"
}
}3.2 TicketSearch (GET)
URL : /Webservice/<ServiceName>/TicketSearchMéthode : GET
Description : Recherche des tickets selon divers critères de filtrage.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| UserLogin, Password | String,String | Oui¹ | Identifiants agent ou SessionID² |
| SessionID | Integer | Oui² | Token pour les sessions authentifiées |
| Title | String/String[] | Non | Recherche avec joker dans le titre (%Commande%) |
| TicketNumber | String/String[] | Non | Numéro(s) de ticket |
| QueueIDs | Integer[] | Non | IDs de file d'attente |
| States | String[] | Non | États (new, open, …) |
| StateType | String/String[] | Non | Catégorie Ouvert/Fermé |
| DynamicField_Name.Op | Mixed | Non | Champs dynamiques avec opérateur (Equals, Like, GreaterThan …) |
¹ Soit UserLogin+Password, soit SessionID. ² Si aucune paire de connexion n'est fournie.
Exemple de Requête :
GET /Webservice/MyConnectorREST/TicketSearch?UserLogin=agent1&Password=geheim&Title=%25Bestellung%25 HTTP/1.1
Host: demo.otobo.orgExemple de Réponse :
{
"Success": 1,
"Data": {
"TicketID": [1001,1005,1012]
}
}3.3 TicketGet (GET)
URL : /Webservice/<ServiceName>/TicketGetMéthode : GET
Description : Renvoie les données détaillées du ticket, y compris les articles, les pièces jointes et les champs dynamiques.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| UserLogin, Password | String,String | Oui¹ | Identifiants agent ou SessionID² |
| SessionID | Integer | Oui² | Token pour les sessions authentifiées |
| TicketID | String/String[] | Oui | Un ou plusieurs IDs de ticket (séparés par virgule ou tableau) |
| DynamicFields | Boolean (0/1) | Non | 1 = Champs dynamiques dans le résultat, Défaut = 0 |
| Extended | Boolean | Non | 1 = Métadonnées étendues (par ex. FirstResponse) |
| AllArticles | Boolean | Non | 1 = Renvoyer tous les articles |
| ArticleLimit | Integer | Non | Nombre maximum d'articles renvoyés |
| Attachments | Boolean | Non | 1 = Intégrer les pièces jointes en Base64 |
| GetAttachmentContents | Boolean | Non | 1 = Charger également le contenu des pièces jointes |
| HTMLBodyAsAttachment | Boolean | Non | 1 = Ajouter la version HTML de l'article en pièce jointe |
¹ Soit UserLogin+Password, soit SessionID. ² Si aucune paire de connexion n'est fournie.
Exemple de Requête :
GET /Webservice/MyConnectorREST/TicketGet?SessionID=42&TicketID=12345&AllArticles=1&DynamicFields=1 HTTP/1.1
Host: demo.otobo.orgExemple de Réponse (tronqué) :
{
"Success":1,
"Data":{
"Ticket":[{
"TicketID":12345,
"TicketNumber":"202501230001",
"Title":"Nouvelle Commande",
"State":"open",
"DynamicField":[{"Name":"Urgency","Value":"high"}],
"Article":[{
"ArticleID":67890,
"Subject":"Demande d'achat…",
"Body":"Merci de fournir une offre de prix…",
"Attachment":[{"Filename":"Angebot.pdf","Content":"JVBERi0x…="}]
}]
}]
}
}3.4 TicketUpdate (PUT)
URL : /Webservice/<ServiceName>/TicketUpdateMéthode : PUT
Description : Met à jour les champs d'un ticket existant et crée éventuellement un nouvel article.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| SessionID | Integer | Oui¹ | Token ou UserLogin+Password² |
| TicketID | Integer | Oui | ID du ticket à mettre à jour |
| Ticket.Title | String | Non | Nouveau titre |
| Ticket.State | String | Non | Nouveau statut |
| Ticket.Owner | String/ID | Non | Nouveau propriétaire |
| Ticket.PendingTime | Hash / Diff | Non | Nouvelle heure de mise en attente |
| Article.Subject | String | Non | Crée un nouvel article |
| Article.Body | String | Non | Contenu du nouvel article |
| DynamicField… | Array | Non | Mise à jour des champs dynamiques |
| Attachment… | Array | Non | Ajout de nouvelles pièces jointes |
¹ Soit SessionID, soit UserLogin+Password. ² Si aucun token SessionID n'est fourni.
Exemple de Requête :
PUT /Webservice/MyConnectorREST/TicketUpdate HTTP/1.1
Host: demo.otobo.org
Content-Type: application/json
X-API-Key: abc123
{
"Data":{
"SessionID":42,
"TicketID":12345,
"Ticket":{ "State":"pending reminder","PendingTime":{"Diff":1440} },
"Article":{ "Subject":"Rappel défini","Body":"Le ticket est en cours de traitement." }
}
}Exemple de Réponse :
{ "Success":1, "ErrorMessage":"", "Data":{ "TicketID":12345, "ArticleID":67891 } }3.5 TicketDelete (DELETE)
URL : /Webservice/<ServiceName>/TicketDeleteMéthode : DELETE
Description : Supprime définitivement un ou plusieurs tickets.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| SessionID | Integer | Oui¹ | Token ou UserLogin+Password² |
| TicketID | String/Array | Oui | Un ou plusieurs IDs de ticket |
Exemple de Requête :
DELETE /Webservice/MyConnectorREST/TicketDelete?SessionID=42&TicketID=12345 HTTP/1.1
Host: demo.otobo.orgExemple de Réponse :
{ "Success":1, "ErrorMessage":"", "Data":{} }3.6 TicketHistoryGet (GET)
URL : /Webservice/<ServiceName>/TicketHistoryGetMéthode : GET
Description : Récupère l'historique d'un ou plusieurs tickets.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
| SessionID | Integer | Oui¹ | Token ou UserLogin+Password² |
| TicketID | String/Array | Oui | Un ou plusieurs IDs de ticket |
Exemple de Requête :
GET /Webservice/MyConnectorREST/TicketHistoryGet?SessionID=42&TicketID=12345,5. Extension & Personnalisation
5.1 Définition WADL
Nouvelles ressources dans GenericTicketConnectorREST.wadl :
<resource path="MyTest" id="MyTest">
<method name="GET" id="GET_MyTest">
<response status="200">
<representation mediaType="application/json"/>
</response>
</method>
</resource>5.2 Import YAML
Alternativement via YAML dans development/webservices/GenericTicketConnectorREST.yml :
Provider:
Operation:
MyTest:
Description: "Opération de test"
MappingInbound: { }
MappingOutbound: { }
Type: Test::Module
Transport:
Config:
RouteOperationMapping:
MyTest:
RequestMethod: [ GET ]
Route: /MyTest6. Gestion des Erreurs & Journalisation
- Indicateur de succès :
Success: 0|1 - Message d'erreur :
ErrorMessagedans le JSON - Débogage : Réglez
Debug-LevelsurDebugdans la boîte de dialogue Transport → entrées de journal visibles dans la base de données
7. Cas d'Usage
| Scénario | Description |
|---|---|
| Automatisation inter-systèmes | Création de tickets depuis des outils de monitoring (Nagios, Zabbix) |
| Synchronisation de données | Mises à jour par lots des champs de tickets depuis un CRM externe |
| Portails Self-Service | Les clients créent leurs propres tickets via REST |
| Applications Mobiles | Applications natives iOS/Android communiquant via REST |
8. Autres Éléments d'Interface Utilisateur & Intégration
Clonage de Service Web
Module de Gestion des Erreurs
Conclusion
L'API REST OTOBO est flexible, performante et hautement extensible grâce à l'Interface Générique. Qu'il s'agisse de création de tickets simple ou d'automatisation de flux de travail complexes, avec quelques clics dans l'interface d'administration et des requêtes JSON standard, vous pouvez réaliser des intégrations transparentes dans n'importe quel paysage informatique.
Bibliothèque Client Python OTOBO
Une bibliothèque client Python asynchrone pour interagir avec l'API REST OTOBO. Construite avec httpx et pydantic pour la sécurité des types et la facilité d'utilisation.
Fonctionnalités
Requêtes HTTP asynchrones utilisant
httpx.AsyncClientModèles Pydantic pour la validation des données de requête et de réponse
Opérations CRUD complètes pour les tickets :
TicketCreateTicketSearchTicketGetTicketUpdateTicketHistoryGet
Gestion des erreurs via
OTOBOErrorpour les erreurs d'APIMéthode utilitaire
search_and_getpour combiner les résultats de recherche avec une récupération détaillée
Installation
Installez depuis PyPI :
pip install otoboDémarrage Rapide
Configuration des Services Web OTOBO :
Créez un nouveau service Web dans OTOBO avec la configuration suivante :
---
Debugger:
DebugThreshold: debug
TestMode: '0'
Description: ''
FrameworkVersion: 11.0.5
Provider:
Operation:
session-create:
Description: ''
IncludeTicketData: '0'
MappingInbound:
Type: Simple
MappingOutbound:
Type: Simple
Type: Session::SessionCreate
ticket-create:
Description: ''
IncludeTicketData: '1'
MappingInbound:
Type: Simple
MappingOutbound:
Type: Simple
Type: Ticket::TicketCreate
ticket-get:
Description: ''
IncludeTicketData: '0'
MappingInbound:
Config:
KeyMapDefault:
MapTo: ''
MapType: Keep
ValueMapDefault:
MapTo: ''
MapType: Keep
Type: Simple
MappingOutbound:
Type: Simple
Type: Ticket::TicketGet
ticket-history-get:
Description: ''
IncludeTicketData: '0'
MappingInbound:
Type: Simple
MappingOutbound:
Type: Simple
Type: Ticket::TicketHistoryGet
ticket-search:
Description: ''
IncludeTicketData: '0'
MappingInbound:
Type: Simple
MappingOutbound:
Type: Simple
Type: Ticket::TicketSearch
ticket-update:
Description: ''
IncludeTicketData: '1'
MappingInbound:
Type: Simple
MappingOutbound:
Type: Simple
Type: Ticket::TicketUpdate
Transport:
Config:
AdditionalHeaders: ~
KeepAlive: '1'
MaxLength: '16000'
RouteOperationMapping:
session-create:
RequestMethod:
- HEAD
- OPTIONS
- PATCH
- POST
- PUT
Route: /session
ticket-create:
RequestMethod:
- HEAD
- OPTIONS
- POST
Route: /ticket
ticket-get:
RequestMethod:
- HEAD
- OPTIONS
- POST
Route: /ticket/get
ticket-history-get:
RequestMethod:
- HEAD
- OPTIONS
- POST
Route: /ticket/history
ticket-search:
RequestMethod:
- HEAD
- OPTIONS
- POST
Route: /ticket/search
ticket-update:
RequestMethod:
- HEAD
- OPTIONS
- PATCH
- PUT
Route: /ticket
Type: HTTP::REST
RemoteSystem: ''
Requester:
Transport:
Type: HTTP::RESTCréer un nouvel Agent
Créez un nouvel Agent Otobo avec un mot de passe sécurisé et donnez-lui les permissions nécessaires pour accomplir la tâche souhaitée.
1. Configurer le client
from otobo import TicketOperation, OTOBOClientConfig
from otobo import AuthData
config = OTOBOClientConfig(
base_url="https://votre-serveur-otobo/nph-genericinterface.pl",
service="OTOBO",
auth=AuthData(UserLogin="user1", Password="SecurePassword"),
operations={
TicketOperation.CREATE.value: "ticket",
TicketOperation.SEARCH.value: "ticket/search",
TicketOperation.GET.value: "ticket/get",
TicketOperation.UPDATE.value: "ticket",
TicketOperation.HISTORY_GET.value: "ticket/history",
}
)2. Initialiser le client
import logging
from otobo import OTOBOClient
logging.basicConfig(level=logging.INFO)
client = OTOBOClient(config)3. Créer un ticket
from otobo import (TicketOperation, OTOBOClientConfig, AuthData, TicketSearchParams, TicketCreateParams,
TicketHistoryParams, TicketUpdateParams, \
TicketGetParams, OTOBOClient, OTOBOTicketCreateResponse)
payload = TicketCreateParams(
Ticket={
"Title": "Nouvelle Commande",
"Queue": "Sales",
"State": "new",
"Priority": "3 normal",
"CustomerUser": "customer@example.com"
},
Article={
"Subject": "Demande de Produit",
"Body": "Veuillez envoyer les détails des prix...",
"MimeType": "text/plain"
}
)
response: OTOBOTicketCreateResponse = await client.create_ticket(payload)
print(response.TicketID, response.TicketNumber)4. Rechercher et récupérer des tickets
from otobo import TicketSearchParams, TicketGetParams
search_params = TicketSearchParams(Title="%Commande%")
search_res = await client.search_tickets(search_params)
ids = search_res.TicketID
for ticket_id in ids:
get_params = TicketGetParams(TicketID=ticket_id, AllArticles=1)
details = await client.get_ticket(get_params)
print(details.Ticket[0])5. Mettre à jour un ticket
from otobo import TicketUpdateParams
update_params = TicketUpdateParams(
TicketID=response.TicketID,
Ticket={"State": "closed"}
)
await client.update_ticket(update_params)6. Obtenir l'historique des tickets
from otobo import TicketHistoryParams
history_params = TicketHistoryParams(TicketID=str(response.TicketID))
history_res = await client.get_ticket_history(history_params)
print(history_res.History)7. Recherche et récupération combinées
from otobo import FullTicketSearchResponse
full_res: FullTicketSearchResponse = await client.search_and_get(search_params)Licence
MIT © Softoft, Tobias A. Bueck