Pular para o conteúdo

Erros

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.

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.

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".

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.

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"
}

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.

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 409 podem trazer o campo constraint.
  • plan_limit: o plano chegou ao limite.
  • idempotency_in_progress: outra requisição com a mesma Idempotency-Key ainda está sendo processada. Espere alguns segundos e repita. Veja Idempotência.
  • idempotency_unknown_result: a primeira requisição com a mesma Idempotency-Key gravou, 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"
}

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.

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.

Janela do terminal
# Exemplo de laço que respeita o Retry-After
while :; 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}"
done

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.

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.