Custom OTOBO workflows & integrations
We build dependable web services, process management automations, and third-party integrations tailored to your IT landscape.

In this guide: Activate, configure, and integrate the OTOBO REST API (Generic Interface) into your applications.
Related: Web Services overview · OpenID Connect · Performance tuning · Professional support
In this comprehensive guide, you will learn how to activate, configure, and integrate the OTOBO REST API (part of the Generic Interface) into your own applications.
OTOBO provides its Generic Interface via REST and SOAP web services. The REST API communicates via HTTP(S)/JSON and enables:
Note: A standard installation does not contain preconfigured web services – you create them yourself in the admin module “Processes & Automation → Web Services”.
TicketCreate, TicketSearch, TicketGet, TicketUpdate, TicketDelete, TicketHistoryGet).
Base URL
https://YOUR-SERVER/otobo/nph-genericinterface.pl/Webservice/<YourServiceName>/Authentication
For each endpoint, you will find a detailed overview of parameters, possible responses, and practical examples here.
URL: /Webservice/<ServiceName>/TicketCreate
Method: POST
Description: Creates a new ticket and simultaneously creates an article.
| Parameter | Type | Required | Description |
|---|---|---|---|
| SessionID | Integer | Yes¹ | Session ID or UserLogin+Password |
| UserLogin | String | Yes² | Agent login (in combination with password) |
| Password | String | Yes² | Password (in combination with UserLogin) |
| Ticket.Title | String | Yes | Subject of the ticket |
| Ticket.Queue | String | Yes | Queue name or Ticket.QueueID |
| Ticket.State | String | Yes | Initial state (e.g., new) |
| Ticket.Priority | String | Yes | Priority (e.g., 3 normal) |
| Ticket.CustomerUser | String | Yes | Customer email or login |
| Article.Subject | String | Yes | Subject of the first article |
| Article.Body | String | Yes | Content of the first article |
| Article.MimeType | String | Yes | text/plain or text/html |
¹ Either SessionID OR UserLogin+Password required. ² If no SessionID token is available.
Example Request:
POST /Webservice/MyConnectorREST/TicketCreate HTTP/1.1Host: demo.otobo.orgContent-Type: application/jsonX-API-Key: abc123
{ "Data": { "SessionID": 42, "Ticket": { "Title": "New Order", "Queue": "Sales", "State": "new", "Priority": "3 normal", "CustomerUser": "max.mustermann@example.com" }, "Article": { "Subject": "Purchase Inquiry – Product XY", "Body": "Please provide a price quote…", "MimeType": "text/plain" } }}Example Response:
{ "Success": 1, "ErrorMessage": "", "Data": { "TicketID": "12345", "ArticleID": "67890" }}URL: /Webservice/<ServiceName>/TicketSearch
Method: GET
Description: Searches for tickets based on various filter criteria.
| Parameter | Type | Required | Description |
|---|---|---|---|
| UserLogin, Password | String,String | Yes¹ | Agent credentials or SessionID² |
| SessionID | Integer | Yes² | Token for authenticated sessions |
| Title | String/String[] | No | Wildcard search in title (%Order%) |
| TicketNumber | String/String[] | No | Ticket number(s) |
| QueueIDs | Integer[] | No | Queue IDs |
| States | String[] | No | States (new, open, …) |
| StateType | String/String[] | No | Open/Closed category |
| DynamicField_Name.Op | Mixed | No | Dynamic fields with operator (Equals, Like, GreaterThan …) |
¹ Either UserLogin+Password OR SessionID. ² If no login pair is provided.
Example Request:
GET /Webservice/MyConnectorREST/TicketSearch?UserLogin=agent1&Password=secret&Title=%25Order%25 HTTP/1.1Host: demo.otobo.orgExample Response:
{ "Success": 1, "Data": { "TicketID": [1001,1005,1012] }}URL: /Webservice/<ServiceName>/TicketGet
Method: GET
Description: Returns detailed ticket data including articles, attachments, and dynamic fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
| UserLogin, Password | String,String | Yes¹ | Agent credentials or SessionID² |
| SessionID | Integer | Yes² | Token for authenticated sessions |
| TicketID | String/String[] | Yes | One or more ticket IDs (comma-separated or array) |
| DynamicFields | Boolean (0/1) | No | 1 = Dynamic fields in result, default = 0 |
| Extended | Boolean | No | 1 = Extended metadata (e.g., FirstResponse) |
| AllArticles | Boolean | No | 1 = Return all articles |
| ArticleLimit | Integer | No | Max. number of returned articles |
| Attachments | Boolean | No | 1 = Embed attachments in Base64 |
| GetAttachmentContents | Boolean | No | 1 = Also load attachment contents |
| HTMLBodyAsAttachment | Boolean | No | 1 = Attach HTML version of the article as attachment |
¹ Either UserLogin+Password OR SessionID. ² If no login pair is provided.
Example Request:
GET /Webservice/MyConnectorREST/TicketGet?SessionID=42&TicketID=12345&AllArticles=1&DynamicFields=1 HTTP/1.1Host: demo.otobo.orgExample Response (abbreviated):
{ "Success":1, "Data":{ "Ticket":[{ "TicketID":12345, "TicketNumber":"202501230001", "Title":"New Order", "State":"open", "DynamicField":[{"Name":"Urgency","Value":"high"}], "Article":[{ "ArticleID":67890, "Subject":"Purchase Inquiry…", "Body":"Please provide a price quote…", "Attachment":[{"Filename":"Quote.pdf","Content":"JVBERi0x…="}] }] }] }}URL: /Webservice/<ServiceName>/TicketUpdate
Method: PUT
Description: Updates fields of an existing ticket and optionally creates a new article.
| Parameter | Type | Required | Description |
|---|---|---|---|
| SessionID | Integer | Yes¹ | Token or UserLogin+Password² |
| TicketID | Integer | Yes | ID of the ticket to update |
| Ticket.Title | String | No | New title |
| Ticket.State | String | No | New state |
| Ticket.Owner | String/ID | No | New owner |
| Ticket.PendingTime | Hash / Diff | No | New pending time |
| Article.Subject | String | No | Creates a new article |
| Article.Body | String | No | Content of the new article |
| DynamicField… | Array | No | Update dynamic fields |
| Attachment… | Array | No | Add new attachments |
¹ Either SessionID OR UserLogin+Password. ² If no SessionID token is available.
Example Request:
PUT /Webservice/MyConnectorREST/TicketUpdate HTTP/1.1Host: demo.otobo.orgContent-Type: application/jsonX-API-Key: abc123
{ "Data":{ "SessionID":42, "TicketID":12345, "Ticket":{ "State":"pending reminder","PendingTime":{"Diff":1440} }, "Article":{ "Subject":"Reminder set","Body":"Ticket is being processed." } }}Example Response:
{ "Success":1, "ErrorMessage":"", "Data":{ "TicketID":12345, "ArticleID":67891 } }URL: /Webservice/<ServiceName>/TicketDelete
Method: DELETE
Description: Permanently deletes one or more tickets.
| Parameter | Type | Required | Description |
|---|---|---|---|
| SessionID | Integer | Yes¹ | Token or UserLogin+Password² |
| TicketID | String/Array | Yes | One or more ticket IDs |
Example Request:
DELETE /Webservice/MyConnectorREST/TicketDelete?SessionID=42&TicketID=12345 HTTP/1.1Host: demo.otobo.orgExample Response:
{ "Success":1, "ErrorMessage":"", "Data":{} }URL: /Webservice/<ServiceName>/TicketHistoryGet
Method: GET
Description: Retrieves the history of one or more tickets.
| Parameter | Type | Required | Description |
|---|---|---|---|
| SessionID | Integer | Yes¹ | Token or UserLogin+Password² |
| TicketID | String/Array | Yes | One or more ticket IDs |
Example Request:
GET /Webservice/MyConnectorREST/TicketHistoryGet?SessionID=42&TicketID=12345 HTTP/1.1Host: demo.otobo.orgExample Response (abbreviated):
{ "Success": 1, "ErrorMessage": "", "Data": { "TicketID": 12345, "History": [ { "HistoryType": "NewTicket", "Name": "New ticket created", "CreateTime": "2025-01-23 09:15:00" }, { "HistoryType": "StateUpdate", "Name": "Changed state to open", "CreateTime": "2025-01-23 10:02:11" } ] }}New resources in GenericTicketConnectorREST.wadl:
<resource path="MyTest" id="MyTest"> <method name="GET" id="GET_MyTest"> <response status="200"> <representation mediaType="application/json"/> </response> </method></resource>Alternatively via YAML in development/webservices/GenericTicketConnectorREST.yml:
Provider: Operation: MyTest: Description: "Test operation" MappingInbound: { } MappingOutbound: { } Type: Test::ModuleTransport: Config:RouteOperationMapping: MyTest: RequestMethod: [ GET ] Route: /MyTestSuccess: 0|1ErrorMessage in JSONDebug-Level to Debug in the transport dialog → Log entries visible in DB| Scenario | Description |
|---|---|
| Cross-system automation | Create tickets from monitoring tools (Nagios, Zabbix) |
| Data synchronization | Batch updates of ticket fields from external CRM |
| Self-service portals | Customers create their own tickets via REST |
| Mobile apps | Native iOS/Android apps communicate via REST |
The OTOBO REST API is flexible, performant, and highly extensible thanks to the Generic Interface. Whether for simple ticket creation or complex workflow automation – with just a few clicks in the admin area and standard JSON requests, you can realize seamless integrations into any IT landscape.
No. A standard installation has no preconfigured web services. You create them yourself under Processes & Automation → Web Services (or import a YAML definition like the one shown above).
You authenticate either with a SessionID (created via a SessionCreate operation) or by passing UserLogin + Password with each request. Always use HTTPS so credentials and tokens are never sent in clear text.
https://YOUR-SERVER/otobo/nph-genericinterface.pl/Webservice/<YourServiceName>/. Each operation (e.g. TicketCreate) is then mapped to a route you define in the transport configuration.
Out of the box you can configure TicketCreate, TicketSearch, TicketGet, TicketUpdate, TicketDelete, and TicketHistoryGet. You can add custom operations via the GenericInterface.
Yes — the open-source library otai-ts-connector (Apache-2.0) is the current Python client for OTOBO, Znuny, Zammad, and KIX. See the quickstart and HTTP reference below.
When the Open Ticket AI connector package is installed, a preconfigured REST webservice named OpenTicketAI is available. Routes use kebab-case; authentication is sent as UserLogin and Password in the JSON body (Generic Interface — not as an Authorization header).
Base URL:
https://YOUR-SERVER/otobo/nph-genericinterface.pl/Webservice/OpenTicketAI/<route>Default API user after connector install: otai-webservice.
| Route | HTTP | Purpose |
|---|---|---|
/ticket-create | POST | Create ticket |
/ticket-get | POST | Retrieve ticket |
/ticket-search | POST | Search ticket IDs |
/ticket-update | PUT | Update ticket |
/queue-list | POST | List queues |
/state-list | POST | List states |
/priority-list | POST | List priorities |
/service-list | POST | List services |
/type-list | POST | List types |
/dynamic-field-list | POST | List dynamic fields |
/dynamic-field-values | POST | Dropdown values (parameter Name) |
/faq-search | POST | Search FAQ (parameter What) |
POST /otobo/nph-genericinterface.pl/Webservice/OpenTicketAI/ticket-create HTTP/1.1Host: otobo.example.comContent-Type: application/jsonAccept: application/json
{ "UserLogin": "otai-webservice", "Password": "secret", "Ticket": { "Title": "New order", "Queue": "Sales", "State": "new", "Priority": "3 normal", "CustomerUser": "customer@example.com" }, "Article": { "Subject": "Product inquiry", "Body": "Please send pricing details…", "ContentType": "text/plain" }}Response (simplified):
{ "TicketID": 12345, "TicketNumber": "202601010001", "ArticleID": 67890}POST /otobo/nph-genericinterface.pl/Webservice/OpenTicketAI/ticket-get HTTP/1.1Host: otobo.example.comContent-Type: application/json
{ "UserLogin": "otai-webservice", "Password": "secret", "TicketID": 12345, "AllArticles": 1}POST /otobo/nph-genericinterface.pl/Webservice/OpenTicketAI/queue-list HTTP/1.1Host: otobo.example.comContent-Type: application/json
{ "UserLogin": "otai-webservice", "Password": "secret"}Response (simplified):
{ "Item": [ { "ID": 2, "Name": "Sales", "ValidID": 1 } ]}OTOBO does not ship an OpenAPI schema — the Generic Interface is historically documented via WADL (see section 4.1). Official OTOBO docs do not include a ReDoc or Swagger UI either.
For the OpenTicketAI webservice we provide a community OpenAPI 3.1 specification:
/openapi-openticketai.yamlThe spec covers ticket and catalogue routes of the connector webservice. Standard Generic Interface webservices with custom route mappings are not included — use your transport YAML there.
otai-ts-connectorThe otai-ts-connector library is the unified Python client for OTOBO, Znuny, Zammad, and KIX (Apache-2.0, Python 3.14+). It replaces the former separate PyPI packages otobo and znuny.
| Capability | Port method |
|---|---|
| Connection check | test_connection() |
| Read / write tickets | get_ticket, create_ticket, update_ticket, add_note |
| FAQ | faq.get, faq.update, faq.list_ids |
| Catalogue / attributes | attributes.list, get_definition, dynamic_field_rows |
There is no find_tickets or faq.search on the product ports — search typically runs through an indexer (e.g. Meilisearch), not this SDK.
More documentation in the repository: OTOBO / Znuny provider.
Currently from git (PyPI may follow):
pip install git+https://github.com/Softoft-Orga/otai-ts-connector.gitimport asyncio
from otai_ts_connector import ( BuildTicketSystemParams, TicketSystemProvider, build_ticket_system,)
async def main() -> None: service = build_ticket_system( BuildTicketSystemParams( kind=TicketSystemProvider.OTOBO, base_url="https://otobo.example.com/otobo/nph-genericinterface.pl", username="otai-webservice", password="…", webservice_name="OpenTicketAI", ), ) await service.test_connection() ticket = await service.get_ticket("12345") print(ticket.subject)
asyncio.run(main())Under the hood the client sends the same HTTP requests as in the HTTP reference — e.g. POST …/ticket-get with UserLogin, Password, and TicketID in the JSON body.
Apache-2.0 © Softoft / Open Ticket AI
Custom OTOBO workflows & integrations
We build dependable web services, process management automations, and third-party integrations tailored to your IT landscape.
The OTOBO REST API is a key component of OTOBO's Generic Interface, enabling communication via HTTP(S) and JSON. It allows for robust integration of OTOBO with external applications, such as CRM or ERP systems. Its primary functionalities encompass a wide range of ticket operations, including creating, retrieving, updating, and deleting tickets. Beyond basic ticket management, the API also supports article operations, allowing users to post new articles and manage attachments associated with tickets. Furthermore, it provides capabilities for accessing ticket history and executing complex search queries, making it a versatile tool for automating and streamlining service management workflows within OTOBO.
Quellen / Sources:
To activate and configure the OTOBO REST API, you must first navigate to the Admin area. Here, you'll go to SysConfig and locate GenericInterface.Transport, changing its setting to REST (HTTP). Following this, within AdminGenericInterfaceTransportHTTPREST, you should configure crucial parameters such as timeouts, host headers, and debug levels to optimize performance and troubleshooting. The final configuration step involves creating and activating the specific operations you intend to use, such as TicketCreate, TicketSearch, TicketGet, TicketUpdate, TicketDelete, and TicketHistoryGet, under GenericInterface.Operation. It's important to remember that a standard OTOBO installation does not come with preconfigured web services, so these steps are vital for setting up your desired integrations.
Quellen / Sources:
Authentication for the OTOBO REST API primarily supports two methods: OTOBO session cookies and API keys/tokens. When making requests, you can either provide a SessionID or a combination of UserLogin and Password parameters. For enhanced security and integration with external applications, API keys or tokens are generally preferred, which can be generated and managed via SysConfig. A critical security measure is to always use HTTPS for all API communications. This ensures that all data exchanged between your application and OTOBO is encrypted, protecting sensitive information like credentials and ticket details from interception. Neglecting HTTPS can expose your system to significant security risks.
Quellen / Sources:
To create a new ticket using the TicketCreate endpoint, you would send a POST request to the URL /Webservice/<YourServiceName>/TicketCreate. The request body should be a JSON object containing the necessary ticket and article data. Essential parameters include Ticket.Title, Ticket.Queue, Ticket.State, Ticket.Priority, Ticket.CustomerUser, Article.Subject, Article.Body, and Article.MimeType. Authentication can be handled via SessionID or UserLogin and Password. For instance, a request might look like this:
{
"Data": {
"SessionID": 42,
"Ticket": {
"Title": "New Order",
"Queue": "Sales",
"State": "new",
"Priority": "3 normal",
"CustomerUser": "max.mustermann@example.com"
},
"Article": {
"Subject": "Purchase Inquiry – Product XY",
"Body": "Please provide a price quote…",
"MimeType": "text/plain"
}
}
}
Upon successful creation, the API will return a JSON response containing the TicketID and ArticleID.
Quellen / Sources:
The TicketSearch endpoint allows you to find tickets based on a wide array of filter criteria by sending a GET request to /Webservice/<YourServiceName>/TicketSearch. You can specify parameters directly in the URL query string. Authentication is required, typically via UserLogin and Password or a SessionID. Search criteria can include Title (supporting wildcard searches like %Order%), specific TicketNumbers, QueueIDs, States (e.g., new, open), or StateType (e.g., Open, Closed). For example, to search for tickets with 'Order' in their title using agent credentials, your request URL might be: GET /Webservice/MyConnectorREST/TicketSearch?UserLogin=agent1&Password=secret&Title=%25Order%25. The API will respond with a JSON object containing a list of TicketIDs that match your search criteria.
Quellen / Sources:
Yes, the OTOBO REST API's TicketSearch endpoint supports searching based on dynamic fields, offering powerful customization for your queries. You can filter by dynamic fields using the parameter format DynamicField_Name.Op, where Name is the name of your dynamic field and Op specifies the operator (e.g., Equals, Like, GreaterThan). This allows for highly specific searches beyond standard ticket attributes. For instance, if you have a dynamic field named 'CustomerReference', you could search for tickets where this field equals a certain value. While the general concept is supported, it's important to structure these parameters correctly in your URL query string, as the API expects a specific format for handling such complex search criteria. This capability significantly enhances the flexibility of ticket retrieval.
Quellen / Sources: