Ir al contenido

OTOBO Web Services – REST API

OTOBO REST API

En esta guía detallada aprenderá cómo activar, configurar e integrar la OTOBO REST API (parte de la Interfaz Genérica) en sus propias aplicaciones.

OTOBO proporciona su Interfaz Genérica a través de Web Services REST y SOAP. La REST API se comunica vía HTTP(S)/JSON y permite:

  • Operaciones de tickets: Crear, obtener, modificar, eliminar
  • Operaciones de artículos: Publicar, gestionar adjuntos
  • Historial y búsqueda: Historial de tickets y consultas de búsqueda complejas

Nota: Una instalación estándar no contiene Web Services preconfigurados; usted debe crearlos en el módulo de administración «Procesos y Automatización → Web Services».

  1. En el área de administración → SysConfigGenericInterface.Transport cambiar a REST (HTTP).
  2. En AdminGenericInterfaceTransportHTTPREST configurar los Timeouts, Host-Header y Debug-Level.
  3. En GenericInterface.Operation crear y activar las operaciones deseadas (p. ej., TicketCreate, TicketSearch, TicketGet, TicketUpdate, TicketDelete, TicketHistoryGet).

Añadir Web Service Web Service Provider

  • URL base

    https://SU-SERVIDOR/otobo/nph-genericinterface.pl/Webservice/<SuNombreDeServicio>/
  • Autenticación

    • Cookies de sesión de OTOBO
    • API-Keys / Token (crear vía SysConfig)
    • ¡Usar siempre HTTPS!

Configurar REST Requester

Para cada endpoint encontrará aquí una visión general detallada de los parámetros, posibles respuestas y ejemplos prácticos.

URL: /Webservice/<ServiceName>/TicketCreate Método: POST

Descripción: Crea un nuevo ticket y genera un artículo al mismo tiempo.

ParámetroTipoObligatorioDescripción
SessionIDIntegerSí¹Session-ID o UserLogin+Password
UserLoginStringSí²Login del agente (en combinación con Password)
PasswordStringSí²Contraseña (en combinación con UserLogin)
Ticket.TitleStringAsunto del ticket
Ticket.QueueStringNombre de la cola o Ticket.QueueID
Ticket.StateStringEstado inicial (p. ej., new)
Ticket.PriorityStringPrioridad (p. ej., 3 normal)
Ticket.CustomerUserStringE-mail o login del cliente
Article.SubjectStringAsunto del primer artículo
Article.BodyStringContenido del primer artículo
Article.MimeTypeStringtext/plain o text/html

¹ Se requiere SessionID O UserLogin+Password. ² Si no hay un token de SessionID disponible.

Ejemplo de Request:

POST /Webservice/MyConnectorREST/TicketCreate HTTP/1.1
Host: demo.otobo.org
Content-Type: application/json
X-API-Key: abc123
{
"Data": {
"SessionID": 42,
"Ticket": {
"Title": "Nuevo pedido",
"Queue": "Sales",
"State": "new",
"Priority": "3 normal",
"CustomerUser": "max.mustermann@example.com"
},
"Article": {
"Subject": "Consulta de compra – Producto XY",
"Body": "Solicito oferta de precio…",
"MimeType": "text/plain"
}
}
}

Ejemplo de respuesta:

{
"Success": 1,
"ErrorMessage": "",
"Data": {
"TicketID": "12345",
"ArticleID": "67890"
}
}

URL: /Webservice/<ServiceName>/TicketSearch Método: GET

Descripción: Busca tickets basándose en diversos criterios de filtro.

ParámetroTipoObligatorioDescripción
UserLogin, PasswordString,StringSí¹Credenciales del agente o SessionID²
SessionIDIntegerSí²Token para sesiones autenticadas
TitleString/String[]NoBúsqueda con comodines en el título (%Pedido%)
TicketNumberString/String[]NoNúmero(s) de ticket
QueueIDsInteger[]NoIDs de cola
StatesString[]NoEstados (new, open, …)
StateTypeString/String[]NoCategoría Open/Closed
DynamicField_Name.OpMixedNoCampos dinámicos con operador (Equals, Like, GreaterThan …)

¹ Se requiere UserLogin+Password O SessionID. ² Si no se pasa un par de login.

Ejemplo de Request:

GET /Webservice/MyConnectorREST/TicketSearch?UserLogin=agent1&Password=secreto&Title=%25Pedido%25 HTTP/1.1
Host: demo.otobo.org

Ejemplo de respuesta:

{
"Success": 1,
"Data": {
"TicketID": [1001,1005,1012]
}
}

URL: /Webservice/<ServiceName>/TicketGet Método: GET

Descripción: Devuelve datos detallados del ticket, incluyendo artículos, adjuntos y campos dinámicos.

ParámetroTipoObligatorioDescripción
UserLogin, PasswordString,StringSí¹Credenciales del agente o SessionID²
SessionIDIntegerSí²Token para sesiones autenticadas
TicketIDString/String[]Uno o varios Ticket-IDs (separados por coma o array)
DynamicFieldsBoolean (0/1)No1 = Campos dinámicos en el resultado, Default = 0
ExtendedBooleanNo1 = Metadatos extendidos (p. ej. FirstResponse)
AllArticlesBooleanNo1 = Devolver todos los artículos
ArticleLimitIntegerNoCantidad máx. de artículos devueltos
AttachmentsBooleanNo1 = Incrustar adjuntos en Base64
GetAttachmentContentsBooleanNo1 = Cargar también el contenido de los adjuntos
HTMLBodyAsAttachmentBooleanNo1 = Adjuntar versión HTML del artículo como adjunto

¹ Se requiere UserLogin+Password O SessionID. ² Si no se pasa un par de login.

Ejemplo de Request:

GET /Webservice/MyConnectorREST/TicketGet?SessionID=42&TicketID=12345&AllArticles=1&DynamicFields=1 HTTP/1.1
Host: demo.otobo.org

Ejemplo de respuesta (abreviado):

{
"Success":1,
"Data":{
"Ticket":[{
"TicketID":12345,
"TicketNumber":"202501230001",
"Title":"Nuevo pedido",
"State":"open",
"DynamicField":[{"Name":"Urgency","Value":"high"}],
"Article":[{
"ArticleID":67890,
"Subject":"Consulta de compra…",
"Body":"Solicito oferta de precio…",
"Attachment":[{"Filename":"Oferta.pdf","Content":"JVBERi0x…="}]
}]
}]
}
}

URL: /Webservice/<ServiceName>/TicketUpdate Método: PUT

Descripción: Actualiza campos de un ticket existente y opcionalmente crea un nuevo artículo.

ParámetroTipoObligatorioDescripción
SessionIDIntegerSí¹Token o UserLogin+Password²
TicketIDIntegerID del ticket a actualizar
Ticket.TitleStringNoNuevo título
Ticket.StateStringNoNuevo estado
Ticket.OwnerString/IDNoNuevo propietario
Ticket.PendingTimeHash / DiffNoNuevo tiempo de espera
Article.SubjectStringNoCrea un nuevo artículo
Article.BodyStringNoContenido del nuevo artículo
DynamicField…ArrayNoActualizar campos dinámicos
Attachment…ArrayNoAñadir nuevos adjuntos

¹ Se requiere SessionID O UserLogin+Password. ² Si no hay un token de SessionID disponible.

Ejemplo de Request:

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":"Recordatorio establecido","Body":"El ticket está siendo procesado." }
}
}

Ejemplo de respuesta:

{ "Success":1, "ErrorMessage":"", "Data":{ "TicketID":12345, "ArticleID":67891 } }

URL: /Webservice/<ServiceName>/TicketDelete Método: DELETE

Descripción: Elimina definitiva uno o varios tickets.

ParámetroTipoObligatorioDescripción
SessionIDIntegerSí¹Token o UserLogin+Password²
TicketIDString/ArrayUno o varios Ticket-IDs

Ejemplo de Request:

DELETE /Webservice/MyConnectorREST/TicketDelete?SessionID=42&TicketID=12345 HTTP/1.1
Host: demo.otobo.org

Ejemplo de respuesta:

{ "Success":1, "ErrorMessage":"", "Data":{} }

URL: /Webservice/<ServiceName>/TicketHistoryGet Método: GET

Descripción: Obtiene el historial de uno o varios tickets.

ParámetroTipoObligatorioDescripción
SessionIDIntegerSí¹Token o UserLogin+Password²
TicketIDString/ArrayUno o varios Ticket-IDs

Ejemplo de Request:

GET /Webservice/MyConnectorREST/TicketHistoryGet?SessionID=42&TicketID=12345,

Nuevos recursos en GenericTicketConnectorREST.wadl:

<resource path="MyTest" id="MyTest">
<method name="GET" id="GET_MyTest">
<response status="200">
<representation mediaType="application/json"/>
</response>
</method>
</resource>

Alternativamente vía YAML en development/webservices/GenericTicketConnectorREST.yml:

Provider:
Operation:
MyTest:
Description: "Operación de prueba"
MappingInbound: { }
MappingOutbound: { }
Type: Test::Module
Transport:
Config:
RouteOperationMapping:
MyTest:
RequestMethod: [ GET ]
Route: /MyTest

Añadir SOAP Provider


  • Indicador de éxito: Success: 0|1
  • Mensaje de error: ErrorMessage en el JSON
  • Debugging: Establezca en el diálogo de transporte Debug-Level en Debug → Entradas de log visibles en la DB

Webservice Debugger


EscenarioDescripción
Automatización entre sistemasCrear tickets desde herramientas de monitoreo (Nagios, Zabbix)
Sincronización de datosActualizaciones por lotes de campos de ticket desde un CRM externo
Portales de autoservicioLos clientes crean sus propios tickets vía REST
Aplicaciones móvilesApps nativas iOS/Android se comunican vía REST

Clonar Web Service Módulo de manejo de errores

La OTOBO REST API es flexible, eficiente y altamente extensible gracias a la Interfaz Genérica. Ya sea para la creación simple de tickets o para una automatización compleja de flujos de trabajo, con unos pocos clics en el Admin y peticiones JSON estándar, usted puede realizar integraciones fluidas en cualquier entorno de TI.

Un cliente de Python asíncrono para interactuar con la OTOBO REST API. Construido con httpx y pydantic para seguridad de tipos y facilidad de uso.

  • Asíncrono: Peticiones HTTP usando httpx.AsyncClient

  • Pydantic: Modelos para la validación de datos de petición y respuesta

  • Operaciones CRUD completas para tickets:

    • TicketCreate
    • TicketSearch
    • TicketGet
    • TicketUpdate
    • TicketHistoryGet
  • Manejo de errores: vía OTOBOError para errores de la API

  • Método de utilidad search_and_get para combinar resultados de búsqueda con recuperación detallada

Instalar desde PyPI:

Ventana de terminal
pip install otobo

Cree un nuevo Web Service en OTOBO con la siguiente configuración:

---
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::REST

Cree un nuevo agente de OTOBO con una contraseña segura y asígnele los permisos necesarios para la tarea que desea realizar.

from otobo import TicketOperation, OTOBOClientConfig
from otobo import AuthData
config = OTOBOClientConfig(
base_url="https://your-otobo-server/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",
}
)
import logging
from otobo import OTOBOClient
logging.basicConfig(level=logging.INFO)
client = OTOBOClient(config)
from otobo import (TicketOperation, OTOBOClientConfig, AuthData, TicketSearchParams, TicketCreateParams,
TicketHistoryParams, TicketUpdateParams, \
TicketGetParams, OTOBOClient, OTOBOTicketCreateResponse)
payload = TicketCreateParams(
Ticket={
"Title": "Nuevo pedido",
"Queue": "Sales",
"State": "new",
"Priority": "3 normal",
"CustomerUser": "customer@example.com"
},
Article={
"Subject": "Consulta de producto",
"Body": "Por favor, envíen detalles de precios...",
"MimeType": "text/plain"
}
)
response: OTOBOTicketCreateResponse = await client.create_ticket(payload)
print(response.TicketID, response.TicketNumber)
from otobo import TicketSearchParams, TicketGetParams
search_params = TicketSearchParams(Title="%Pedido%")
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])
from otobo import TicketUpdateParams
update_params = TicketUpdateParams(
TicketID=response.TicketID,
Ticket={"State": "closed"}
)
await client.update_ticket(update_params)
from otobo import TicketHistoryParams
history_params = TicketHistoryParams(TicketID=str(response.TicketID))
history_res = await client.get_ticket_history(history_params)
print(history_res.History)
from otobo import FullTicketSearchResponse
full_res: FullTicketSearchResponse = await client.search_and_get(search_params)

MIT © Softoft, Tobias A. Bueck