Pular para o conteúdo principal

Status de Erros

A API do TapSign usa os códigos de status HTTP padrão para indicar o resultado de cada requisição. Esta página mostra o formato das respostas de erro e como tratá-las.

Códigos de Status HTTP​

CódigoStatusQuando acontece
200OKRequisição processada com sucesso
201CreatedRecurso criado com sucesso
204No ContentProcessada, sem corpo na resposta (ex.: DELETE)
400Bad RequestCampo inválido, parâmetro com tipo errado ou regra de negócio violada (ex.: enviar um envelope que não está em rascunho)
401UnauthorizedToken ausente, inválido ou expirado; chave de API desativada ou excluída
402Payment RequiredA conta não tem plano com acesso ao recurso (ex.: criar chave de API fora dos planos Equipe e Enterprise)
403ForbiddenAutenticado, mas sem permissão (ex.: recurso de uma organização da qual você não participa)
404Not FoundRecurso inexistente ou de outro usuário, ou rota inexistente
405Method Not AllowedMétodo HTTP não aceito na rota
409ConflictConflito com dados existentes (ex.: convite ou membro já existente)
413Payload Too LargeArquivo acima de 10 MB. Essa resposta vem do proxy e não tem corpo JSON
429Too Many RequestsRate limit excedido. Veja Políticas de Rate Limit
500Internal Server ErrorErro inesperado. Veja a observação abaixo
Nem todo 500 é falha do servidor

Hoje, JSON malformado, valor inválido em campo de enum (por exemplo "signOrder": "X") e parâmetro ou arquivo obrigatório ausente em upload multipart/form-data caem no erro genérico e voltam como 500. Se receber 500, confira o formato da requisição antes de repetir.

Formato padrão de erro​

As respostas de erro seguem este formato JSON:

{
"title": "Invalid Arguments!",
"status": 400,
"details": "Validation failed",
"timestamp": "2026-09-12T14:30:00Z",
"fields": {
"title": "Título é obrigatório"
}
}
CampoTipoDescrição
titlestringResumo do erro
statusintegerO mesmo status HTTP da resposta
detailsstringDescrição do erro. Em erro de regra de negócio, traz o motivo específico
timestampstringMomento do erro (ISO 8601, UTC)
fieldsobjectEm erro de validação, o nome de cada campo inválido e a mensagem. Nos demais erros vem vazio ({})
devMsgstringInformação técnica. Não aparece em produção, exceto na resposta 429. Aparece no sandbox
Idioma das mensagens

title e details saem em inglês por padrão. Envie o header Accept-Language: pt-BR para receber em português (por exemplo "Argumentos inválidos!" e "Falha na validação"). As mensagens de validação dos campos e os motivos de regra de negócio têm texto próprio e podem vir em português mesmo sem o header.

Dica

Trate os erros pelo status HTTP e pelo objeto fields. Os textos de title e details podem mudar sem aviso.

Exemplos de respostas de erro​

400: erro de validação​

{
"title": "Invalid Arguments!",
"status": 400,
"details": "Validation failed",
"timestamp": "2026-09-12T14:30:00Z",
"fields": {
"title": "Título é obrigatório",
"signOrder": "Ordem de assinatura é obrigatória"
}
}

400: regra de negócio​

{
"title": "Business rule violation!",
"status": 400,
"details": "Envelope só pode ser enviado a partir de DRAFT. Status atual: SENT",
"timestamp": "2026-09-12T14:30:00Z",
"fields": {}
}

401: não autenticado​

A resposta 401 por token ausente ou inválido tem um formato próprio:

{
"timestamp": "2026-09-12T14:30:00Z",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/v1/envelopes"
}

Com token JWT, a sessão também pode ter sido encerrada por um login mais novo do mesmo usuário:

{
"error": "SESSION_REVOKED",
"message": "Your session was ended because you logged in on another device"
}

402: plano sem acesso​

{
"title": "Plan Required",
"status": 402,
"details": "API access requires an active plan. Please upgrade your subscription.",
"timestamp": "2026-09-12T14:30:00Z",
"fields": {}
}

403: sem permissão​

{
"title": "Access denied!",
"status": 403,
"details": "Access denied",
"timestamp": "2026-09-12T14:30:00Z",
"fields": {}
}

404: recurso não encontrado​

{
"title": "Resource not found!",
"status": 404,
"details": "Resource not found",
"timestamp": "2026-09-12T14:30:00Z",
"fields": {}
}

409: conflito​

{
"title": "Data integrity error!",
"status": 409,
"details": "Data integrity violation",
"timestamp": "2026-09-12T14:30:00Z",
"fields": {}
}

429: rate limit​

Veja o corpo completo em Políticas de Rate Limit.

500: erro interno​

{
"title": "Internal server error!",
"status": 500,
"details": "An unexpected error occurred",
"timestamp": "2026-09-12T14:30:00Z",
"fields": {}
}
Erros 500

Se o erro persistir, escreva para [email protected] com o método e a rota chamados, o horário (em UTC) e o corpo da requisição e da resposta, sem incluir a sua chave de API.

Tratamento de erros​

Exemplo em JavaScript​

async function createEnvelope(data, attempt = 0) {
const response = await fetch('https://api.tapsign.com.br/v1/envelopes', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.TAPSIGN_API_KEY}`,
'Content-Type': 'application/json',
'Accept-Language': 'pt-BR'
},
body: JSON.stringify(data)
});

if (response.ok) {
return response.json();
}

const error = await response.json().catch(() => ({}));

switch (response.status) {
case 400:
// Campos inválidos (fields) ou regra de negócio (details)
console.error('Requisição inválida:', error.details, error.fields);
break;

case 401:
console.error('Chave de API ausente, inválida ou desativada');
break;

case 402:
console.error('A conta não tem plano com acesso à API');
break;

case 429:
if (attempt < 3) {
const retryAfter = Number(response.headers.get('Retry-After') || 60);
await new Promise(r => setTimeout(r, retryAfter * 1000));
return createEnvelope(data, attempt + 1);
}
break;

default:
console.error(`Erro ${response.status}: ${error.title ?? ''} ${error.details ?? ''}`);
}

throw new Error(`TapSign respondeu ${response.status}`);
}

Exemplo em Python​

import os
import time
import requests

def create_envelope(data, attempt=0):
response = requests.post(
"https://api.tapsign.com.br/v1/envelopes",
headers={
"Authorization": f"Bearer {os.environ['TAPSIGN_API_KEY']}",
"Accept-Language": "pt-BR",
},
json=data,
)

if response.ok:
return response.json()

try:
error = response.json()
except ValueError:
error = {}

if response.status_code == 400:
print(f"Requisição inválida: {error.get('details')} {error.get('fields')}")

elif response.status_code == 401:
print("Chave de API ausente, inválida ou desativada")

elif response.status_code == 402:
print("A conta não tem plano com acesso à API")

elif response.status_code == 429 and attempt < 3:
time.sleep(int(response.headers.get("Retry-After", 60)))
return create_envelope(data, attempt + 1)

raise Exception(f"TapSign respondeu {response.status_code}: {error.get('title')} {error.get('details')}")
Boas práticas
  1. Use o status HTTP e o objeto fields para tratar erros, e não o texto das mensagens
  2. Faça retry em 429 e 5xx com espera; não repita um 400 sem corrigir a requisição
  3. Registre método, rota, horário e corpo da resposta para facilitar o suporte
  4. Em 401 com chave de API, confira se a chave está ativa na tela de Integrações
  5. Valide os dados localmente antes de enviar, para reduzir erros 400

Próxima seção: Criar Documento: crie documentos via API.