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ódigo | Status | Quando acontece |
|---|---|---|
200 | OK | Requisição processada com sucesso |
201 | Created | Recurso criado com sucesso |
204 | No Content | Processada, sem corpo na resposta (ex.: DELETE) |
400 | Bad Request | Campo inválido, parâmetro com tipo errado ou regra de negócio violada (ex.: enviar um envelope que não está em rascunho) |
401 | Unauthorized | Token ausente, inválido ou expirado; chave de API desativada ou excluída |
402 | Payment Required | A conta não tem plano com acesso ao recurso (ex.: criar chave de API fora dos planos Equipe e Enterprise) |
403 | Forbidden | Autenticado, mas sem permissão (ex.: recurso de uma organização da qual você não participa) |
404 | Not Found | Recurso inexistente ou de outro usuário, ou rota inexistente |
405 | Method Not Allowed | Método HTTP não aceito na rota |
409 | Conflict | Conflito com dados existentes (ex.: convite ou membro já existente) |
413 | Payload Too Large | Arquivo acima de 10 MB. Essa resposta vem do proxy e não tem corpo JSON |
429 | Too Many Requests | Rate limit excedido. Veja Políticas de Rate Limit |
500 | Internal Server Error | Erro inesperado. Veja a observação abaixo |
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"
}
}
| Campo | Tipo | Descrição |
|---|---|---|
title | string | Resumo do erro |
status | integer | O mesmo status HTTP da resposta |
details | string | Descrição do erro. Em erro de regra de negócio, traz o motivo específico |
timestamp | string | Momento do erro (ISO 8601, UTC) |
fields | object | Em erro de validação, o nome de cada campo inválido e a mensagem. Nos demais erros vem vazio ({}) |
devMsg | string | Informação técnica. Não aparece em produção, exceto na resposta 429. Aparece no sandbox |
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.
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": {}
}
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')}")
- Use o status HTTP e o objeto
fieldspara tratar erros, e não o texto das mensagens - Faça retry em 429 e 5xx com espera; não repita um 400 sem corrigir a requisição
- Registre método, rota, horário e corpo da resposta para facilitar o suporte
- Em 401 com chave de API, confira se a chave está ativa na tela de Integrações
- Valide os dados localmente antes de enviar, para reduzir erros 400
Próxima seção: Criar Documento: crie documentos via API.