Pular para o conteúdo principal

API REST: o SignSession Contract

O Servidor implementa o SignSession Contract, a API que uma aplicação cliente chama para abrir uma Sessão de Assinatura vinculada a um CPF, opcionalmente em nome de uma Empresa, e assinar documentos nela. Esta página trata da autenticação, do ciclo de vida da sessão, de cada operação, do envelope de erro e de qual documento é a especificação do contrato.

dica

Com o Servidor em execução, o contrato legível por máquina é servido em /openapi/v1.json (OpenAPI 3.1) e uma referência navegável em /scalar. Os dois respondem sem credencial. Esta página é o guia conceitual; o documento publicado é a fonte de verdade para os detalhes de cada campo.

Versão do contrato e caminho base​

Toda operação é servida sob /v1, e nada mais responde: uma chamada a uma rota sem o prefixo é recusada com 404 ENDPOINT_NOT_FOUND. v1 é a versão do contrato, a única à qual um cliente deve se fixar. O campo version do documento OpenAPI é a versão do build do Servidor e não diz nada sobre compatibilidade de protocolo.

Autenticação​

Toda operação exige o header X-API-Key, com uma chave de API emitida para uma Aplicação Cliente no console administrativo. Qualquer uma das chaves de uma aplicação autentica toda a superfície; a chave não restringe nada dentro dela. Chaves ausentes, desconhecidas, revogadas, expiradas e de aplicações desativadas são todas recusadas da mesma forma, com 401 UNAUTHORIZED.

Trate um sessionId e um signatureId como tokens de portador (bearer tokens) daquilo que identificam: qualquer chave aceita pode usar uma sessão ou buscar um documento cujo id ela tenha.

Toda resposta, inclusive as de erro, traz um X-Correlation-Id gerado pelo Servidor. Informe-o ao relatar um problema; ele leva o operador a todo o rastro da requisição.

O ciclo de vida da sessão​

POST /v1/sessions (cpf, pin[, cnpj]) ──▶ 201 { sessionId, expiresIn, expiresAt }
│
├──▶ GET /v1/sessions/status?sessionId=… is it still active? (never extends it)
├──▶ GET /v1/certificates/info?sessionId=… which certificate, which verdict
├──▶ POST /v1/signatures (sessionId, document) ──▶ 202 { signatureId, fileName }
├──▶ POST /v1/signatures/batch (sessionId, files[]) ──▶ 202 { results[] }
│ └──▶ GET /v1/signatures/{signatureId}/document ──▶ 200 PDF | 409 | 422
└──▶ POST /v1/sessions/deactivate (sessionId) ──▶ 200
  1. Crie uma sessão com o CPF e o PIN do titular, e com um CNPJ para assinar em nome de uma Empresa. O Servidor tenta primeiro os Certificados do Cofre guardados para esse CPF. Se nenhum servir, as estações de trabalho que têm um certificado do CPF são solicitadas a provar que têm o PIN em uso ali, e o Servidor confere cada prova contra o PIN que você enviou. O PIN não vai além do Servidor: nenhuma estação de trabalho o recebe, e ele nunca é apresentado ao token. Se nenhuma estação de trabalho tiver esse PIN em cache, o titular recebe uma solicitação no Tray App e esta requisição fica aberta até que ele responda ou a solicitação expire (60 s por padrão). Leve isso em conta no timeout do seu cliente. O certificado que confirmar o PIN é o que fica vinculado à sessão.
  2. Assine na sessão, um documento por vez ou em lote. A assinatura inteira acontece dentro da requisição e normalmente leva alguns segundos.
  3. Busque o PDF assinado pelo id da assinatura. É também aí que se lê o resultado de uma assinatura.
  4. Desative a sessão quando o trabalho terminar, ou deixe a janela de inatividade se esgotar.

Há no máximo uma sessão ativa por CPF, ou por CPF e CNPJ numa sessão em nome de uma Empresa; criar outra para o mesmo par substitui a anterior. Assinar estende a janela de inatividade; consultar o status, não. Uma sessão também termina quando a Franquia de Assinaturas opcional da implantação se esgota.

Uma sessão vinculada a um Certificado do Cofre se apoia em um segredo guardado apenas na memória do Servidor, então reiniciar o Servidor a encerra: o cliente recebe SESSION_EXPIRED na chamada seguinte e se recupera criando uma nova sessão com o mesmo PIN. Uma sessão vinculada a uma estação de trabalho sobrevive ao mesmo reinício.

Workstation 1.5.0 e Servidor 1.13.0

A partir do Servidor 1.13.0, só estações de trabalho com o Workstation 1.5.0 ou posterior recebem pedidos de prova de PIN ou solicitações de PIN. Uma máquina com uma versão anterior continua assinando nas sessões já vinculadas a ela, mas, na criação de sessão, conta como offline: um titular cujas máquinas tenham todas uma versão anterior recebe 422 WORKSTATION_OFFLINE até que uma delas seja atualizada. Veja Instalação da estação de trabalho.

Operações​

POST /v1/sessions: criar uma Sessão de Assinatura​

curl -s https://trustbridge.example.com/v1/sessions \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{ "cpf": "12345678909", "pin": "1234", "sessionDuration": 3600, "email": "holder@example.com" }'
Campo
cpfobrigatórioOnze dígitos, sem pontuação. Os dígitos verificadores são conferidos, e os onze valores de dígitos repetidos são recusados, com 400 INVALID_REQUEST. Numa sessão em nome de uma Empresa, continua sendo o CPF da pessoa: o responsável pelo e-CNPJ da Empresa.
pinobrigatórioO PIN do certificado, qualquer que seja a custódia. Para um Certificado do Cofre, a senha que abre o arquivo dele.
cnpjopcionalA Empresa em nome da qual assinar, com o e-CNPJ dela. Catorze caracteres, sem pontuação e em maiúsculas: doze dígitos ou letras (o CNPJ alfanumérico é aceito tanto quanto o numérico) seguidos de dois dígitos verificadores. Os dígitos verificadores são conferidos, e doze repetições de um mesmo caractere são recusadas, com 400 INVALID_REQUEST. Se omitido, a sessão é da pessoa, como antes.
sessionDurationopcionalEm segundos. Se omitido, vale a janela padrão do Servidor; acima do máximo, o valor é reduzido ao máximo, não recusado.
emailopcionalUm endereço alternativo do signatário, usado apenas quando o certificado vinculado não traz nenhum. Sem ele, um certificado assim é recusado no momento da assinatura com CERT_INCOMPLETE_IDENTITY.
{ "sessionId": "8f3c…", "cpf": "12345678909", "expiresIn": 3600, "expiresAt": "2026-09-21T15:04:05Z" }

expiresIn é sempre a janela efetivamente concedida. Recusas:

  • 404 CERT_NOT_FOUND: nenhum certificado para o CPF (e CNPJ) em lugar nenhum.
  • 422 CERT_NOT_ACTIVE: todo certificado do CPF (e CNPJ) tem um veredito diferente de ativo.
  • 401 INVALID_PIN: todo certificado candidato foi tentado e nenhum aceitou o PIN.
  • 422 PIN_NOT_AVAILABLE: não foi possível fazer nenhuma comparação. Uma solicitação expirou, foi recusada ou não pôde ser exibida; um Certificado do Cofre não pôde ser aberto; ou tentativas recentes demais contra o certificado não conferiram, e ele só volta a ser consultado quando elas saírem da janela. details diz qual.
  • 422 WORKSTATION_OFFLINE: toda máquina com um certificado ativo está offline, ou com uma versão do Workstation anterior à 1.5.0.
  • 429 TOO_MANY_PIN_ATTEMPTS: bloqueio por CPF.

Sessão em nome de uma Empresa​

Envie cnpj junto com cpf para assinar com o e-CNPJ de uma Empresa. O cpf continua sendo o da pessoa: o responsável por esse e-CNPJ, cujo PIN é este.

curl -s https://trustbridge.example.com/v1/sessions \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{ "cpf": "12345678909", "cnpj": "12ABC34501DE35", "pin": "1234" }'
{ "sessionId": "c71d…", "cpf": "12345678909", "cnpj": "12ABC34501DE35", "expiresIn": 3600, "expiresAt": "2026-09-21T15:04:05Z" }
  • A correspondência é exata. Com cnpj, só um e-CNPJ que traga esse CNPJ e esse CPF pode vincular a sessão, nunca o e-CPF da própria pessoa. Sem ele, só o e-CPF da pessoa pode, nunca um e-CNPJ, mesmo que traga o mesmo CPF.
  • Uma sessão ativa por CPF e CNPJ. A sessão da pessoa e a da Empresa dela convivem, e as de dois responsáveis pela mesma Empresa também. Encerrar uma não afeta a outra.
  • O bloqueio por PIN continua por CPF, qualquer que seja o cnpj enviado, ou nenhum: um mesmo cartão costuma guardar os dois certificados atrás de um só PIN, então as falhas em qualquer um deles contam juntas.
  • As respostas devolvem o cnpj sempre que trazem o CPF da sessão: na criação, na desativação e na descrição do certificado. Uma sessão sem ele responde sem nenhum membro cnpj (nem com null), então uma integração que nunca o envia não vê nada de novo.

GET /v1/sessions/status?sessionId=…: verificar uma sessão​

Responde o estado da sessão e quanto tempo ela ainda tem. Um id que não identifica nada ativo ainda responde 200 com active: false; omitir o id resulta em 400. Pode ser consultado periodicamente sem risco; nunca estende a janela. Não há como perguntar se um CPF tem uma sessão: um cliente que perdeu o id cria uma nova sessão.

{ "active": true, "sessionId": "8f3c…", "expiresIn": 3412, "expiresAt": "2026-09-21T15:04:05Z" }

POST /v1/sessions/deactivate: encerrar uma sessão​

curl -s https://trustbridge.example.com/v1/sessions/deactivate \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" -d '{ "sessionId": "8f3c…" }'

Encerra a sessão imediatamente e descarta o segredo em que ela se apoiava (o PIN que uma estação de trabalho tinha em cache para ela, ou a senha que o Servidor guardava para abrir um Certificado do Cofre). Não é idempotente: sem nada ativo, responde 401 SESSION_EXPIRED. A resposta informa o CPF lido da sessão (e o cnpj dela, numa sessão em nome de uma Empresa), o id, active: false e endedAt.

GET /v1/certificates/info?sessionId=…: descrever o certificado vinculado​

O certificado ao qual a sessão está vinculada, como a plataforma o registrou pela última vez: cpf (o titular do certificado, que não precisa ser igual ao CPF da sessão; num e-CNPJ, o CPF do responsável pelo certificado em nome da Empresa), cnpj (só num e-CNPJ), subjectName, issuer, serialNumber, notBefore, notAfter e status. Verifique status antes de assinar: um veredito pode mudar enquanto a sessão está ativa, e só ACTIVE pode assinar. Exige uma sessão ativa; nunca a estende.

POST /v1/signatures: assinar um documento​

Há dois formatos de corpo. JSON, com o documento codificado em base64:

curl -s https://trustbridge.example.com/v1/signatures \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d "{ \"sessionId\": \"8f3c…\", \"document\": \"$(base64 -w0 contract.pdf)\", \"fileName\": \"contract.pdf\" }"

Ou multipart, com um campo sessionId e o PDF como parte de arquivo (o nome do arquivo é tirado da parte):

curl -s https://trustbridge.example.com/v1/signatures \
-H "X-API-Key: $API_KEY" \
-F "sessionId=8f3c…" -F "document=@contract.pdf"

Qualquer parte de arquivo é lida como o documento, seja qual for o nome do campo. Só uma é assinada: quando a requisição traz várias, vence document, depois file, depois a primeira que chegou.

Responde 202:

{ "signatureId": "a1b2…", "fileName": "contract.pdf", "status": "PROCESSING", "acceptedAt": "2026-09-21T14:10:00Z" }

fileName é o nome com que o Servidor assinou o documento, que nem sempre é o enviado: o fileName da requisição, ou o nome da própria parte de arquivo (filename* quando a parte traz um); document.pdf quando esse nome está ausente ou vazio; e cortado em 260 caracteres, o que pode levar a extensão junto. Quando uma requisição multipart trouxe várias partes de arquivo, ele indica qual foi assinada.

Um 202 não significa "deu certo". Depois que o documento chega ao serviço de assinatura, esta operação responde o id aconteça o que acontecer em seguida, porque o id é o único caminho de volta a um documento que pode ter sido assinado. O resultado é lido na busca. signatureId é o id do documento no próprio Lacuna Signer. Só PDFs são assinados (422 UNSUPPORTED_DOCUMENT); um documento acima de Signing:MaxDocumentBytes (10 MB por padrão, medidos sobre os bytes decodificados) resulta em 413 DOCUMENT_TOO_LARGE; nenhum documento resulta em 400 INVALID_DOCUMENT; um sessionId ausente resulta em 400 INVALID_REQUEST.

Duas respostas do serviço de assinatura significam coisas opostas. 422 SIGNER_REJECTED é o serviço recusando a requisição (em geral o documento, às vezes outra coisa que a requisição indicou; details diz qual): reenviá-la sem mudança traz a mesma resposta. 502 SIGNER_ERROR é o serviço inacessível, limitando requisições ou falhando antes de o documento chegar a ele: nada foi assinado, e o mesmo documento pode ser reenviado quando o serviço voltar.

POST /v1/signatures/batch: assinar vários documentos​

Somente multipart/form-data: um campo sessionId e uma parte de arquivo por documento, até Signing:MaxBatchItems (50 por padrão).

curl -s https://trustbridge.example.com/v1/signatures/batch \
-H "X-API-Key: $API_KEY" \
-F "sessionId=8f3c…" -F "files=@a.pdf" -F "files=@b.pdf" -F "files=@c.pdf"

Responde 202 com um resultado por documento, na ordem em que as partes chegaram:

{
"results": [
{ "fileName": "a.pdf", "signatureId": "a1b2…", "status": "PROCESSING", "error": null },
{ "fileName": "b.pdf", "signatureId": null, "status": "ERROR",
"error": { "code": "DOCUMENT_TOO_LARGE", "message": "…" } },
{ "fileName": "c.pdf", "signatureId": "c3d4…", "status": "PROCESSING", "error": null }
],
"acceptedAt": "2026-09-21T14:10:00Z"
}

Cada documento é independente: um que falhou traz status: "ERROR" e um código do mesmo vocabulário, enquanto os demais trazem ids. Leia os resultados, não o código de status. Cada item, com falha ou não, recebe o nome pela mesma regra do fileName da assinatura individual. A chamada inteira só falha por algo que valha para todos eles: nenhum sessionId (400 INVALID_REQUEST), nenhuma sessão ativa, um certificado que não pode assinar, mais documentos que o limite (400 INVALID_REQUEST) ou nenhum (400 INVALID_DOCUMENT). Os documentos são assinados vários de cada vez, até Signing:SignerConcurrency, e a chamada inteira é aguardada, então um lote grande leva o tempo de assinar todos os documentos dele. Um lote conta como uma chamada para o throttle e para a Franquia de Assinaturas.

GET /v1/signatures/{signatureId}/document: buscar o documento assinado​

curl -s https://trustbridge.example.com/v1/signatures/a1b2…/document \
-H "X-API-Key: $API_KEY" -o signed.pdf -w '%{http_code}\n'
StatusSignificado
200O PDF assinado, como corpo da resposta.
409 DOCUMENT_NOT_READYAinda está sendo assinado. Pergunte de novo.
422 DOCUMENT_UNAVAILABLETerminou sem versão assinada: details diz Refused, Canceled ou Expired. Não há o que esperar.
404 DOCUMENT_NOT_FOUNDNenhum documento tem esse id, inclusive um que o serviço de assinatura não guarda.
502 SIGNER_ERRORNão foi possível consultar o serviço de assinatura (inacessível, limitando requisições ou com falha); o documento não foi afetado. Pergunte de novo em instantes.

O Servidor não armazena nada, então o tempo durante o qual um documento pode ser buscado é a retenção do Lacuna Signer. Qualquer chave de API válida pode buscar qualquer documento cujo id conheça, inclusive um criado por outra Aplicação Cliente. Isso é o contrato, e não um descuido: trate um signatureId como um token de portador do documento dele.

O envelope de erro​

Todo erro chega em um único envelope. code é uma string, não um conjunto fechado: trate um código desconhecido como uma falha inesperada, e não como um erro de parsing. Decida com base em code, nunca em message.

{ "error": { "code": "CERT_NOT_ACTIVE", "message": "…", "details": "…" } }

"O CPF", abaixo, significa o CPF e o CNPJ juntos numa sessão em nome de uma Empresa. O bloqueio por PIN é a única exceção, e continua por CPF.

CódigoHTTPSignificado
INVALID_REQUEST400, 415Requisição malformada, ou um corpo em um media type que a operação não lê. details diz o que estava errado: por exemplo, um sessionId ausente, ou um CPF ou CNPJ com dígitos verificadores errados.
INVALID_DOCUMENT400Nenhum documento a assinar chegou, ou ele estava vazio.
UNAUTHORIZED401A chave de API não foi aceita.
SESSION_EXPIRED401Nenhuma Sessão de Assinatura ativa tem o sessionId informado: expirada, desativada, substituída, esgotada ou interrompida. Crie uma nova sessão.
INVALID_PIN401O PIN não abriu nenhum Certificado do Cofre do CPF e é diferente do PIN em uso em todas as estações de trabalho que têm um certificado dele: todo candidato foi tentado, e nenhum conferiu.
CERT_NOT_FOUND404Na criação: nenhum certificado para o CPF em lugar nenhum, nem no cofre nem em uma estação de trabalho. Na leitura ou na assinatura: o certificado vinculado não está mais disponível.
DOCUMENT_NOT_FOUND404Nenhum documento tem esse id de assinatura.
ENDPOINT_NOT_FOUND404Nenhuma operação responde a esse método e caminho. Verifique o prefixo /v1.
DOCUMENT_NOT_READY409Ainda está sendo assinado. Vale perguntar de novo.
DOCUMENT_TOO_LARGE413O documento ou o corpo da requisição excede o limite do Servidor; details informa o tamanho e o limite.
CERT_NOT_ACTIVE422Todo certificado do CPF, ou o certificado vinculado, tem um veredito diferente de ativo (EXPIRED, REVOKED, UNTRUSTED, STALE).
DOCUMENT_UNAVAILABLE422O documento terminou sem versão assinada: recusado, cancelado ou expirado. Não há o que esperar.
PIN_NOT_AVAILABLE422Não foi possível fazer nenhuma comparação: uma solicitação expirou, foi recusada ou não pôde ser exibida, um Certificado do Cofre não pôde ser aberto, ou tentativas recentes demais contra o certificado não conferiram. details diz qual.
WORKSTATION_OFFLINE422Todo certificado ativo do CPF está em uma estação de trabalho, e todas elas estão offline (depois da tolerância de reconexão, em uma assinatura).
CERT_DATA_UNAVAILABLE422Os dados do próprio certificado, necessários para assinar, não estão guardados para ele.
CERT_INCOMPLETE_IDENTITY422O certificado não identifica o titular o suficiente para assinar; details indica o campo que falta. Um endereço de e-mail é o único campo que o email da sessão pode suprir.
UNSUPPORTED_DOCUMENT422Não é um PDF.
SIGNER_REJECTED422O serviço de assinatura recusou a requisição, em geral o próprio documento; details traz a explicação dele e diz qual. Repetir sem mudança dá o mesmo resultado.
SIGN_TIMEOUT422A assinatura não terminou dentro do tempo dado a uma requisição (60 s por padrão); nada foi assinado.
SERVER_BUSY429O Servidor está executando tantas chamadas do contrato quanto aceita e a fila dele está cheia. Nada na requisição foi recusado: tente de novo com um backoff próprio, com jitter. Nenhum Retry-After é enviado.
TOO_MANY_PIN_ATTEMPTS429O bloqueio por PINs incorretos do CPF está em vigor, qualquer que seja o cnpj enviado com o CPF, ou nenhum. Refere-se a um CPF, em todas as chaves de API; tentar de novo piora a situação. Some à medida que as falhas mais antigas saem da janela (15 min por padrão).
INTERNAL_ERROR500Não foi possível concluir a requisição; é seguro tentar de novo.
SIGNER_ERROR502Não foi possível consultar o serviço de assinatura: inacessível, limitando requisições ou respondendo com uma falha própria. Em uma assinatura, só chega antes de o documento ter chegado ao serviço, então nada foi assinado; em uma busca, não diz nada sobre o documento.

Dois 429 diferentes. SERVER_BUSY diz respeito ao Servidor naquele momento e se resolve sozinho; TOO_MANY_PIN_ATTEMPTS diz respeito ao certificado de uma pessoa e não se resolve com novas tentativas. Um cliente que decide só pelo status vai tratá-los da mesma forma, e é por isso que são códigos separados.

A especificação​

A descrição normativa do contrato é a especificação de referência do SignSession (SignSession — Documentação de referência), escrita em português a partir da implementação deste Servidor e adotada pelo autor da especificação do contrato no lugar do documento de integração anterior. Peça uma cópia à Lacuna Software. O documento OpenAPI que um Servidor em execução serve em /openapi/v1.json é gerado a partir do próprio Servidor e mantido idêntico ao que ele responde. Se os dois discordarem, um deles está errado: informe a diferença em vez de supor que ela é intencional.

Os códigos que o documento OpenAPI marca como TrustBridge extension são os que a especificação original não definia. A especificação atual os traz com a mesma marca; eles fazem parte do contrato como qualquer outro.

Vindo do documento de integração anterior​

Um cliente escrito com base no documento de integração anterior, ou na outra implementação do contrato (o CertSession), encontra estas respostas. Todas elas agora são o contrato, e duas são silenciosas: produzem um comportamento diferente sem nenhum erro que o indique.

O que um cliente encontraO que fazer
Toda rota tem o prefixo /v1. Uma rota sem o prefixo responde 404 ENDPOINT_NOT_FOUND.Use o prefixo em todas as chamadas. Não há header nem media type de versão.
Uma sessão é identificada pelo sessionId, e não por um CPF. Só a criação recebe um CPF; status, informações do certificado, assinatura e desativação recebem o id.Guarde o sessionId. Nenhuma chamada o recupera a partir de um CPF.
expiresIn nunca é nulo. Um sessionDuration omitido concede a janela padrão, e não uma ilimitada.Silencioso. Leia expiresIn e expiresAt na resposta, em vez de supor a janela que você pediu.
Assinar estende a sessão em vez de encerrá-la, a menos que a implantação tenha definido uma Franquia de Assinaturas (uma franquia de 1 dá sessões de uso único).Silencioso. Um cliente que cria uma sessão por documento continua funcionando, ao custo de mais uma confirmação de PIN a cada vez. Para encerrar a sessão junto com o documento, chame POST /v1/sessions/deactivate.
Um cpf precisa ser um CPF real: dígitos verificadores conferidos, valores de dígitos repetidos recusados.400 INVALID_REQUEST. Valide os dígitos verificadores também no seu formulário; o pattern do schema (^[0-9]{11}$) não consegue expressá-los.
Uma chamada de assinatura sem sessionId é malformada, individual ou em lote.400 INVALID_REQUEST: corrija a requisição. Um 401 SESSION_EXPIRED significa criar uma sessão e tentar de novo.
Os certificados são validados quanto à cadeia e à revogação, não só quanto à expiração.CERT_NOT_ACTIVE com UNTRUSTED, REVOKED ou STALE onde uma verificação só de expiração assinaria.
O Servidor descarta carga.429 SERVER_BUSY. Tente de novo após um backoff próprio; usar lotes reduz a frequência com que isso acontece.
O resultado é lido na busca. Não há webhook a registrar.Consulte GET /v1/signatures/{signatureId}/document até receber 200 ou 422.
Qualquer chave de API válida busca qualquer documento cujo signatureId conheça.Trate o id como um token de portador: não o registre em log nem o entregue a quem não deve ter o documento.

Como escrever um cliente robusto​

  • Guarde o sessionId. Nenhuma chamada o recupera a partir de um CPF.
  • Esteja pronto para SESSION_EXPIRED em qualquer chamada e recupere-se criando uma nova sessão. Você não tem como saber se uma implantação definiu uma Franquia de Assinaturas, nem deveria.
  • Leia o resultado na busca. Um 202 diz que o documento foi aceito, não assinado. Consulte o endpoint do documento periodicamente enquanto receber 409; pare em 200 ou 422.
  • Defina um timeout generoso em POST /v1/sessions. Uma criação que vai para uma solicitação no Tray aguarda uma pessoa, até o timeout da solicitação mais alguns segundos.
  • Decida com base em error.code e trate os dois 429 de forma diferente. Não reenvie sem mudança um documento recusado com SIGNER_REJECTED; reenvie um que recebeu SIGNER_ERROR.
  • Use lotes quando tiver muitos documentos. Uma chamada, uma vaga no throttle, um débito na franquia.
  • Envie email se algum certificado com que você assina puder não trazer endereço.
  • Envie cnpj só para assinar em nome de uma Empresa. Uma sessão sem ele nunca se vincula a um e-CNPJ, e uma com ele nunca se vincula ao e-CPF da pessoa.

Testando o contrato manualmente​

A Lacuna Software pode fornecer uma coleção do Postman com o contrato como este Servidor o implementa, com um environment que traz um pequeno PDF codificado em base64 e um cnpj de exemplo. Importe os dois, cole em apiKey uma chave de API emitida na tela Aplicações Cliente e execute as requisições em ordem: crie uma sessão (acompanhe a solicitação no Tray App se não houver PIN em cache), assine um documento e busque-o. Uma segunda requisição de criação faz o mesmo para uma Empresa, enviando o cnpj do environment. A coleção grava sessionId e signatureId no environment, então não é preciso colar nada entre um passo e outro. Quando a coleção e o /openapi/v1.json publicado pelo Servidor discordarem, vale o documento publicado.

Ver em Markdown