SignDocs Brasil External API
Todas as respostas de erro da API SignDocs Brasil seguem o formato RFC 7807 Problem Details
(Content-Type: application/problem+json).
{
"type": "https://api.signdocs.com.br/errors/<tipo-do-erro>",
"title": "<Texto do Status HTTP>",
"status": 400,
"detail": "<explicação legível do erro>",
"instance": "/v1/transactions/abc-123"
}
| Campo | Tipo | Descrição |
|---|---|---|
type |
string |
URI que identifica o tipo do erro. Estável entre versões da API. |
title |
string |
Texto curto do status HTTP (ex.: "Bad Request"). |
status |
number |
Código de status HTTP. |
detail |
string |
Explicação legível sobre o que deu errado nesta requisição. |
instance |
string |
Caminho da requisição que gerou o erro. |
Campos adicionais podem estar presentes dependendo do tipo de erro (ex.: issues para
erros de validação de certificado).
Tipo: https://api.signdocs.com.br/errors/bad-request
A requisição contém dados inválidos, campos obrigatórios ausentes ou valores em formato incorreto. Exemplos comuns:
signer.name, signer.cpf/cnpj, url, etc.)client_id, email, base64)grant_type diferente de client_credentials)Content-Type incorreto no endpoint de token (application/x-www-form-urlencoded){
"type": "https://api.signdocs.com.br/errors/bad-request",
"title": "Bad Request",
"status": 400,
"detail": "signer.cpf must be exactly 11 digits",
"instance": "/v1/transactions"
}
Content-Type está correto para o endpoint utilizado.Tipo: https://api.signdocs.com.br/errors/unauthorized
A requisição não possui credenciais válidas de autenticação. Causas comuns:
Authorization ausente ou mal formatadoclient_id/client_secret) incorretas ou revogadas{
"type": "https://api.signdocs.com.br/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid or missing authentication",
"instance": "/v1/transactions"
}
POST /oauth2/token com credenciais válidas.exp do JWT).Tipo: https://api.signdocs.com.br/errors/forbidden
A autenticação foi aceita, mas o usuário/credencial não tem permissão para a operação. Causas comuns:
role) insuficiente para a operação admin{
"type": "https://api.signdocs.com.br/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Insufficient permissions",
"instance": "/v1/transactions/tx_abc123"
}
scopes) associados à credencial no painel administrativo.Admin no
Cognito e possui o papel MASTER.Tipo: https://api.signdocs.com.br/errors/not-found
O recurso solicitado não existe ou não pertence ao tenant autenticado. Causas comuns:
{
"type": "https://api.signdocs.com.br/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "Transaction not found",
"instance": "/v1/transactions/tx_nao_existe"
}
Tipo: https://api.signdocs.com.br/errors/conflict
A requisição conflita com o estado atual do recurso. Esta é a classe de erro mais comum em operações de fluxo da transação. Cenários típicos:
STEPS_COMPLETEDSTARTEDOTP_CHALLENGE)DOCUMENT_SIGNATUREIdempotency-Key mas corpo diferente{
"type": "https://api.signdocs.com.br/errors/conflict",
"title": "Conflict",
"status": 409,
"detail": "Transaction cannot be finalized in status: CREATED",
"instance": "/v1/transactions/tx_abc123/finalize"
}
GET antes de executar a operação.OTP_CHALLENGE novamente via POST /v1/steps/{id}/start.Idempotency-Key.Tipo: https://api.signdocs.com.br/errors/unprocessable-entity
A requisição é sintaticamente válida, mas não pode ser processada por regras de negócio ou pré-condições não atendidas. Causas comuns:
issues contém detalhes)pdf-quality-validation-failed — O PDF não atende aos critérios mínimos de qualidade (resolução insuficiente, páginas em branco ou arquivo corrompido)pdf-password-protected — O PDF está protegido por senha e não pode ser processadofeature-not-enabled — A funcionalidade solicitada não está habilitada para o tenant. Exemplos:
documentExtractionEnabled — necessário para enrollment com source DOCUMENT_PHOTOserpro.enabled — necessário para etapas SERPRO_IDENTITY_CHECKhostedLivenessEnabled — necessário para modo HOSTED_PAGEgeolocation-required — O campo geolocation é obrigatório para etapas biométricas quando o tenant possui biometricRequired habilitado{
"type": "https://api.signdocs.com.br/errors/unprocessable-entity",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Certificate validation failed",
"instance": "/v1/signing/prepare",
"issues": [
"Certificate CN does not match signer name",
"Certificate expired on 2025-01-15T00:00:00Z"
]
}
issues para detalhes específicos.POST /v1/users/{userExternalId}/enrollment antes de iniciar a etapa biométrica.Tipo: https://api.signdocs.com.br/errors/too-many-requests
O tenant excedeu os limites de taxa da API. A SignDocs Brasil aplica dois tipos de limites:
| Header | Descrição |
|---|---|
Retry-After |
Segundos até o limite ser resetado. |
RateLimit-Limit |
Limite total configurado para a janela. |
RateLimit-Remaining |
Requisições restantes na janela atual. |
RateLimit-Reset |
Segundos até o reset da janela atual. |
{
"type": "https://api.signdocs.com.br/errors/too-many-requests",
"title": "Too Many Requests",
"status": 429,
"detail": "Daily transaction quota exceeded (100/100)",
"instance": "/v1/transactions"
}
Retry-After: 3600
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 3600
Retry-After e aguarde antes de tentar novamente.RateLimit-* nas respostas de sucesso para evitar atingir o
limite.Tipo: https://api.signdocs.com.br/errors/internal-server-error
Um erro inesperado ocorreu no servidor. Por segurança, detalhes internos nunca são expostos ao cliente. Causas possíveis (internas):
{
"type": "https://api.signdocs.com.br/errors/internal-server-error",
"title": "Internal Server Error",
"status": 500,
"instance": "/v1/transactions"
}
Note que o campo detail está ausente intencionalmente para não expor informações
internas.
instance path e o horário da requisição.Tipo: https://api.signdocs.com.br/errors/service-unavailable
Um serviço downstream está temporariamente indisponível. A API mapeia automaticamente erros transientes da AWS para 503:
ProvisionedThroughputExceededException (DynamoDB)ThrottlingException (qualquer serviço AWS)RequestLimitExceededTooManyRequestsExceptionServiceUnavailableExceptionInternalServerError / InternalServiceError (AWS)TransactionConflictException (DynamoDB)| Header | Descrição |
|---|---|
Retry-After |
Segundos recomendados para aguardar antes de retry. |
{
"type": "https://api.signdocs.com.br/errors/service-unavailable",
"title": "Service Unavailable",
"status": 503,
"detail": "A downstream service is temporarily unavailable. Please retry.",
"instance": "/v1/transactions/tx_abc123/finalize"
}
Retry-After: 5
Retry-After (padrão: 5 segundos).Todas as respostas da API (inclusive erros) incluem os seguintes headers de segurança:
| Header | Valor |
|---|---|
Strict-Transport-Security |
max-age=31536000; includeSubDomains |
X-Content-Type-Options |
nosniff |
X-Frame-Options |
DENY |
Referrer-Policy |
strict-origin-when-cross-origin |
Cache-Control |
no-store |
API-Version |
1.0 |
statusUse o código de status HTTP (campo status) para determinar a categoria do erro. O
campo detail fornece contexto legível mas pode mudar entre versões.
type para tratamento programáticoO campo type é estável e pode ser usado em lógica condicional:
const error = await response.json();
switch (error.type) {
case 'https://api.signdocs.com.br/errors/too-many-requests':
await aguardarRetryAfter(response.headers.get('Retry-After'));
break;
case 'https://api.signdocs.com.br/errors/conflict':
await recarregarEstadoDoRecurso();
break;
case 'https://api.signdocs.com.br/errors/unauthorized':
await renovarToken();
break;
}
| Status | Retentável? | Ação recomendada |
|---|---|---|
| 400 | Não | Corrigir a requisição. |
| 401 | Sim* | Renovar token e tentar novamente. |
| 403 | Não | Verificar permissões/escopos. |
| 404 | Não | Verificar ID do recurso. |
| 409 | Não** | Consultar estado atual e ajustar fluxo. |
| 422 | Não | Verificar pré-condições do negócio. |
| 429 | Sim | Aguardar Retry-After + backoff. |
| 500 | Sim | Retry com backoff. |
| 503 | Sim | Aguardar Retry-After + backoff. |
* Renovar o token antes de retentar.
** Exceto TransactionConflictException mapeado para 503, que é retentável.
Para erros retentáveis (429, 500, 503), implemente a seguinte estratégia:
import time
import random
def request_com_retry(fazer_request, max_tentativas=5):
for tentativa in range(max_tentativas):
response = fazer_request()
if response.status_code < 400:
return response
if response.status_code in (429, 503):
retry_after = int(response.headers.get('Retry-After', 0))
espera = max(retry_after, (2 ** tentativa) + random.uniform(0, 1))
time.sleep(espera)
continue
if response.status_code >= 500:
espera = (2 ** tentativa) + random.uniform(0, 1)
time.sleep(espera)
continue
# Erros 4xx (exceto 429) não são retentáveis
raise ApiError(response)
raise MaxRetryError(f"Falhou após {max_tentativas} tentativas")
Regras da estratégia:
Ao entrar em contato com o suporte, inclua as seguintes informações para agilizar a resolução:
instance da resposta -- identifica o endpoint e o recurso.client_id utilizado (nunca envie o client_secret).api-hml.signdocs.com.br) ou produção (api.signdocs.com.br).Canal de suporte: suporte@signdocs.com.br
Severidades: