Referência da API
Endpoints disponíveis para tokens de acesso pessoal
Referência dos endpoints da API REST do OpsScript acessíveis com tokens de acesso pessoal (ops_pat_...). Para criar um token, conceder escopos e entender o fluxo de aprovação, veja Integração e APIs.
Autenticação
Todas as chamadas usam o header x-api-key com o token completo. A URL base é https://api.opsscript.io e todas as rotas têm o prefixo /api/v1.
curl -H "x-api-key: ops_pat_seu_token_aqui" \
https://api.opsscript.io/api/v1/ticketO token só acessa os endpoints cobertos pelos escopos concedidos (em interseção com as permissões do usuário criador) e apenas na organização escolhida na criação: listagens são automaticamente restritas à organização do token, e qualquer referência a outra organização — filtro organization_id divergente, chamado de outra organização — retorna 403 com código PAT_010. Chamadas fora do escopo retornam 403 com código PAT_002.
Convenções
Paginação
Endpoints de listagem aceitam actual_page (padrão 1) e limit (padrão 10) como query params e respondem no envelope:
{
"page": 1,
"pageCount": 5,
"totalRecords": 42,
"items": []
}Erros
{ "code": "PAT_002", "message": "token scopes do not allow this action" }| Status | Significado |
|---|---|
200 / 201 | Sucesso / recurso criado |
207 | Operação em lote — verifique o resultado por item |
400 | Dados inválidos |
401 | Token inválido, expirado, revogado ou aguardando aprovação (PAT_001) |
402 | Limite do plano atingido |
403 | Fora do escopo do token (PAT_002), IP não autorizado (PAT_003) ou recurso de outra organização (PAT_010) |
404 | Recurso não encontrado |
Escopos × endpoints
| Escopo | Endpoints |
|---|---|
tickets:read | GET /ticket, GET /ticket/:id |
tickets:write | POST /ticket, PATCH /ticket, PATCH /ticket/assume-many |
tickets:close | PUT /ticket/:id/open-close, PATCH /ticket/complete-many, PUT /ticket/:id/archive, PATCH /ticket/archive-many |
comments:read | GET /ticket/:id/comment, GET /comment/:id |
comments:write | POST /comment |
time:read | GET /ticket_agent_time, GET /ticket/:id/time-tracking, GET /ticket/time-tracking/active |
time:write | POST /ticket_agent_time, PUT /ticket_agent_time/:id, POST /ticket/:id/time-tracking/start|stop |
attachments:read | GET /ticket/:ticket_id/attachment, GET /ticket_attachment/:id, GET /ticket_attachment/:id/url |
attachments:write | POST /ticket_attachment |
Os dados de referência (prioridades, tipos e status) são acessíveis por qualquer token válido, sem escopo específico.
Chamados
Listar chamados
GET /api/v1/ticketEscopo: tickets:read. Query params (todos opcionais):
| Parâmetro | Descrição |
|---|---|
actual_page, limit | Paginação |
subject | Busca por título; "1042" ou "#1042" busca pelo número exato do chamado |
description | Busca no corpo do chamado |
status_id, priority_id | Filtro por id de status/prioridade |
status_types | CSV de tipos de status: open,pending,done,in_progress,archived |
type_ids | CSV de ids de tipo de chamado |
tag_names | CSV de tags |
agent_id, create_user_id, involved_user_id | Filtros por usuário (involved_user_id aceita me) |
project_id, sprint_id | Filtros por vínculo |
organization_id | Sempre fixado na organização do token (valor divergente → 403 PAT_010) |
only_active | true exclui arquivados/concluídos |
order_by | subject, created_at, status, agent_name, organization_name, priority, type, sla, ticket_number |
order | asc ou desc |
curl -G https://api.opsscript.io/api/v1/ticket \
-H "x-api-key: ops_pat_seu_token_aqui" \
-d "actual_page=1" \
-d "limit=20" \
-d "status_types=open,in_progress" \
-d "order_by=created_at" \
-d "order=desc"Resposta 200:
{
"page": 1,
"pageCount": 3,
"totalRecords": 42,
"items": [
{
"id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"ticket_number": 1042,
"subject": "Erro 500 no checkout",
"description": "<p>Detalhes do incidente...</p>",
"description_format": "html",
"organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b",
"organization_name": "Minha Empresa",
"agent_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
"agent_name": "Ana Souza",
"priority_id": 3,
"priority": "Alta",
"type_id": 2,
"type": "Incidente",
"status_id": 1,
"status": "Aberto",
"status_type": "open",
"project_id": null,
"sla": "2026-07-23T18:00:00Z",
"tags": ["produção", "checkout"],
"last_activity_at": "2026-07-22T14:32:10Z",
"created_at": "2026-07-22T13:05:44Z",
"updated_at": "2026-07-22T14:32:10Z"
}
]
}Consultar um chamado
GET /api/v1/ticket/{id}Escopo: tickets:read. Sem query params além do path.
curl https://api.opsscript.io/api/v1/ticket/0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d \
-H "x-api-key: ops_pat_seu_token_aqui"Resposta 200: o mesmo objeto Ticket do exemplo acima (item da listagem), completo.
Criar chamado
POST /api/v1/ticketEscopo: tickets:write.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
organization_id | string | ✅ | Organização do chamado (deve ser a organização do token) |
subject | string | ✅ | Título |
description | string | — | Corpo do chamado |
description_format | string | — | html (padrão) ou markdown |
priority_id | int | — | Id de prioridade (veja dados de referência) |
type_id | int | — | Id do tipo de chamado |
status_id | int | — | Id do status inicial (padrão: aberto) |
project_id | string | — | Vincula a um projeto da mesma organização |
agent_id | string | — | Atribui a um agente |
Payload:
{
"organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b",
"subject": "Erro 500 no checkout",
"description": "Ao finalizar a compra a API retorna 500. Stack trace em anexo.",
"description_format": "markdown",
"priority_id": 3,
"type_id": 2
}curl -X POST https://api.opsscript.io/api/v1/ticket \
-H "x-api-key: ops_pat_seu_token_aqui" \
-H "Content-Type: application/json" \
-d '{
"organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b",
"subject": "Erro 500 no checkout",
"description": "Ao finalizar a compra a API retorna 500.",
"description_format": "markdown",
"priority_id": 3,
"type_id": 2
}'Resposta 201: o Ticket criado (mesmo shape da consulta). 402 se o limite de chamados do plano foi atingido.
Atualizar chamado
PATCH /api/v1/ticketEscopo: tickets:write.
Este endpoint exige o header adicional X-Action: single. Sem ele a requisição é rejeitada com 400.
Body: objeto Ticket com id, organization_id e os campos a alterar (subject, description, status_id, priority_id, agent_id, ...).
Payload:
{
"id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b",
"status_id": 2,
"priority_id": 4
}curl -X PATCH https://api.opsscript.io/api/v1/ticket \
-H "x-api-key: ops_pat_seu_token_aqui" \
-H "X-Action: single" \
-H "Content-Type: application/json" \
-d '{
"id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b",
"status_id": 2,
"priority_id": 4
}'Resposta 200: o chamado atualizado.
Assumir chamados
PATCH /api/v1/ticket/assume-manyEscopo: tickets:write. Body é um array (funciona para um ou vários chamados); o agente atribuído é o dono do token.
Payload:
[
{ "ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d", "organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b" },
{ "ticket_id": "1e8a3b47-6c2d-4f9e-8b1a-3d5c7e9f0a2b", "organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b" }
]curl -X PATCH https://api.opsscript.io/api/v1/ticket/assume-many \
-H "x-api-key: ops_pat_seu_token_aqui" \
-H "Content-Type: application/json" \
-d '[{ "ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d", "organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b" }]'Resposta 207 Multi-Status com o resultado por item:
[
{ "id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d", "error": false },
{ "id": "1e8a3b47-6c2d-4f9e-8b1a-3d5c7e9f0a2b", "error": false }
]Concluir / reabrir chamado
PUT /api/v1/ticket/{id}/open-closeEscopo: tickets:close. Sem body — alterna o estado: chamado aberto é concluído; chamado concluído é reaberto.
curl -X PUT https://api.opsscript.io/api/v1/ticket/0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d/open-close \
-H "x-api-key: ops_pat_seu_token_aqui"Resposta 200: o Ticket.
Concluir em lote
PATCH /api/v1/ticket/complete-manyEscopo: tickets:close. Mesmo payload e resposta (207) do assumir chamados — move os chamados para concluído.
curl -X PATCH https://api.opsscript.io/api/v1/ticket/complete-many \
-H "x-api-key: ops_pat_seu_token_aqui" \
-H "Content-Type: application/json" \
-d '[{ "ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d", "organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b" }]'Arquivar chamado
PUT /api/v1/ticket/{id}/archiveEscopo: tickets:close. Sem body.
curl -X PUT https://api.opsscript.io/api/v1/ticket/0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d/archive \
-H "x-api-key: ops_pat_seu_token_aqui"Resposta 200: o Ticket com status_type: "archived".
Arquivar em lote
PATCH /api/v1/ticket/archive-manyEscopo: tickets:close.
Atenção: diferente dos demais endpoints em lote, aqui o campo do payload é id (não ticket_id).
Payload:
[
{ "id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d" },
{ "id": "1e8a3b47-6c2d-4f9e-8b1a-3d5c7e9f0a2b" }
]curl -X PATCH https://api.opsscript.io/api/v1/ticket/archive-many \
-H "x-api-key: ops_pat_seu_token_aqui" \
-H "Content-Type: application/json" \
-d '[{ "id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d" }]'Resposta 200.
Comentários
Listar comentários de um chamado
GET /api/v1/ticket/{id}/commentEscopo: comments:read. Query params:
| Parâmetro | Descrição |
|---|---|
actual_page, limit | Paginação |
create_user_id | Filtra por autor |
order | asc ou desc |
curl -G https://api.opsscript.io/api/v1/ticket/0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d/comment \
-H "x-api-key: ops_pat_seu_token_aqui" \
-d "actual_page=1" \
-d "limit=20" \
-d "order=asc"Resposta 200:
{
"page": 1,
"pageCount": 1,
"totalRecords": 2,
"items": [
{
"id": "3f7a9b1c-8d2e-4a6f-9c0b-5e1d7a3b9f4c",
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"description": "Deploy do fix aplicado em produção.",
"description_format": "markdown",
"agent_only": true,
"create_user_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
"user_name": "Ana Souza",
"reply_to_comment_id": null,
"created_at": "2026-07-22T15:10:02Z",
"updated_at": "2026-07-22T15:10:02Z"
}
]
}Consultar um comentário
GET /api/v1/comment/{id}Escopo: comments:read. Sem query params.
curl https://api.opsscript.io/api/v1/comment/3f7a9b1c-8d2e-4a6f-9c0b-5e1d7a3b9f4c \
-H "x-api-key: ops_pat_seu_token_aqui"Resposta 200: o objeto Comment (mesmo shape do item da listagem).
Comentar em um chamado
POST /api/v1/commentEscopo: comments:write.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
ticket_id | string | ✅ | Chamado a comentar |
description | string | ✅ | Conteúdo do comentário |
description_format | string | — | html (padrão) ou markdown |
agent_only | bool | — | true = comentário interno, visível só para agentes |
reply_to_comment_id | string | — | Responde a outro comentário |
Payload:
{
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"description": "Deploy do fix aplicado em produção.",
"description_format": "markdown",
"agent_only": true
}curl -X POST https://api.opsscript.io/api/v1/comment \
-H "x-api-key: ops_pat_seu_token_aqui" \
-H "Content-Type: application/json" \
-d '{
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"description": "Deploy do fix aplicado em produção.",
"description_format": "markdown",
"agent_only": true
}'Resposta 200: o Comment criado.
Apontamentos de tempo
Listar apontamentos
GET /api/v1/ticket_agent_timeEscopo: time:read. Query params:
| Parâmetro | Descrição |
|---|---|
actual_page, limit | Paginação |
ticket_id | Filtra por chamado |
agent_id | Filtra por agente |
is_billable | true ou false |
order | asc ou desc |
curl -G https://api.opsscript.io/api/v1/ticket_agent_time \
-H "x-api-key: ops_pat_seu_token_aqui" \
-d "ticket_id=0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d" \
-d "actual_page=1" \
-d "limit=20"Resposta 200:
{
"page": 1,
"pageCount": 1,
"totalRecords": 1,
"items": [
{
"id": "5c2d8e4f-1a7b-4c9d-8e3f-6b0a2c4d8e1f",
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"time_interval": "1h30m0s",
"agent_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
"is_billable": true,
"created_at": "2026-07-22T16:00:00Z"
}
]
}Criar apontamento
POST /api/v1/ticket_agent_timeEscopo: time:write. O agente do apontamento é o dono do token.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
ticket_id | string | ✅ | Chamado |
time_interval | string | ✅ | Duração no formato Go: "90m", "1h30m", "45m" |
is_billable | bool | — | Padrão true |
Payload:
{
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"time_interval": "1h30m",
"is_billable": true
}curl -X POST https://api.opsscript.io/api/v1/ticket_agent_time \
-H "x-api-key: ops_pat_seu_token_aqui" \
-H "Content-Type: application/json" \
-d '{
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"time_interval": "1h30m",
"is_billable": true
}'Resposta 201: o TicketAgentTime criado (mesmo shape do item da listagem).
Editar apontamento
PUT /api/v1/ticket_agent_time/{id}Escopo: time:write. Mesmo payload do criar.
curl -X PUT https://api.opsscript.io/api/v1/ticket_agent_time/5c2d8e4f-1a7b-4c9d-8e3f-6b0a2c4d8e1f \
-H "x-api-key: ops_pat_seu_token_aqui" \
-H "Content-Type: application/json" \
-d '{
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"time_interval": "2h",
"is_billable": false
}'Resposta 200: o apontamento atualizado.
Iniciar cronômetro
POST /api/v1/ticket/{id}/time-tracking/startEscopo: time:write. Sem body — inicia um timer no chamado (ou retorna o já em execução).
curl -X POST https://api.opsscript.io/api/v1/ticket/0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d/time-tracking/start \
-H "x-api-key: ops_pat_seu_token_aqui"Resposta 200:
{
"id": "7e4f1a2b-9c5d-4e8f-1a3b-8d6c0e2f4a7b",
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"agent_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d",
"organization_id": "6b1f0e2a-3c4d-4e5f-8a9b-0c1d2e3f4a5b",
"started_at": "2026-07-22T16:45:00Z",
"elapsed_seconds": 0
}Parar cronômetro
POST /api/v1/ticket/{id}/time-tracking/stopEscopo: time:write. Sem body — encerra o timer, arredonda para cima ao minuto e, se o tempo for ≥ 1 minuto, cria o apontamento automaticamente (como billable).
curl -X POST https://api.opsscript.io/api/v1/ticket/0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d/time-tracking/stop \
-H "x-api-key: ops_pat_seu_token_aqui"Resposta 200 (agent_time é null quando o tempo foi menor que 1 minuto):
{
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"started_at": "2026-07-22T16:45:00Z",
"elapsed_seconds": 1260,
"agent_time": {
"id": "5c2d8e4f-1a7b-4c9d-8e3f-6b0a2c4d8e1f",
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"time_interval": "21m0s",
"is_billable": true
}
}Consultar cronômetro de um chamado
GET /api/v1/ticket/{id}/time-trackingEscopo: time:read. Sem query params. Resposta 200: o timer ativo do chamado (mesmo shape do start) ou null se não houver.
curl https://api.opsscript.io/api/v1/ticket/0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d/time-tracking \
-H "x-api-key: ops_pat_seu_token_aqui"Listar cronômetros ativos
GET /api/v1/ticket/time-tracking/activeEscopo: time:read. Sem query params — lista todos os timers ativos do usuário.
curl https://api.opsscript.io/api/v1/ticket/time-tracking/active \
-H "x-api-key: ops_pat_seu_token_aqui"Resposta 200:
[
{
"id": "7e4f1a2b-9c5d-4e8f-1a3b-8d6c0e2f4a7b",
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"started_at": "2026-07-22T16:45:00Z",
"elapsed_seconds": 320,
"ticket_subject": "Erro 500 no checkout",
"ticket_status": "Em andamento",
"organization_name": "Minha Empresa"
}
]Anexos
Listar anexos de um chamado
GET /api/v1/ticket/{ticket_id}/attachmentEscopo: attachments:read. Query params:
| Parâmetro | Descrição |
|---|---|
actual_page, limit | Paginação |
create_user_id | Filtra por autor do upload |
order | asc ou desc |
curl -G https://api.opsscript.io/api/v1/ticket/0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d/attachment \
-H "x-api-key: ops_pat_seu_token_aqui" \
-d "actual_page=1" \
-d "limit=20"Resposta 200:
{
"page": 1,
"pageCount": 1,
"totalRecords": 1,
"items": [
{
"id": "8f5a2b3c-0d7e-4f1a-9b4c-2e6d8a0c3f5b",
"ticket_id": "0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d",
"ticket_comment_id": null,
"name": "evidencia.png",
"url": "https://storage.opsscript.io/...",
"size": 204800,
"created_at": "2026-07-22T15:20:00Z"
}
]
}Consultar um anexo
GET /api/v1/ticket_attachment/{id}Escopo: attachments:read. Sem query params. Resposta 200: o objeto Attachment (mesmo shape do item da listagem).
curl https://api.opsscript.io/api/v1/ticket_attachment/8f5a2b3c-0d7e-4f1a-9b4c-2e6d8a0c3f5b \
-H "x-api-key: ops_pat_seu_token_aqui"Obter URL de download
GET /api/v1/ticket_attachment/{id}/urlEscopo: attachments:read. Sem query params. Resposta 200: uma string com a URL pré-assinada (validade limitada) para download direto.
curl https://api.opsscript.io/api/v1/ticket_attachment/8f5a2b3c-0d7e-4f1a-9b4c-2e6d8a0c3f5b/url \
-H "x-api-key: ops_pat_seu_token_aqui""https://storage.opsscript.io/attachments/evidencia.png?X-Amz-Signature=..."Enviar anexo
POST /api/v1/ticket_attachmentEscopo: attachments:write.
O body é multipart/form-data (não JSON).
| Campo (form) | Obrigatório | Descrição |
|---|---|---|
file | ✅ | O arquivo |
ticket_id | ✅ | Chamado de destino |
ticket_comment_id | — | Vincula o anexo a um comentário |
name | — | Nome de exibição |
alt | — | Texto alternativo |
curl -X POST https://api.opsscript.io/api/v1/ticket_attachment \
-H "x-api-key: ops_pat_seu_token_aqui" \
-F "[email protected]" \
-F "ticket_id=0d9f2c58-7d1a-4a8e-9c3b-2f6e8a1b4c5d" \
-F "name=Evidência do erro"Resposta 201: o Attachment criado.
Dados de referência
Disponíveis para qualquer token válido (sem escopo específico) — use-os para descobrir os ids aceitos ao criar/atualizar chamados. Sem query params; as respostas são arrays diretos, sem envelope de paginação.
Prioridades
GET /api/v1/ticket/prioritycurl https://api.opsscript.io/api/v1/ticket/priority \
-H "x-api-key: ops_pat_seu_token_aqui"[
{ "id": 1, "name": "Baixa", "color": "#10B981" },
{ "id": 2, "name": "Normal", "color": "#3B82F6" },
{ "id": 3, "name": "Alta", "color": "#F59E0B" },
{ "id": 4, "name": "Urgente", "color": "#EF4444" }
]Tipos de chamado
GET /api/v1/ticket/typecurl https://api.opsscript.io/api/v1/ticket/type \
-H "x-api-key: ops_pat_seu_token_aqui"[
{ "id": 1, "name": "Dúvida", "color": "#3B82F6" },
{ "id": 2, "name": "Incidente", "color": "#EF4444" }
]Status de chamado
GET /api/v1/ticket/statusO campo type é um de: open, pending, in_progress, done, archived.
curl https://api.opsscript.io/api/v1/ticket/status \
-H "x-api-key: ops_pat_seu_token_aqui"[
{ "id": 1, "name": "Aberto", "color": "#3B82F6", "type": "open" },
{ "id": 2, "name": "Em andamento", "color": "#F59E0B", "type": "in_progress" },
{ "id": 3, "name": "Concluído", "color": "#10B981", "type": "done" }
]Precisa de um endpoint que não está nesta lista? A gestão de tokens, assinatura e demais recursos administrativos é feita apenas pela interface do OpsScript — tokens de acesso são deliberadamente limitados ao domínio de chamados.