Erros
Formato
Seção intitulada “Formato”Todo erro sai como Problem Details (RFC 9457), com
Content-Type: application/problem+json:
{ "type": "https://tools.ietf.org/html/rfc9110#section-15.5.10", "title": "O horário acabou de ser ocupado.", "status": 409, "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"}| Campo | O que é |
|---|---|
type |
URI que identifica o tipo de problema. |
title |
Mensagem em português, pronta para mostrar a quem usa a integração. |
status |
O mesmo status HTTP da resposta. |
detail |
Explicação adicional, quando houver. |
code |
Código estável, em inglês, para os casos que o seu código precisa distinguir (tabela abaixo). Nem todo erro tem. |
errors |
Só nos 400 de validação: campo (em camelCase) → lista de mensagens. |
traceId |
Identificador da requisição. Mande junto quando pedir suporte. |
Decida pelo status e pelo code, nunca pelo texto de title ou detail: os textos podem mudar sem aviso.
Códigos (code)
Seção intitulada “Códigos (code)”code |
Status | Significado |
|---|---|---|
plan_feature |
403 |
O plano do salão não inclui integrações (Solo). |
account_blocked |
403 |
Assinatura inativa: o salão está em modo somente leitura e a requisição escreve. |
plan_limit |
409 |
O plano chegou a um limite (ex.: número de profissionais ativos). |
idempotency_key_invalid |
400 |
O header Idempotency-Key é inválido. |
idempotency_in_progress |
409 |
Outra requisição com a mesma Idempotency-Key ainda está em andamento. |
idempotency_unknown_result |
409 |
A requisição com a mesma Idempotency-Key chegou a gravar, mas a resposta se perdeu (e passaram 2 minutos). Não é executada de novo: consulte o recurso e, se ele não existir, use outra chave. |
idempotency_mismatch |
422 |
A Idempotency-Key já foi usada com outro corpo ou em outro endpoint. |
Novos códigos podem aparecer sem mudar de versão (veja compatibilidade): trate um code desconhecido
pelo status.
400 — requisição inválida
Seção intitulada “400 — requisição inválida”Algum campo veio faltando, com formato inválido ou fora do permitido. Corrija a requisição; repetir igual não adianta.
{ "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1", "title": "Há campos inválidos.", "status": 400, "errors": { "professionalId": ["'Profissional' deve ser informado."], "customerId": ["Escolha um cliente ou cadastre um novo."] }, "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"}Algumas regras de negócio também respondem 400 sem errors, só com o title (ex.: marcar a chegada com uma hora
no futuro). Um header Idempotency-Key inválido responde 400 com code: "idempotency_key_invalid".
401 — não autenticado
Seção intitulada “401 — não autenticado”O token não veio, está malformado, expirou, foi revogado ou o membro que o criou foi desativado. A resposta traz
WWW-Authenticate: Bearer. Também é a resposta, para qualquer requisição com token, das rotas que não aceitam token:
login, cadastro, conta (/me), troca de senha ou de e-mail e as rotas públicas. Não tente de novo com o mesmo token:
confira o header Authorization: Bearer pv_... e o estado do token no painel.
403 — proibido
Seção intitulada “403 — proibido”O token é válido, mas a ação não é permitida. Diferencie pelo code:
code |
Significado | O que fazer |
|---|---|---|
plan_feature |
O salão está no plano Solo, que não inclui integrações. Toda requisição com token responde assim. | O salão precisa mudar para o plano Equipe ou Negócio. |
account_blocked |
Assinatura inativa: o salão está em modo somente leitura. GET continua funcionando; o resto responde 403. |
Pare as escritas e avise o salão; volta sozinho quando a assinatura for regularizada. |
(sem code) |
Falta permissão ao token ou ao membro que o criou (lembre da interseção). | Crie um token com a permissão necessária, ou peça ao dono para dar a permissão ao membro. |
{ "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4", "title": "Assinatura inativa: o negócio está em modo somente leitura.", "status": 403, "code": "account_blocked", "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"}404 — não encontrado
Seção intitulada “404 — não encontrado”O recurso não existe ou pertence a outro salão. Isso vale também para o próprio salonId: um token só enxerga o
salão em que foi criado, e qualquer outro responde 404 (e não 403), para não revelar o que existe. Com o escopo
“só a própria agenda”, agendamentos de outro profissional também respondem 404. No host api.pegavez.com.br,
caminhos fora de /api/*, /mcp e /health também respondem 404.
409 — conflito
Seção intitulada “409 — conflito”A requisição é válida, mas o estado atual não permite a ação.
- Conflito de horário: outro agendamento ou bloqueio ocupou o horário (inclusive entre a sua consulta de disponibilidade e a criação). Consulte os horários livres de novo e ofereça outro.
- Transição de status inválida: ex.: concluir um agendamento cancelado.
- Duplicidade: ex.: telefone ou e-mail de cliente já cadastrado. Esses
409podem trazer o campoconstraint. plan_limit: o plano chegou ao limite.idempotency_in_progress: outra requisição com a mesmaIdempotency-Keyainda está sendo processada. Espere alguns segundos e repita. Veja Idempotência.idempotency_unknown_result: a primeira requisição com a mesmaIdempotency-Keygravou, mas não respondeu, e já passaram 2 minutos. Não repita com a mesma chave: consulte o recurso (GET) e, se ele não estiver lá, crie com uma chave nova.
{ "type": "https://tools.ietf.org/html/rfc9110#section-15.5.10", "title": "Uma requisição com esta Idempotency-Key ainda está em andamento. Tente de novo em instantes.", "status": 409, "code": "idempotency_in_progress", "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"}422 — chave de idempotência reutilizada
Seção intitulada “422 — chave de idempotência reutilizada”A mesma Idempotency-Key foi usada antes com um corpo diferente (ou em outro endpoint):
code: "idempotency_mismatch". Gere uma chave nova para cada operação nova. Veja Idempotência.
429 — muitas requisições
Seção intitulada “429 — muitas requisições”O token passou de 600 requisições por minuto (API e MCP somados) — ou, com token que não autentica, o IP passou
de 60 por minuto (em IPv6, conta a rede /64 inteira). Espere os segundos do header Retry-After e repita.
# Exemplo de laço que respeita o Retry-Afterwhile :; do status=$(curl -s -o resposta.json -w '%{http_code}' -D cabecalhos.txt -G \ "https://api.pegavez.com.br/api/salons/$SALON_ID/appointments" \ --data-urlencode "from=2026-11-01" --data-urlencode "to=2026-11-30" \ -H "Authorization: Bearer $PEGAVEZ_TOKEN") [ "$status" != "429" ] && break espera=$(grep -i '^retry-after:' cabecalhos.txt | tr -dc '0-9') sleep "${espera:-5}"done5xx — erro do servidor
Seção intitulada “5xx — erro do servidor”Falha do nosso lado. Repita com espera crescente (ex.: 1 s, 2 s, 4 s…). Ao criar agendamento ou cliente, use sempre
Idempotency-Key: assim a repetição não duplica nada. Se persistir, fale com o suporte informando o traceId.
Resumo: repetir ou não?
Seção intitulada “Resumo: repetir ou não?”| Status | Repetir igual? |
|---|---|
400, 401, 403, 404, 422 |
Não. Corrija a requisição, a chave, o token ou a permissão. |
409 |
Só com code: "idempotency_in_progress", depois de alguns segundos. Com idempotency_unknown_result, consulte o recurso antes (e, se repetir, use outra chave). Conflito de horário pede outro horário. |
429 |
Sim, depois do Retry-After. |
5xx, timeout |
Sim, com espera crescente e Idempotency-Key ao criar agendamento ou cliente. |