OTOBO / Znuny Web Services – REST API

Neste guia detalhado, você aprenderá como ativar, configurar e integrar a OTOBO REST API (parte da Interface Genérica) em suas próprias aplicações.
1. Arquitetura & Fundamentos
OTOBO fornece sua Interface Genérica através de web services REST e SOAP. A REST API comunica via HTTP(S)/JSON e permite:
- Operações de Ticket: Criar, Obter, Modificar, Excluir
- Operações de Artigo: Postar, Gerenciar anexos
- Histórico & Pesquisa: Histórico de tickets e consultas de pesquisa complexas
Nota: Uma instalação padrão não inclui web services pré-configurados – você os cria você mesmo no módulo Admin “Processos & Automação → Web Services”.
2. Configuração
2.1 Ativar Interface Genérica
- Na área Admin → SysConfig → GenericInterface.Transport, mude para REST (HTTP).
- Em AdminGenericInterfaceTransportHTTPREST, configure timeouts, cabeçalho do host e nível de depuração.
- Em GenericInterface.Operation, crie e ative as operações desejadas (por exemplo,
TicketCreate,TicketSearch,TicketGet,TicketUpdate,TicketDelete,TicketHistoryGet).
2.2 URL Base & Autenticação
URL Base
https://SEU-SERVIDOR/otobo/nph-genericinterface.pl/Webservice/<SeuServiceName>/Autenticação
- Cookies de sessão OTOBO
- Chaves de API / Tokens (criar via SysConfig)
- Sempre usar HTTPS!
3. Endpoints & Métodos HTTP (Detalhe)
Para cada endpoint, você encontrará aqui uma visão detalhada de parâmetros, respostas possíveis e exemplos práticos.
3.1 TicketCreate (POST)
URL: /Webservice/<ServiceName>/TicketCreateMétodo: POST
Descrição: Cria um novo ticket e um artigo ao mesmo tempo.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| SessionID | Integer | Sim¹ | ID de sessão ou UserLogin+Password |
| UserLogin | String | Sim² | Login do agente (em combinação com Password) |
| Password | String | Sim² | Senha (em combinação com UserLogin) |
| Ticket.Title | String | Sim | Assunto do ticket |
| Ticket.Queue | String | Sim | Nome da fila ou Ticket.QueueID |
| Ticket.State | String | Sim | Estado inicial (por exemplo, new) |
| Ticket.Priority | String | Sim | Prioridade (por exemplo, 3 normal) |
| Ticket.CustomerUser | String | Sim | E-mail ou login do cliente |
| Article.Subject | String | Sim | Assunto do primeiro artigo |
| Article.Body | String | Sim | Conteúdo do primeiro artigo |
| Article.MimeType | String | Sim | text/plain ou text/html |
¹ É necessária SessionID OU UserLogin+Password. ² Se nenhum token SessionID for fornecido.
Exemplo de Requisição:
POST /Webservice/MyConnectorREST/TicketCreate HTTP/1.1
Host: demo.otobo.org
Content-Type: application/json
X-API-Key: abc123
{
"Data": {
"SessionID": 42,
"Ticket": {
"Title": "Novo Pedido",
"Queue": "Vendas",
"State": "new",
"Priority": "3 normal",
"CustomerUser": "max.mustermann@example.com"
},
"Article": {
"Subject": "Solicitação de compra – Produto XY",
"Body": "Por favor, envie uma cotação…",
"MimeType": "text/plain"
}
}
}Exemplo de Resposta:
{
"Success": 1,
"ErrorMessage": "",
"Data": {
"TicketID": "12345",
"ArticleID": "67890"
}
}3.2 TicketSearch (GET)
URL: /Webservice/<ServiceName>/TicketSearchMétodo: GET
Descrição: Pesquisa tickets com base em vários critérios de filtro.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| UserLogin, Password | String,String | Sim¹ | Credenciais do agente ou SessionID² |
| SessionID | Integer | Sim² | Token para sessões autenticadas |
| Title | String/String[] | Não | Pesquisa com curinga no título (%Pedido%) |
| TicketNumber | String/String[] | Não | Número(s) do ticket |
| QueueIDs | Integer[] | Não | IDs das filas |
| States | String[] | Não | Estados (new, open, …) |
| StateType | String/String[] | Não | Categoria Aberto/Fechado |
| DynamicField_Name.Op | Mixed | Não | Campos dinâmicos com operador (Equals, Like, GreaterThan …) |
¹ É necessário UserLogin+Password OU SessionID. ² Se nenhum par de login for passado.
Exemplo de Requisição:
GET /Webservice/MyConnectorREST/TicketSearch?UserLogin=agente1&Password=secreto&Title=%25Pedido%25 HTTP/1.1
Host: demo.otobo.orgExemplo de Resposta:
{
"Success": 1,
"Data": {
"TicketID": [1001,1005,1012]
}
}3.3 TicketGet (GET)
URL: /Webservice/<ServiceName>/TicketGetMétodo: GET
Descrição: Retorna dados detalhados do ticket, incluindo artigos, anexos e campos dinâmicos.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| UserLogin, Password | String,String | Sim¹ | Credenciais do agente ou SessionID² |
| SessionID | Integer | Sim² | Token para sessões autenticadas |
| TicketID | String/String[] | Sim | Um ou mais IDs de ticket (separados por vírgula ou array) |
| DynamicFields | Boolean (0/1) | Não | 1 = Campos dinâmicos no resultado, Padrão = 0 |
| Extended | Boolean | Não | 1 = Metadados estendidos (por exemplo, FirstResponse) |
| AllArticles | Boolean | Não | 1 = Retornar todos os artigos |
| ArticleLimit | Integer | Não | Número máximo de artigos retornados |
| Attachments | Boolean | Não | 1 = Incorporar anexos em Base64 |
| GetAttachmentContents | Boolean | Não | 1 = Carregar também os conteúdos dos anexos |
| HTMLBodyAsAttachment | Boolean | Não | 1 = Anexar a versão HTML do artigo como anexo |
¹ É necessário UserLogin+Password OU SessionID. ² Se nenhum par de login for passado.
Exemplo de Requisição:
GET /Webservice/MyConnectorREST/TicketGet?SessionID=42&TicketID=12345&AllArticles=1&DynamicFields=1 HTTP/1.1
Host: demo.otobo.orgExemplo de Resposta (truncado):
{
"Success":1,
"Data":{
"Ticket":[{
"TicketID":12345,
"TicketNumber":"202501230001",
"Title":"Novo Pedido",
"State":"open",
"DynamicField":[{"Name":"Urgency","Value":"high"}],
"Article":[{
"ArticleID":67890,
"Subject":"Solicitação de compra…",
"Body":"Por favor, envie uma cotação…",
"Attachment":[{"Filename":"Oferta.pdf","Content":"JVBERi0x…="}]
}]
}]
}
}3.4 TicketUpdate (PUT)
URL: /Webservice/<ServiceName>/TicketUpdateMétodo: PUT
Descrição: Atualiza campos de um ticket existente e opcionalmente cria um novo artigo.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| SessionID | Integer | Sim¹ | Token ou UserLogin+Password² |
| TicketID | Integer | Sim | ID do ticket a ser atualizado |
| Ticket.Title | String | Não | Novo título |
| Ticket.State | String | Não | Novo status |
| Ticket.Owner | String/ID | Não | Novo proprietário |
| Ticket.PendingTime | Hash / Diff | Não | Novo tempo de pendência |
| Article.Subject | String | Não | Cria um novo artigo |
| Article.Body | String | Não | Conteúdo do novo artigo |
| DynamicField… | Array | Não | Atualiza campos dinâmicos |
| Attachment… | Array | Não | Adiciona novos anexos |
¹ É necessário SessionID OU UserLogin+Password. ² Se nenhum token SessionID for fornecido.
Exemplo de Requisição:
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":"Lembrete definido","Body":"Ticket está sendo processado." }
}
}Exemplo de Resposta:
{ "Success":1, "ErrorMessage":"", "Data":{ "TicketID":12345, "ArticleID":67891 } }3.5 TicketDelete (DELETE)
URL: /Webservice/<ServiceName>/TicketDeleteMétodo: DELETE
Descrição: Exclui permanentemente um ou mais tickets.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| SessionID | Integer | Sim¹ | Token ou UserLogin+Password² |
| TicketID | String/Array | Sim | Um ou mais IDs de ticket |
Exemplo de Requisição:
DELETE /Webservice/MyConnectorREST/TicketDelete?SessionID=42&TicketID=12345 HTTP/1.1
Host: demo.otobo.orgExemplo de Resposta:
{ "Success":1, "ErrorMessage":"", "Data":{} }3.6 TicketHistoryGet (GET)
URL: /Webservice/<ServiceName>/TicketHistoryGetMétodo: GET
Descrição: Obtém o histórico de um ou mais tickets.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| SessionID | Integer | Sim¹ | Token ou UserLogin+Password² |
| TicketID | String/Array | Sim | Um ou mais IDs de ticket |
Exemplo de Requisição:
GET /Webservice/MyConnectorREST/TicketHistoryGet?SessionID=42&TicketID=12345,5. Extensão & Personalização
5.1 Definição WADL
Novos recursos em 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 Importação YAML
Alternativamente via YAML em development/webservices/GenericTicketConnectorREST.yml:
Provider:
Operation:
MyTest:
Description: "Operação de teste"
MappingInbound: { }
MappingOutbound: { }
Type: Test::Module
Transport:
Config:
RouteOperationMapping:
MyTest:
RequestMethod: [ GET ]
Route: /MyTest6. Tratamento de Erros & Logging
- Indicador de Sucesso:
Success: 0|1 - Mensagem de Erro:
ErrorMessageno JSON - Depuração: Defina
Debug-LevelparaDebugno diálogo do transporte → Entradas de log visíveis no DB
7. Casos de Uso
| Cenário | Descrição |
|---|---|
| Automação Inter-Sistemas | Criação de tickets a partir de ferramentas de monitoramento (Nagios, Zabbix) |
| Sincronização de Dados | Atualizações em lote de campos de ticket a partir de CRM externo |
| Portais de Autoatendimento | Clientes criam seus próprios tickets via REST |
| Aplicativos Móveis | Aplicativos nativos iOS/Android se comunicam via REST |
8. Outros Elementos de UI & Integração
Clonar Web Service
Módulo de Tratamento de Erros
Conclusão
A OTOBO REST API é flexível, performática e altamente extensível graças à Interface Genérica. Seja para criação simples de tickets ou automação complexa de fluxos de trabalho – com poucos cliques no Admin e requisições JSON padrão, você pode implementar integrações perfeitas em qualquer paisagem de TI.
Biblioteca Cliente Python OTOBO
Uma biblioteca cliente Python assíncrona para interagir com a OTOBO REST API. Construída com httpx e pydantic para segurança de tipo e facilidade de uso.
Funcionalidades
Requisições HTTP assíncronas usando
httpx.AsyncClientModelos Pydantic para validação de dados de requisição e resposta
Operações CRUD completas para tickets:
TicketCreateTicketSearchTicketGetTicketUpdateTicketHistoryGet
Método de tratamento de erros
OTOBOErrorpara erros de APIMétodo utilitário
search_and_getpara combinar resultados de pesquisa com recuperação detalhada
Instalação
Instale a partir do PyPI:
pip install otoboGuia Rápido
Configurar Web Services OTOBO:
Crie um novo web service no OTOBO com a seguinte configuração:
---
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::RESTCriar um novo Agente
Crie um novo Agente OTOBO com uma senha segura e conceda as permissões necessárias para a tarefa que você deseja realizar.
1. Configurar o cliente
from otobo import TicketOperation, OTOBOClientConfig
from otobo import AuthData
config = OTOBOClientConfig(
base_url="https://seu-servidor-otobo/nph-genericinterface.pl",
service="OTOBO",
auth=AuthData(UserLogin="usuario1", Password="SenhaSegura"),
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. Inicializar o cliente
import logging
from otobo import OTOBOClient
logging.basicConfig(level=logging.INFO)
client = OTOBOClient(config)3. Criar um ticket
from otobo import (TicketOperation, OTOBOClientConfig, AuthData, TicketSearchParams, TicketCreateParams,
TicketHistoryParams, TicketUpdateParams, \
TicketGetParams, OTOBOClient, OTOBOTicketCreateResponse)
payload = TicketCreateParams(
Ticket={
"Title": "Novo Pedido",
"Queue": "Vendas",
"State": "new",
"Priority": "3 normal",
"CustomerUser": "cliente@example.com"
},
Article={
"Subject": "Consulta de Produto",
"Body": "Por favor, envie detalhes de preços...",
"MimeType": "text/plain"
}
)
response: OTOBOTicketCreateResponse = await client.create_ticket(payload)
print(response.TicketID, response.TicketNumber)4. Pesquisar e recuperar tickets
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])5. Atualizar um ticket
from otobo import TicketUpdateParams
update_params = TicketUpdateParams(
TicketID=response.TicketID,
Ticket={"State": "closed"}
)
await client.update_ticket(update_params)6. Obter histórico de 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. Pesquisa e obtenção combinadas
from otobo import FullTicketSearchResponse
full_res: FullTicketSearchResponse = await client.search_and_get(search_params)Licença
MIT © Softoft, Tobias A. Bueck