Open Ticket AI Runtime – Python Automation for OTOBO
In this guide: Where OTAI Runtime sits in OTOBO admin (Generic Interface, Python, on-premise). Full product docs: openticketai.com/en/docs/otai-runtime.
Related: Generic Agent · Web Services · REST API · OpenTicketAI product overview · OTOBO AI features
When built-in tools like the Generic Agent or Process Management reach their limits, you need a way to express richer logic: fetch tickets, evaluate conditions, call external APIs, update fields, and repeat — all under your control and on your infrastructure.
Open Ticket AI Runtime (OTAI Runtime) is an open-source, Python-based automation engine for exactly that. Despite the name, it is not limited to AI. You can use it for classical ticket routing, field updates, scheduled jobs, and integrations — and add AI classification or summarization only where it helps.
Source code: github.com/Softoft-Orga/open-ticket-ai (LGPL-2.1)
What OTAI Runtime does
Section titled “What OTAI Runtime does”OTAI Runtime runs as a containerized Python service (Docker or pip install) between your helpdesk and any logic you define. For OTOBO, it typically:
- Ingests tickets — via the Generic Interface (Web Services) using a dedicated technical user.
- Runs a pipeline — a sequence of pipes that pass context from step to step.
- Executes actions — update queue, priority, dynamic fields, add notes, call external systems, or run ML models locally.
- Logs everything — each pipe result is traceable for auditing and debugging.
Because processing stays on-premise, ticket content does not need to leave your network — an important difference from cloud-only automation tools.
flowchart LR
OTOBO["OTOBO\n(Generic Interface)"]
RT["OTAI Runtime\n(Python pipelines)"]
AI["Optional:\nlocal ML / LLM"]
EXT["Optional:\nexternal APIs"]
OTOBO <-->|REST| RT
RT --> AI
RT --> EXT
RT -->|update tickets| OTOBO
Pipes: if this, then do that
Section titled “Pipes: if this, then do that”The core idea is pipes: small, composable processing units wired together in YAML. Each pipe receives a shared context (results from earlier steps), runs its task, and produces a PipeResult for the next step.
Think of it as if this, then do that, chained:
| Pattern | Pipe type | Behavior |
|---|---|---|
| When (trigger) | IntervalTrigger, ExpressionPipe | Run only every N seconds, or when a condition is true |
| If (guard) | ExpressionPipe with fail() | Stop the pipeline when a check fails |
| Then (action) | FetchTicketsPipe, UpdateTicketPipe, AddNotePipe | Read or change tickets in OTOBO |
| Else / skip | SimpleSequentialRunner | Run run only when on succeeded |
Simple pipes
Section titled “Simple pipes”Atomic steps with one job — for example fetch tickets from a queue:
- id: fetch_tickets use: base:FetchTicketsPipe injects: ticket_system: otobo_znuny params: ticket_search_criteria: queue: name: Incoming limit: 10Composite pipes (multi-step workflows)
Section titled “Composite pipes (multi-step workflows)”A CompositePipe runs child steps in order and merges their results — ideal for full workflows:
- id: ticket_workflow use: base:CompositePipe steps: - id: fetch use: base:FetchTicketsPipe injects: { ticket_system: otobo_znuny } params: ticket_search_criteria: queue: { name: Incoming } limit: 10
- id: guard use: base:ExpressionPipe params: expression: > {{ fail() if (get_pipe_result('fetch', 'fetched_tickets') | length) == 0 else 'ok' }}
- id: update use: base:UpdateTicketPipe injects: { ticket_system: otobo_znuny } params: ticket_id: "{{ get_pipe_result('fetch', 'fetched_tickets') | first | attr('id') }}" updated_ticket: queue: name: SupportConditional execution
Section titled “Conditional execution”SimpleSequentialRunner implements classic if-then logic: execute run only when on succeeds (for example, when an interval trigger fires):
- id: run-when-triggered use: base:SimpleSequentialRunner params: on: id: gate use: base:IntervalTrigger params: { interval: PT60S } run: id: do-something use: base:ExpressionPipe params: { expression: Triggered run }Pipes share data through Jinja2 templates. Use get_pipe_result('pipe_id', 'data_key') to read output from earlier steps and has_failed('pipe_id') to branch on errors.
For background polling (daemon-style loops), SimpleSequentialOrchestrator repeats its steps endlessly — useful for continuous ticket processing.
How it connects to OTOBO
Section titled “How it connects to OTOBO”OTAI Runtime talks to OTOBO through the Generic Interface, the same mechanism described in Web Services and the REST API reference.
Typical setup:
- Technical user — create an agent such as
open_ticket_aiwith only the permissions your pipeline needs (ro,move_into,priority,note, etc.). - Web service — import the bundled
OpenTicketAI.ymltemplate from the GitHub repository. It exposes restricted REST operations (ticket-search,ticket-get,ticket-update,ticket-create) and maps all requests to the technical user. - Runtime config — point OTAI at your OTOBO URL and credentials via environment variables and
config.yml.
The OTOBO-side steps mirror a standard Web Services integration; the runtime adds the Python pipeline layer on top.
Detailed setup: OTOBO / Znuny plugin setup (Open Ticket AI docs)
Quick start
Section titled “Quick start”Install via pip
Section titled “Install via pip”pip install open-ticket-aipip install open-ticket-ai otai-otobo-znuny otai-hf-localRun with Docker
Section titled “Run with Docker”docker pull openticketai/engine:latestservices: open-ticket-ai: image: openticketai/engine:latest ports: - "8080:8080" environment: OT_AI_CONFIG: /app/config.yml volumes: - ./config.yml:/app/config.yml:roClone the repository for development:
git clone https://github.com/Softoft-Orga/open-ticket-ai.gitcd open-ticket-aiuv syncuv run -m pytestExample: classify and route tickets
Section titled “Example: classify and route tickets”The same pipe model supports AI and non-AI steps. A classification pipe can sit between fetch and update:
- id: classify use: otai_hf_local:HFLocalTextClassificationPipe params: model: bert-base-german-cased text: "{{ get_pipe_result('fetch', 'fetched_tickets') | first | attr('subject') }}"
- id: update use: base:UpdateTicketPipe injects: { ticket_system: otobo_znuny } params: ticket_id: "{{ get_pipe_result('fetch', 'fetched_tickets') | first | attr('id') }}" updated_ticket: queue: name: "{{ get_pipe_result('classify', 'predicted_queue') }}"Replace the classification pipe with any other pipe — keyword matching, HTTP calls, database lookups — and the workflow structure stays the same.
Extend with Python plugins
Section titled “Extend with Python plugins”Every pipe is a Python class registered in the pipe registry (base:FetchTicketsPipe, base:UpdateTicketPipe, …). You can:
- Configure existing pipes in YAML (no code required for many automations).
- Install community plugins from the plugin marketplace.
- Write custom pipes in Python when you need proprietary business logic, then reference them with
use: your_plugin:YourPipe.
The runtime uses dependency injection, structured logging, and pytest-based testing — see the developer documentation on openticketai.com.
When to use OTAI vs built-in automation
Section titled “When to use OTAI vs built-in automation”| Need | Built-in OTOBO | OTAI Runtime |
|---|---|---|
| Simple rules (queue, priority, time) | Generic Agent | Usually overkill |
| Guided agent/customer flows | Process Management | Different purpose |
| REST integration with external systems | Web Services | OTAI uses this under the hood |
| Multi-step logic, Python, ML, custom APIs | Limited | OTAI Runtime |
| On-premise AI without cloud APIs | Not built in | OTAI Runtime + local model plugins |
| Fully custom automation without AI | Generic Agent or scripts | OTAI Runtime (pipes, no ML required) |
Further reading
Section titled “Further reading”- GitHub repository: github.com/Softoft-Orga/open-ticket-ai
- Official OTAI Runtime docs: openticketai.com/en/docs/otai-runtime/
- Pipe system reference: Pipe System
- First pipeline tutorial: First Pipeline
- Product / AI solutions: OpenTicketAI for OTOBO
License: LGPL-2.1-only — suitable for extending and integrating in enterprise environments while keeping custom pipe code under your control.
Frequently asked questions
Does Open Ticket AI Runtime require an AI model?
No, Open Ticket AI Runtime (OTAI Runtime) is a versatile, open-source automation engine that is not limited to AI applications. While it can integrate AI models for tasks like classification or summarization, its core functionality allows for conventional automations such as ticket routing, updating ticket fields, executing scheduled jobs, and integrating with external systems, all without needing any AI model. The 'AI' in its name reflects its capability, not a strict requirement, offering flexibility for various automation needs on-premise.
Quellen / Sources:
How does Open Ticket AI Runtime connect and interact with OTOBO?
Open Ticket AI Runtime connects to OTOBO primarily through OTOBO's Generic Interface and REST web services. It operates as a containerized Python service (via Docker or pip install) positioned between your helpdesk and the custom logic you define. A typical setup involves creating a dedicated technical user in OTOBO with specific permissions, importing the bundled OpenTicketAI.yml web service template to expose restricted REST operations, and configuring the runtime with your OTOBO URL and credentials via environment variables or config.yml. This mirrors a standard Web Services integration, with the runtime adding a powerful Python pipeline layer on top for complex automation.
Quellen / Sources:
Can Open Ticket AI Runtime be deployed on-premise, and what are the benefits?
Yes, Open Ticket AI Runtime is specifically designed for on-premise deployment. It runs as a Python service or container (e.g., Docker) within your own infrastructure. This on-premise capability is a significant advantage, as it ensures that sensitive ticket content and other data do not need to leave your network. This addresses critical data privacy and security requirements, making it an ideal solution for organizations that cannot or prefer not to use cloud-only automation tools for their helpdesk operations. All processing and logging remain under your direct control.
Quellen / Sources:
What are 'Pipes' in Open Ticket AI Runtime, and how do they form workflows?
Pipes are the fundamental building blocks of automation workflows in Open Ticket AI Runtime. They are small, modular, and composable processing units defined in YAML. Each pipe has a specific task: it receives a shared context (which includes results from preceding steps), executes its defined task, and then produces a PipeResult that is passed to the next pipe in the sequence. This creates a chained 'if this, then do that' logic. For example, a FetchTicketsPipe might retrieve tickets, followed by an ExpressionPipe to evaluate conditions, and then an UpdateTicketPipe to modify ticket attributes. This modular design allows for highly flexible and customizable automation flows.
Quellen / Sources:
How does Open Ticket AI Runtime support conditional execution and complex multi-step workflows?
Open Ticket AI Runtime provides robust mechanisms for conditional execution and building complex multi-step workflows. The SimpleSequentialRunner implements classic 'if-then' logic, executing a run pipe only if an on pipe succeeds (e.g., an IntervalTrigger fires). For more intricate workflows, a CompositePipe allows you to define a sequence of child steps that are executed in order, with their results merged. Pipes share data through Jinja2 templates, enabling dynamic logic; you can use get_pipe_result('pipe_id', 'data_key') to access output from earlier steps or has_failed('pipe_id') to branch based on previous pipe failures. For continuous, daemon-style operations, the SimpleSequentialOrchestrator can repeat its steps endlessly, making it suitable for ongoing ticket processing.
Quellen / Sources:
What are typical use cases for Open Ticket AI Runtime in an OTOBO environment?
Open Ticket AI Runtime extends OTOBO's automation capabilities for various scenarios. Typical use cases include:
- Automated Ticket Routing: Fetching new tickets and dynamically assigning them to specific queues, agents, or teams based on complex criteria, keywords, or even AI-driven classification.
- Dynamic Field Updates: Automatically modifying ticket properties like priority, state, or custom dynamic fields based on ticket content, external data, or time-based conditions.
- Scheduled Maintenance & Reports: Executing routine tasks such as archiving old tickets, generating periodic reports, or sending automated reminders.
- External System Integrations: Calling external APIs to enrich ticket data (e.g., customer information from a CRM) or trigger actions in other business systems.
- AI-Powered Assistance: Integrating local machine learning models for tasks like classifying ticket intent, summarizing long customer communications, or extracting key entities, enhancing agent efficiency. This allows for highly customized and powerful automations beyond OTOBO's built-in tools.
Quellen / Sources: