{
  "openapi": "3.0.3",
  "info": {
    "title": "API Gototem Partner",
    "version": "1",
    "description": "API para sistemas parceiros abrirem chamados no help desk da Gototem. Guia, com exemplos e o\nque fazer em cada erro: https://developers.gototem.com.br/api-integracao/. O detalhe de cada\nresposta está em `components.responses`.\n\nAutenticação: toda chamada leva a chave no cabeçalho `Authorization: Bearer gtes_...` (o\nesquema `Bearer` vale em maiúsculas ou minúsculas). O suporte da Gototem entrega a chave junto\ncom os escopos liberados e o identificador do seu sistema (usado no webhook). Não envie outro\ncabeçalho de autenticação: o de outro sistema da Gototem é recusado (ver `BadRequest` e\n`NotFound`); remova-o e envie só o `Authorization`.\n\nEscopos: `help-desk-ticket.create` libera `help-desk-ticket-options`, `help-desk-ticket` e o\nwebhook; `lead.create` libera `lead` (ainda não disponível). Sem o escopo da rota, 403\n`forbidden_scope`.\n\nErros: toda recusa desta API vem em `application/problem+json`, com `type`, `title`, `status`,\n`detail` (para leitura humana, em inglês; pode mudar) e `code` (o que o seu código usa). As\npoucas recusas do servidor, antes da API, vêm sem `code` (ver `NotFound` e `WebhookBadRequest`):\nconfira o status antes de ler o corpo.\n\nAPI desligada por um tempo: toda rota responde 503 `temporarily_unavailable` com `Retry-After`.\nGuarde o chamado e reenvie depois da espera, com o mesmo `external_id`; nunca o descarte. O 404 é\nsempre erro de endereço: corrija-o.\n\nAntes da chave: a API responde um problema por vez, e corrigir um pode revelar o seguinte. Saem\nantes da chave, sem contar no limite de chamadas, o 503, o 400 `conflicting_credentials`, o 404, o 405\n(método diferente do da rota, com o cabeçalho `Allow`; `OPTIONS` não recebe 405: exige a chave,\nconta no limite e responde 200 sem corpo, com o `Allow`), o 413 (corpo acima de 65.536 bytes),\no 415 e o 422 `invalid_body` das rotas JSON (`help-desk-ticket` e `lead`). Os 422 dos campos\nsaem por último.\n\nToda resposta das rotas desta API traz o cabeçalho `X-Request-Id`: informe-o ao suporte ao\nfalar de uma chamada. Também o traz o 404 de um caminho desta API em outra versão ou sem versão\n(`/v2/api-external-system/...`, `/api-external-system/...`); não o traz o 404 de um caminho fora\ndela, como `/v1/api-external-system` sem a barra final.\n\nLimite de chamadas: os cabeçalhos `X-RateLimit-*` vêm em toda resposta depois da conferência do\nlimite do seu sistema; sem eles, o limite não foi medido naquela chamada (nunca leia como zero).\nChamadas repetidas com chave errada, vindas do mesmo IP, bloqueiam esse IP por até um minuto,\nmesmo com a chave certa (ver `RateLimited`).\n\nCompatibilidade: a v1 só muda de forma aditiva. Os `code` de erro e de aviso são texto aberto, e\ncampo, aviso ou código novo podem surgir: ignore o que não conhecer. Remover um campo ou mudar o\ntipo dele, só numa v2, avisada antes. As mudanças de forma até 2026-10-15 vieram antes da\nprimeira integração, quando nenhum sistema tinha chave: foram o último ajuste de forma da v1.\n\nRotacionar a chave não derruba a anterior na hora: a anterior continua valendo por 24 horas\n(salvo prazo combinado com o suporte). Depois disso ela recebe 401, que\nnão conta para o bloqueio do IP. Em caso de vazamento, o suporte para a anterior na hora.\n\n## Changelog\n\nDo mais recente para o mais antigo.\n\n- **2026-10-15** — Quebra, feita antes da primeira integração: a API desligada passou a\n  responder 503 `temporarily_unavailable` com `Retry-After` (antes, 404 sem corpo); o caminho de\n  outra versão ou sem versão passou a receber o 404 `not_found` (antes, 404 sem corpo); toda\n  recusa passou a vir em `application/problem+json`, com `type`, `title`, `status`, `detail` e\n  `code` (o campo `message` do erro saiu; o texto está em `detail`); a frase do 400\n  `conflicting_credentials` passou a ser a do contrato. Acréscimos: `required_scope` no 403\n  `forbidden_scope`, o aviso `requester_truncated` (solicitante cortado) e o aviso\n  `description_differs` (reenvio com outra descrição).\n- **2026-10-14** — Nome: a API passou a se chamar API Gototem Partner (antes, API de\n  integração). Nenhuma rota, chave ou endereço mudou.\n- **2026-10-12 (9)** — A documentação saiu da API e passou a ser publicada só no portal do\n  desenvolvedor: `/v1/api-external-system/docs` e `/v1/api-external-system/docs/openapi.yaml`\n  respondem 404. Nenhuma rota da API mudou.\n- **2026-10-12 (8)** — Comportamento: depois de uma troca de chave, a anterior continua valendo\n  por 24 horas (antes parava no ato), e a anterior vencida não conta mais para o bloqueio do IP.\n- **2026-10-12 (7)** — Comportamento: o IP do bloqueio por chaves erradas passou a ser o do\n  servidor que se conecta à API, nunca um header que o cliente escreva; em IPv6, conta o bloco\n  `/64` inteiro.\n- **2026-10-12 (6)** — Forma: o 404 do caminho que começa com `/v1/api-external-system/` mas não\n  é rota ganhou o corpo `{code, message}` (`not_found`; antes, a página HTML do servidor). O 404\n  sem corpo, o que manda guardar e reenviar, não mudou.\n- **2026-10-12 (5)** — Forma: o 405 ganhou o corpo `{code, message}` (`method_not_allowed`, com\n  `Allow`) e passou a sair antes da chave, sem contar no limite.\n- **2026-10-12 (4)** — Comportamento: caracteres invisíveis e de controle passaram a ser\n  retirados de `external_id` e do `requester` (o NUL continua recusado).\n- **2026-10-12 (3)** — Aditiva: o campo `param` nos 422 dos campos, com o nome do campo recusado.\n- **2026-10-12 (2)** — Aditiva: o aviso `ignored_fields` em `warnings` para campo fora do\n  contrato (o chamado é aberto do mesmo jeito).\n- **2026-10-12 (1)** — Aditiva: os headers `X-RateLimit-Limit`, `X-RateLimit-Remaining` e\n  `X-RateLimit-Reset` em toda resposta depois da conferência do limite do sistema, e o\n  `Retry-After` do 429 com a espera real (antes, a janela inteira).\n- **2026-10-11** — Todas aditivas: o bloco `applied` na resposta do chamado; id com casa decimal\n  zero aceito como o inteiro; `WWW-Authenticate: Bearer` no 401; `code` de erro e de aviso como\n  texto aberto no contrato.\n"
  },
  "servers": [
    {
      "url": "https://api.gototem.com.br",
      "description": "Produção. Em homologação, o suporte informa o endereço junto com a chave. O endereço é HTTPS; envie a chave só por HTTPS."
    }
  ],
  "externalDocs": {
    "description": "Guia da API Gototem Partner no portal do desenvolvedor",
    "url": "https://developers.gototem.com.br/api-integracao/"
  },
  "security": [
    {
      "integrationKey": []
    }
  ],
  "tags": [
    {
      "name": "Chamados"
    },
    {
      "name": "Leads"
    }
  ],
  "x-tagGroups": [
    {
      "name": "Chamados",
      "x-id": "ref-chamados",
      "tags": [
        "Chamados"
      ]
    },
    {
      "name": "Leads",
      "x-id": "ref-leads",
      "tags": [
        "Leads"
      ]
    }
  ],
  "paths": {
    "/v1/api-external-system/help-desk-ticket-options": {
      "get": {
        "tags": [
          "Chamados"
        ],
        "operationId": "getHelpDeskTicketOptions",
        "x-permission": "help-desk-ticket.create",
        "summary": "O que o seu sistema pode escolher ao abrir um chamado",
        "description": "Escopo: `help-desk-ticket.create`.\n\nLista as empresas, as categorias liberadas para o seu sistema (com o tipo de cada uma), as\nprioridades, os níveis de suporte e as naturezas. O `id` da empresa vai em `company`, o da\ncategoria em `category`, o da prioridade em `priority`, o do nível em `support_level` e o\n`identifier` da natureza em `nature`. Os ids mudam entre homologação e produção (os do exemplo\nsão ilustrativos): leia-os daqui, nunca os fixe no código.\n\nGuarde a resposta em cache por algumas horas e consulte de novo ao receber\n`category_fallback`, `priority_fallback` ou `invalid_nature`.\n",
        "responses": {
          "200": {
            "description": "As opções",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HelpDeskTicketOptions"
                },
                "example": {
                  "companies": [
                    {
                      "id": "gototem",
                      "name": "Gototem"
                    },
                    {
                      "id": "melhoretec",
                      "name": "Melhoretec"
                    }
                  ],
                  "categories": [
                    {
                      "id": 3,
                      "name": "Falha na impressora",
                      "description": null,
                      "default": false,
                      "default_priority_id": 1,
                      "type": {
                        "id": 3,
                        "name": "Problema",
                        "description": "Algo que funcionava parou de funcionar ou funciona errado."
                      }
                    },
                    {
                      "id": 7,
                      "name": "Ajustes em cardápios",
                      "description": "Pedido para incluir, alterar ou remover produtos, preços ou opcionais do cardápio. Não use quando algo parou de funcionar.",
                      "default": true,
                      "default_priority_id": 3,
                      "type": {
                        "id": 1,
                        "name": "Solicitação de Serviço",
                        "description": "O cliente pede algo novo ou uma alteração; nada está quebrado."
                      }
                    }
                  ],
                  "priorities": [
                    {
                      "id": 1,
                      "name": "Crítica",
                      "description": "A loja não consegue vender. Use só quando a operação estiver parada.",
                      "level": 1,
                      "response_time_hours": 1
                    },
                    {
                      "id": 3,
                      "name": "Normal",
                      "description": null,
                      "level": 3,
                      "response_time_hours": 8
                    }
                  ],
                  "support_levels": [
                    {
                      "id": 1,
                      "name": "Nível 1",
                      "description": "Primeiro atendimento: dúvidas de uso, orientação e problemas que o suporte resolve com os procedimentos padrão. Use na maioria dos chamados."
                    },
                    {
                      "id": 2,
                      "name": "Nível 2",
                      "description": "Análise técnica especializada: falha que se repete ou que o primeiro atendimento já tentou resolver sem sucesso, erro do sistema ou de integração. Use só quando a conversa mostrar isso."
                    }
                  ],
                  "natures": [
                    {
                      "identifier": "hardware",
                      "name": "Hardware"
                    },
                    {
                      "identifier": "implementation",
                      "name": "Implantação"
                    },
                    {
                      "identifier": "software",
                      "name": "Software"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/v1/api-external-system/help-desk-ticket": {
      "post": {
        "tags": [
          "Chamados"
        ],
        "operationId": "createHelpDeskTicket",
        "x-permission": "help-desk-ticket.create",
        "summary": "Abre um chamado no help desk",
        "description": "Escopo: `help-desk-ticket.create`.\n\nO `external_id` identifica o reenvio: o mesmo `external_id` devolve o chamado que já existe\n(200, `duplicate: true`, como foi criado), nunca um segundo; o corpo do reenvio ainda é\nvalidado (os 422 valem). O registro do `external_id` é por sistema: a rota direta e o webhook\ndo mesmo sistema o compartilham, e ele não expira.\n\n`category`, `priority` e `support_level` nunca recusam o chamado: valor desconhecido, não\nliberado ou de tipo errado é trocado pelo padrão, com aviso em `warnings`; o que foi gravado\nvem em `applied`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TicketRequest"
              },
              "example": {
                "external_id": "conv-8841",
                "company": "gototem",
                "description": "Cliente relata que o totem não imprime o cupom.",
                "category": 3,
                "priority": 3,
                "support_level": 1,
                "nature": "hardware",
                "requester": {
                  "name": "Maria Souza",
                  "contact": "maria@loja.com.br"
                },
                "cnpj": "12.345.678/0001-90"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reenvio do mesmo external_id; devolve o chamado que já existe, com o `applied` dele",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TicketResponse"
                },
                "example": {
                  "ticket": "I-12345A",
                  "id": "aGVsbG8td29ybGQ",
                  "duplicate": true,
                  "warnings": [],
                  "applied": {
                    "category_id": 3,
                    "priority_id": 3,
                    "support_level": 1,
                    "nature": "hardware",
                    "company": "gototem"
                  }
                }
              }
            }
          },
          "201": {
            "description": "Chamado criado",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TicketResponse"
                },
                "example": {
                  "ticket": "I-12345A",
                  "id": "aGVsbG8td29ybGQ",
                  "duplicate": false,
                  "warnings": [],
                  "applied": {
                    "category_id": 3,
                    "priority_id": 3,
                    "support_level": 1,
                    "nature": "hardware",
                    "company": "gototem"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/v1/api-external-system/webhook/{system}": {
      "post": {
        "tags": [
          "Chamados"
        ],
        "operationId": "createHelpDeskTicketByWebhook",
        "x-permission": "help-desk-ticket.create",
        "summary": "Abre um chamado pelo webhook do seu sistema",
        "description": "Escopo: `help-desk-ticket.create`.\n\nO mesmo chamado da rota direta, para quando o seu sistema envia por webhook. `{system}` é o\nidentificador do seu sistema, informado pelo suporte da Gototem junto com a chave. Nesta\nversão o webhook também exige a chave no cabeçalho `Authorization` e o corpo segue o mesmo\nformato da rota direta, com as mesmas respostas (inclusive `applied`). Qualquer\n`Content-Type` é aceito. O teto de 65.536 bytes (413) vale antes da chave, como nas outras\nrotas; o formato do corpo (`invalid_body`) só é conferido depois dela. Com `Content-Type` JSON,\ncorpo que não é objeto nem lista JSON recebe 400 em `application/problem+json`, sem `code`.\n\nIdentificador desconhecido, ou a chave de outro sistema, recebe 401 `unauthorized`.\nIdentificador fora do padrão (maiúscula, acento, outro caractere ou mais de 40 caracteres)\nnão é rota: recebe o 404 `not_found`.\n",
        "parameters": [
          {
            "name": "system",
            "in": "path",
            "required": true,
            "description": "O identificador do seu sistema (letras minúsculas, números, `-` e `_`, até 40 caracteres)",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9_-]{1,40}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "O mesmo corpo da rota direta. Qualquer `Content-Type` é aceito.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TicketRequest"
              },
              "example": {
                "external_id": "conv-8842",
                "company": "gototem",
                "description": "Cliente relata que o totem não imprime o cupom.",
                "category": 3,
                "priority": 3,
                "support_level": 1,
                "nature": "hardware",
                "requester": {
                  "name": "Maria Souza",
                  "contact": "maria@loja.com.br"
                },
                "cnpj": "12.345.678/0001-90"
              }
            },
            "*/*": {
              "schema": {
                "$ref": "#/components/schemas/TicketRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reenvio do mesmo external_id",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TicketResponse"
                }
              }
            }
          },
          "201": {
            "description": "Chamado criado",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TicketResponse"
                },
                "example": {
                  "ticket": "I-12345A",
                  "id": "aGVsbG8td29ybGQ",
                  "duplicate": false,
                  "warnings": [],
                  "applied": {
                    "category_id": 3,
                    "priority_id": 3,
                    "support_level": 1,
                    "nature": "hardware",
                    "company": "gototem"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/WebhookBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/v1/api-external-system/lead": {
      "post": {
        "tags": [
          "Leads"
        ],
        "operationId": "createLead",
        "x-permission": "lead.create",
        "x-status": "planned",
        "summary": "Envio de lead (ainda não disponível)",
        "description": "Escopo: `lead.create`.\n\nA rota já autentica e confere o formato mínimo, mas ainda não grava: responde 501\n`not_implemented`. Não integre esta rota até a Gototem avisar. Sem o escopo `lead.create` na\nchave, a resposta é o 403 `forbidden_scope`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "external_id"
                ],
                "properties": {
                  "external_id": {
                    "type": "string",
                    "maxLength": 120
                  }
                }
              }
            }
          }
        },
        "responses": {
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/Unprocessable"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "501": {
            "description": "Ainda não implementado",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "type": "about:blank",
                  "title": "Not Implemented",
                  "status": 501,
                  "detail": "Not implemented yet.",
                  "code": "not_implemented"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "integrationKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "gtes_ seguido de 43 caracteres",
        "description": "A chave, entregue pelo suporte da Gototem. O esquema `Bearer` vale em maiúsculas ou minúsculas."
      }
    },
    "schemas": {
      "TicketRequest": {
        "type": "object",
        "required": [
          "external_id",
          "company",
          "description"
        ],
        "description": "Campos fora desta lista são ignorados, nunca recusados (não há campo de conta ou local: o\n`cnpj` é o único identificador do cliente), e vêm no aviso `ignored_fields`. `null` num campo\nopcional é o mesmo que não enviar; num obrigatório, recusa com o `missing_*` do campo.\n",
        "properties": {
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "description": "O id do atendimento no seu sistema; identifica o reenvio, por sistema. Os espaços das\npontas e os caracteres invisíveis e de controle (menos o ZWNJ e o ZWJ) são retirados antes\nde comparar e de contar; maiúsculas e minúsculas diferem. Inteiro JSON vale como o mesmo\ntexto. Vazio: `missing_external_id`; acima de 120 caracteres: `field_too_long` (não é\ncortado); NUL (`\\u0000`): `invalid_field`.\n"
          },
          "company": {
            "type": "string",
            "description": "Id de uma das `companies` de `help-desk-ticket-options` (ex. `gototem`); os espaços das\npontas são retirados e maiúscula vale como minúscula. Ausente ou vazio: `missing_company`;\nfora da lista: `invalid_company`.\n"
          },
          "description": {
            "type": "string",
            "maxLength": 20000,
            "description": "O relato, em texto puro, até 20.000 caracteres (contados antes de retirar os espaços das\npontas; quebra de linha e tabulação ficam). Acima: `field_too_long` (não é cortado: corte\nno seu lado). Vazio: `missing_description`. NUL: `invalid_field`. O corpo inteiro tem teto\nde 65.536 bytes (413).\n"
          },
          "category": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Id inteiro de `categories` (`3.0` vale como 3). Ausente: a categoria padrão do sistema.\nDesconhecida, não liberada, texto (`\"3\"`) ou fração: também a padrão, com o aviso\n`category_fallback`; nunca recusa.\n"
          },
          "priority": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Id inteiro de `priorities` (`1.0` vale como 1). Ausente: a `default_priority_id` da\ncategoria gravada. Desconhecida, texto (`\"1\"`) ou fração: também a padrão, com o aviso\n`priority_fallback`; nunca recusa.\n"
          },
          "support_level": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Id inteiro de `support_levels` (`2.0` vale como 2). Ausente: 1. Fora da lista, texto\n(`\"2\"`) ou fração: também 1, com o aviso `support_level_fallback`; nunca recusa.\n"
          },
          "nature": {
            "type": "string",
            "nullable": true,
            "description": "O `identifier` de uma das `natures` de `help-desk-ticket-options`; os espaços das pontas\nsão retirados e maiúscula vale como minúscula. Ausente: o chamado nasce sem natureza. Outro\nvalor: `invalid_nature`, a única escolha que recusa o chamado (na dúvida, omita).\n"
          },
          "cnpj": {
            "type": "string",
            "nullable": true,
            "description": "CNPJ do cliente em 14 caracteres, numérico ou alfanumérico, como texto\n(`12.345.678/0001-90` ou `L3USOA72000137`); a pontuação e o rótulo `CNPJ` na frente são\nignorados, e minúscula vale como maiúscula. O dígito verificador não é conferido. Fora do\nformato (inclusive o número JSON que perdeu o zero à esquerda): ignorado, com o aviso\n`cnpj_ignored`; nunca recusa. O aviso não diz se o CNPJ é de um cliente da Gototem.\n"
          },
          "requester": {
            "type": "object",
            "nullable": true,
            "description": "Quem pediu: `name` (até 120 caracteres) e `contact` (até 160). Acima do limite o texto é\ncortado, nunca recusado; espaços das pontas e invisíveis (menos o ZWNJ e o ZWJ) são\nretirados; NUL: `invalid_field`. Valor que não é texto é ignorado sem aviso; `requester`\nque não é objeto, e chave fora de `name`/`contact`, vêm em `ignored_fields`.\n",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true,
                "maxLength": 120,
                "description": "O nome de quem pediu, até 120 caracteres (o excedente é cortado)."
              },
              "contact": {
                "type": "string",
                "nullable": true,
                "maxLength": 160,
                "description": "Como falar com quem pediu (ex. e-mail ou telefone), até 160 caracteres (o excedente é cortado)."
              }
            }
          }
        }
      },
      "TicketResponse": {
        "type": "object",
        "required": [
          "ticket",
          "id",
          "duplicate",
          "warnings",
          "applied"
        ],
        "properties": {
          "ticket": {
            "type": "string",
            "description": "O número do chamado no help desk (começa com I-)."
          },
          "id": {
            "type": "string",
            "description": "Id do chamado, opaco."
          },
          "duplicate": {
            "type": "boolean",
            "description": "true quando o external_id já tinha sido enviado."
          },
          "warnings": {
            "type": "array",
            "description": "Escolhas trocadas pelo padrão, CNPJ ignorado, campos fora do contrato e solicitante cortado. Vazio quando nada foi trocado nem ignorado. No reenvio, o único aviso possível é `description_differs` (outra descrição para o mesmo `external_id`).",
            "items": {
              "$ref": "#/components/schemas/Warning"
            }
          },
          "applied": {
            "type": "object",
            "description": "O que foi de fato gravado no chamado, depois das trocas pelo padrão: confira aqui a\ncategoria, a prioridade e o nível que valeram. No reenvio (200), os valores do chamado que\njá existia. `null` em qualquer campo não é erro: o chamado foi aberto; não reenvie por\ncausa dele. Traz só estes cinco campos: o `cnpj` não é ecoado (sem o aviso `cnpj_ignored`,\nele foi aceito) e o `requester` também não (o excedente é cortado, com o aviso\n`requester_truncated`).\n",
            "required": [
              "category_id",
              "priority_id",
              "support_level",
              "nature",
              "company"
            ],
            "properties": {
              "category_id": {
                "type": "integer",
                "nullable": true,
                "description": "O id da categoria gravada. Na criação sempre vem; `null` só num reenvio de chamado que perdeu a categoria depois."
              },
              "priority_id": {
                "type": "integer",
                "nullable": true,
                "description": "O id da prioridade gravada; pode ser `null`."
              },
              "support_level": {
                "type": "integer",
                "nullable": true,
                "description": "O nível de suporte gravado; pode ser `null`."
              },
              "nature": {
                "type": "string",
                "nullable": true,
                "description": "O `identifier` da natureza gravada. `null` quando o chamado não tem natureza."
              },
              "company": {
                "type": "string",
                "nullable": true,
                "description": "O id (de `companies`) da empresa gravada; pode ser `null`."
              }
            }
          }
        }
      },
      "Warning": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Texto aberto. Os valores conhecidos são `category_fallback`, `priority_fallback`,\n`support_level_fallback`, `cnpj_ignored`, `ignored_fields`, `requester_truncated` e\n`description_differs`. Aviso novo pode surgir a qualquer momento: registre o que não\nconhecer e siga, porque o chamado foi criado (ou já existia, no reenvio).\n",
            "x-extensible-enum": [
              "category_fallback",
              "priority_fallback",
              "support_level_fallback",
              "cnpj_ignored",
              "ignored_fields",
              "requester_truncated",
              "description_differs"
            ]
          },
          "message": {
            "type": "string",
            "description": "Para leitura humana, em inglês; pode mudar. Use o `code` na lógica."
          },
          "fields": {
            "type": "array",
            "description": "Só no `ignored_fields` e no `requester_truncated`. No `ignored_fields`: os campos ignorados,\nna ordem do corpo (`requester.<chave>` para os de dentro de `requester`), no máximo 20\nnomes, cada um com até 64 caracteres, sem caracteres invisíveis. No\n`requester_truncated`: os campos cortados (`requester.name`, `requester.contact`).\n",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "HelpDeskTicketOptions": {
        "type": "object",
        "required": [
          "companies",
          "categories",
          "priorities",
          "support_levels",
          "natures"
        ],
        "properties": {
          "companies": {
            "type": "array",
            "description": "As empresas ativas do grupo Gototem pelas quais o chamado pode ser aberto.",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "description": "O identificador da empresa (ex. `gototem`), o valor que o chamado aceita em `company`."
                },
                "name": {
                  "type": "string",
                  "description": "O nome da empresa, para exibir."
                }
              }
            }
          },
          "categories": {
            "type": "array",
            "description": "A categoria padrão do seu sistema e as liberadas para ele, em ordem alfabética do nome do\ntipo e, dentro de cada tipo, do nome da categoria.\n",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "description",
                "default",
                "default_priority_id",
                "type"
              ],
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "O id (número inteiro) da categoria, o valor que o chamado aceita em `category`."
                },
                "name": {
                  "type": "string",
                  "description": "O nome da categoria."
                },
                "description": {
                  "$ref": "#/components/schemas/OptionDescription"
                },
                "default": {
                  "type": "boolean",
                  "description": "true na categoria usada quando nenhuma é escolhida."
                },
                "default_priority_id": {
                  "type": "integer",
                  "nullable": true,
                  "description": "O `id` (de `priorities`) da prioridade usada quando o chamado vem com esta categoria\ne sem `priority`. Hoje toda categoria tem prioridade padrão; `null` fica reservado e,\nse aparecer, envie `priority` junto com essa categoria.\n"
                },
                "type": {
                  "type": "object",
                  "description": "O tipo da categoria (Incidente, Problema, Solicitação de Serviço ou Solicitação de Mudança). Escolher a categoria já define o tipo.",
                  "required": [
                    "id",
                    "name",
                    "description"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer",
                      "description": "O id do tipo. Só informativo; o chamado não recebe o tipo, que vem da categoria."
                    },
                    "name": {
                      "type": "string",
                      "description": "O nome do tipo."
                    },
                    "description": {
                      "$ref": "#/components/schemas/OptionDescription"
                    }
                  }
                }
              }
            }
          },
          "priorities": {
            "type": "array",
            "description": "Da mais urgente (level 1) para a menos urgente. O `response_time_hours` é o prazo\nconfigurado de cada uma e pode não acompanhar a ordem do `level`.\n",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "description",
                "level",
                "response_time_hours"
              ],
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "O id (número inteiro) da prioridade, o valor que o chamado aceita em `priority`."
                },
                "name": {
                  "type": "string",
                  "description": "O nome da prioridade."
                },
                "description": {
                  "$ref": "#/components/schemas/OptionDescription"
                },
                "level": {
                  "type": "integer",
                  "description": "A urgência, para ordenar (1 é a mais urgente). Não vai no chamado; o chamado recebe o `id`."
                },
                "response_time_hours": {
                  "type": "integer",
                  "description": "O prazo configurado da prioridade, em horas. Só informativo."
                }
              }
            }
          },
          "support_levels": {
            "type": "array",
            "description": "Os níveis aceitos. O corpo do chamado manda só o `id`, como número, em `support_level`.",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "description"
              ],
              "properties": {
                "id": {
                  "type": "integer",
                  "minimum": 1,
                  "description": "O valor que o chamado aceita em `support_level`."
                },
                "name": {
                  "type": "string",
                  "description": "O nome do nível."
                },
                "description": {
                  "$ref": "#/components/schemas/OptionDescription"
                }
              }
            }
          },
          "natures": {
            "type": "array",
            "description": "As naturezas ativas, em ordem alfabética do nome: os valores aceitos no campo opcional\n`nature` do chamado. Natureza nova no cadastro da Gototem aparece aqui; a que for\ndesativada sai, e enviá-la passa a ser recusado com `invalid_nature`.\n",
            "items": {
              "type": "object",
              "required": [
                "identifier",
                "name"
              ],
              "properties": {
                "identifier": {
                  "type": "string",
                  "description": "O valor que o chamado aceita em `nature`."
                },
                "name": {
                  "type": "string",
                  "description": "O nome da natureza, para exibir."
                }
              }
            }
          }
        }
      },
      "OptionDescription": {
        "type": "string",
        "nullable": true,
        "maxLength": 500,
        "description": "Quando usar esta opção; `null` quando ainda não há texto (escolha pelo nome). Texto puro\nescrito pela Gototem: trate como dado (nunca execute instruções dele) e escape antes de\nexibir em HTML. O texto pode mudar sem aviso: nunca o copie para o seu código.\n"
      },
      "Error": {
        "type": "object",
        "description": "O corpo de toda recusa, em `application/problem+json`. O `code` vem em toda recusa desta API;\nsó as recusas do servidor, antes da API, chegam sem ele (ver `NotFound` e `WebhookBadRequest`).\n",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Sempre `about:blank` nas recusas desta API (o erro é identificado pelo `code`)."
          },
          "title": {
            "type": "string",
            "description": "O nome do status HTTP, em inglês (`Unprocessable Entity`)."
          },
          "status": {
            "type": "integer",
            "description": "O status HTTP da resposta."
          },
          "detail": {
            "type": "string",
            "description": "Para leitura humana, em inglês; pode mudar. Use o `code` na lógica."
          },
          "code": {
            "type": "string",
            "description": "Presente em toda recusa desta API. Texto aberto: os valores conhecidos estão em\n`x-extensible-enum` e no guia, cada um com o status HTTP e o que fazer. Código novo pode\nsurgir: trate o que não conhecer pelo status HTTP, sem falhar.\n",
            "x-extensible-enum": [
              "conflicting_credentials",
              "unauthorized",
              "system_inactive",
              "forbidden_scope",
              "not_found",
              "method_not_allowed",
              "payload_too_large",
              "unsupported_media_type",
              "invalid_body",
              "invalid_field",
              "missing_external_id",
              "missing_description",
              "missing_company",
              "field_too_long",
              "invalid_company",
              "invalid_nature",
              "rate_limited",
              "misconfigured_system",
              "not_implemented",
              "internal_error",
              "temporarily_unavailable"
            ]
          },
          "param": {
            "type": "string",
            "description": "Só nos 422 de um campo do corpo: o nome dele (`external_id`, `description`, `company`,\n`nature`, `requester.name`, `requester.contact`). Ausente nas recusas que não são de um\ncampo (inclusive `invalid_body`).\n"
          },
          "required_scope": {
            "type": "string",
            "description": "Só no 403 `forbidden_scope`: o escopo que a rota exige e a chave não tem\n(`help-desk-ticket.create` ou `lead.create`). Peça-o ao suporte.\n"
          }
        }
      }
    },
    "headers": {
      "XRequestId": {
        "description": "Identificador desta chamada no registro da Gototem. Informe-o ao suporte.",
        "schema": {
          "type": "string"
        }
      },
      "XRateLimitLimit": {
        "description": "O limite de chamadas do seu sistema por janela de um minuto. Vem em toda resposta depois da\nconferência do limite; ausente quando ele não está sendo medido naquela chamada.\n",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitRemaining": {
        "description": "Quantas chamadas ainda cabem na janela (0 no 429). O saldo é do seu sistema, não de um\nservidor: todos os servidores que usam a chave do sistema, e a chave anterior durante uma\ntroca, gastam o mesmo saldo. Por isso ele pode cair mais do que as chamadas de um servidor\nexplicam.\n",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitReset": {
        "description": "Instante, em segundos Unix, em que a chamada mais antiga da janela deixa de contar (o saldo\nsobe). Com saldo 0, é quando a próxima chamada passa.\n",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "WebhookBadRequest": {
        "description": "Duas causas, as duas em `application/problem+json`. Veio um cabeçalho de autenticação de outro\nsistema da Gototem: `conflicting_credentials`, antes da chave (ver BadRequest). Ou, com\n`Content-Type` JSON (`application/json` ou um tipo com o sufixo `+json`), o corpo não é objeto\nnem lista JSON (JSON quebrado, texto que não é UTF-8 válido, ou um valor sozinho como `\"oi\"`,\n`5`, `true` ou `null`): quem recusa é o servidor, depois da chave e da cota, **sem `code`**, com\nos `X-RateLimit-*`. Uma lista recebe 422 `invalid_body`, e com outro `Content-Type` todo corpo\nque não é objeto também. Corrija o corpo; reenviar igual não resolve.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Bad Request",
              "status": 400,
              "detail": "This API does not accept authentication headers from other Gototem systems. Send only the integration key.",
              "code": "conflicting_credentials"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Veio um cabeçalho de autenticação de outro sistema da Gototem (a mesma recusa também pode sair como o 404 sem `code`, ver NotFound). Remova o cabeçalho e envie só o `Authorization`. Sai antes da chave e não conta no limite de chamadas. O `detail` é informativo e pode mudar; use o `code`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Bad Request",
              "status": 400,
              "detail": "This API does not accept authentication headers from other Gototem systems. Send only the integration key.",
              "code": "conflicting_credentials"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Chave ausente, fora do formato ou desconhecida; no webhook, também o identificador\ndesconhecido e a chave de outro sistema. A mesma resposta em todos os casos. Sai depois do 405\n(método errado recebe 405 mesmo sem a chave). Cada 401 de chave desconhecida conta para o\nbloqueio do IP (ver RateLimited); a chave anterior do sistema, depois do prazo da troca, não\nconta.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "WWW-Authenticate": {
            "description": "Sempre `Bearer`.",
            "schema": {
              "type": "string",
              "example": "Bearer"
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Unauthorized",
              "status": 401,
              "detail": "Invalid or missing credentials.",
              "code": "unauthorized"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Sistema desativado (`system_inactive`) ou sem o escopo da rota (`forbidden_scope`: o campo\n`required_scope` diz o escopo que falta). Fale com o suporte; guarde o chamado e reenvie depois, com o mesmo\n`external_id`, quando o suporte confirmar a correção. Os cabeçalhos `X-RateLimit-*` vêm no\n`forbidden_scope`, que sai depois da conferência do limite; no `system_inactive`, que sai\nantes dela, não vêm.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/XRateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/XRateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/XRateLimitReset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Forbidden",
              "status": 403,
              "detail": "This system is not allowed to use this resource.",
              "code": "forbidden_scope",
              "required_scope": "lead.create"
            }
          }
        }
      },
      "NotFound": {
        "description": "Sempre erro de endereço (a API desligada responde 503, não 404). Três formas:\n\n- `not_found` em `application/problem+json`, com `X-Request-Id`: o caminho começa com\n  `/v1/api-external-system/` mas não é nenhuma das rotas (erro de digitação, barra no fim,\n  `{system}` fora do padrão), ou é de uma rota desta API em outra versão ou sem versão\n  (`/v2/api-external-system/...`, `/api-external-system/...`). Confira o endereço; reenviar\n  igual não resolve.\n- `application/problem+json` **sem `code`**, com `X-Request-Id`: veio um cabeçalho de\n  autenticação de outro sistema da Gototem (ver BadRequest). Quem recusa é o servidor, antes\n  da API. Remova o cabeçalho e envie só o `Authorization`.\n- Página HTML do servidor, sem `X-Request-Id`: o caminho está fora do prefixo (como\n  `/v1/api-external-system` sem a barra final ou `/v1/outra-coisa`); essa chamada não chega a\n  esta API. Confira o endereço.\n\nConfira o status antes de ler o corpo como JSON.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A página HTML do servidor, para o caminho fora do prefixo desta API."
            }
          },
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Not Found",
              "status": 404,
              "detail": "Resource not found. Check the path against the API reference in the Gototem developer portal.",
              "code": "not_found"
            }
          }
        }
      },
      "MethodNotAllowed": {
        "description": "Método HTTP diferente do da rota (por exemplo, `GET` numa rota de `POST`): `method_not_allowed`,\ncom o cabeçalho `Allow` dizendo o método aceito. Sai antes da chave e não conta no limite de\nchamadas. `HEAD` numa rota `GET` também recebe 405 (use `GET`); `OPTIONS` não: exige a chave,\nconta no limite de chamadas e recebe 200 sem corpo, com o `Allow`.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "Allow": {
            "description": "O método que a rota aceita",
            "schema": {
              "type": "string"
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Method Not Allowed",
              "status": 405,
              "detail": "This endpoint only accepts POST.",
              "code": "method_not_allowed"
            }
          }
        }
      },
      "UnsupportedMediaType": {
        "description": "Corpo enviado sem `Content-Type` ou com um diferente de `application/json` (`; charset=utf-8` é aceito, e também um tipo com o sufixo `+json`, como `application/vnd.exemplo+json`). O tipo vai em minúsculas; `Application/JSON` também recebe 415. Sai antes da chave.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Unsupported Media Type",
              "status": 415,
              "detail": "Unsupported Content-Type. Send Content-Type: application/json.",
              "code": "unsupported_media_type"
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "Corpo acima de 65.536 bytes, contados no corpo como enviado (bytes, não caracteres). Sai antes\nda chave, em todas as rotas (inclusive o webhook). Em UTF-8 sem escape, letra sem\nacento ocupa 1 byte, letra acentuada 2 e emoji 4: os 20.000 caracteres da `description` só\nestouram o teto com muitos caracteres de 3 ou 4 bytes. JSON que escapa o Unicode gasta 6\nbytes por acento e 12 por emoji, e estoura antes.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Payload Too Large",
              "status": 413,
              "detail": "Request body is too large.",
              "code": "payload_too_large"
            }
          }
        }
      },
      "Unprocessable": {
        "description": "Corpo que não é objeto JSON, inclusive JSON quebrado ou que não é UTF-8 válido\n(`invalid_body`, conferido antes da chave nas rotas JSON: `help-desk-ticket` e `lead`; no\nwebhook, depois dela); campo obrigatório ausente (`missing_*`); `external_id` ou\n`description` acima do limite (`field_too_long`, só nesses dois campos); empresa ou natureza\nfora da lista (`invalid_company`, `invalid_nature`); texto com o caractere NUL\n(`invalid_field`). O `param` diz o campo, nas recusas de um campo do corpo. Corrija antes de\nreenviar. Os cabeçalhos `X-RateLimit-*` vêm nos 422 dos campos e no `invalid_body` do\nwebhook; no `invalid_body` das rotas JSON, que sai antes da conferência do limite, não vêm.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/XRateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/XRateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/XRateLimitReset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Unprocessable Entity",
              "status": 422,
              "detail": "Unknown company. Use one of: gototem, melhoretec.",
              "code": "invalid_company",
              "param": "company"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Limite atingido. Duas causas, com a mesma resposta: o limite do seu sistema (120 chamadas\npor minuto por padrão; o suporte pode combinar outro), ou o IP bloqueado: chamadas repetidas\ncom chave errada, vindas do mesmo IP, bloqueiam esse IP por até um minuto, mesmo com a chave\ncerta. Aguarde os segundos do cabeçalho `Retry-After` (a espera real) e reenvie com o mesmo\n`external_id`; não reenvie em laço. No limite do sistema, a resposta traz também os\n`X-RateLimit-*` (saldo 0); no IP bloqueado, não.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "Retry-After": {
            "description": "Segundos até a próxima chamada passar (a espera real, não a janela inteira). Quando o servidor não consegue medir, a janela inteira.",
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/XRateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/XRateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/XRateLimitReset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Too Many Requests",
              "status": 429,
              "detail": "Too many requests. Try again later.",
              "code": "rate_limited"
            }
          }
        }
      },
      "ServerError": {
        "description": "Cadastro do sistema incompleto (`misconfigured_system`: fale com o suporte, guarde o chamado e\nreenvie depois da correção) ou falha inesperada (`internal_error`: reenvie em alguns minutos).\nNos dois casos, com o mesmo `external_id`.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Internal Server Error",
              "status": 500,
              "detail": "Unexpected error. Try again later.",
              "code": "internal_error"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "A API está desligada por um tempo (`temporarily_unavailable`), em qualquer rota e antes da\nchave. Guarde o chamado e reenvie depois dos segundos do `Retry-After`, com o mesmo\n`external_id`; nunca o descarte. Se durar, fale com o suporte.\n",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "Retry-After": {
            "description": "Segundos até tentar de novo.",
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "about:blank",
              "title": "Service Unavailable",
              "status": 503,
              "detail": "The API is temporarily unavailable. Retry after the time in the Retry-After header.",
              "code": "temporarily_unavailable"
            }
          }
        }
      }
    }
  }
}
