Baixar e listar documentos
Download das versões de um documento
A partir do momento em que um documento é criado, é possível baixar diferentes versões dele, de acordo com o estágio em que ele se encontra. Utilize a API de Download de Documentos, informando o tipo desejado no parâmetro type:
GET /api/documents/b12cb1b2-5d6e-40b2-a050-097d068c4c11/content?type=Original
Tipos de versão (type)
type | Descrição |
|---|---|
Original | Arquivo original enviado |
Signatures | Arquivo assinado |
PrinterFriendlyVersion | Versão para impressão |
SigningTags | Etiquetas de assinatura |
SignatureMarks | Marcas de assinatura |
OriginalWithMarks | Arquivo original com as marcas de assinatura |
SignaturesManifest | Manifesto de assinaturas |
Existem dois métodos com tipos de retorno diferentes: um retorna uma Stream de dados referente ao documento e o outro retorna o documento em um vetor de bytes[].
Nas bibliotecas cliente:
| Cliente | O arquivo (GET .../content) | Outras formas |
|---|---|---|
| C# | GetDocumentContentAsync(id, DocumentDownloadTypes), uma Stream | GetDocumentContentBytesAsync(id, DocumentDownloadTypes), um DocumentContentModel (Base64); GetDocumentBytesAsync(id, DocumentTicketType), um byte[] |
| Java | getDocumentContent(id, DocumentDownloadTypes), um InputStream | getDocumentBytes(id, DocumentTicketType), um byte[] |
| Node.js | apiDocumentsIdContentGet(id, DocumentDownloadTypes, { responseType: "arraybuffer" }). Sem responseType: "arraybuffer", o axios decodifica o arquivo como texto e o corrompe | apiDocumentsIdContentB64Get(id, DocumentDownloadTypes), os bytes em Base64 |
| PHP | getDocumentContent($id, DocumentDownloadTypes::...), o conteúdo do arquivo | GetDocumentContentBytesAsync($id, DocumentDownloadTypes::...), o JSON de content-b64, com os bytes em Base64 |
O DocumentDownloadTypes do cliente PHP 1.4.10 não tem constante para SignaturesManifest. O getDocumentContent põe o tipo na query string como o recebe, então passe o texto "SignaturesManifest".
Quando uma versão não pode ser baixada
SignaturesePrinterFriendlyVersionsó existem depois que pelo menos um participante assinou. Para um documento que ninguém assinou ainda, a API responde422com o código de erroDocumentHasNoSignatures. Enquanto o documento não estáConcluded,Signaturestraz as assinaturas coletadas até o momento.- Documentos cancelados, expirados ou recusados só podem ser baixados como
OriginalePrinterFriendlyVersion.
Antes de baixar, consulte o documento com a API de Detalhes do Documento e verifique os campos hasSignature e status, como fazem os exemplos. O formato do erro está em Respostas de erro.
Com uma biblioteca cliente, consulte o documento, verifique o status e então baixe Signatures e PrinterFriendlyVersion:
- C#
- Java
- Node.js
- PHP
using Lacuna.Signer.Api;
// 1. Verifique o status
var details = await signerClient.GetDocumentDetailsAsync(documentId);
// details.IsConcluded: o fluxo inteiro terminou
// details.FlowActions[i].Status == ActionStatus.Completed: aquele participante terminou
if (!details.HasSignature)
{
return; // por enquanto só o Original pode ser baixado
}
// 2. Signatures: o arquivo assinado. Não existe para documentos cancelados, recusados ou expirados.
if (details.Status != DocumentStatus.Canceled && details.Status != DocumentStatus.Refused && details.Status != DocumentStatus.Expired)
{
using (var signed = await signerClient.GetDocumentContentAsync(documentId, DocumentDownloadTypes.Signatures))
using (var fileStream = new FileStream("signed.pdf", FileMode.Create, FileAccess.Write))
{
signed.CopyTo(fileStream);
}
}
// 3. PrinterFriendlyVersion: um PDF com as marcas de assinatura e o manifesto de assinaturas
using (var printerFriendly = await signerClient.GetDocumentContentAsync(documentId, DocumentDownloadTypes.PrinterFriendlyVersion))
using (var fileStream = new FileStream("printer-friendly.pdf", FileMode.Create, FileAccess.Write))
{
printerFriendly.CopyTo(fileStream);
}
import com.lacunasoftware.signer.ActionStatus;
import com.lacunasoftware.signer.DocumentDownloadTypes;
import com.lacunasoftware.signer.DocumentStatus;
import com.lacunasoftware.signer.documents.DocumentModel;
// 1. Verifique o status
DocumentModel details = signerClient.getDocumentDetails(documentId);
// details.isIsConcluded(): o fluxo inteiro terminou
// details.getFlowActions().get(i).getStatus() == ActionStatus.COMPLETED: aquele participante terminou
if (!Boolean.TRUE.equals(details.isHasSignature())) {
return; // por enquanto só o Original pode ser baixado
}
// 2. Signatures: o arquivo assinado. Não existe para documentos cancelados, recusados ou expirados.
DocumentStatus status = details.getStatus();
if (status != DocumentStatus.CANCELED && status != DocumentStatus.REFUSED && status != DocumentStatus.EXPIRED) {
try (InputStream signed = signerClient.getDocumentContent(documentId, DocumentDownloadTypes.SIGNATURES)) {
Files.copy(signed, Paths.get("signed.pdf"), StandardCopyOption.REPLACE_EXISTING);
}
}
// 3. PrinterFriendlyVersion: um PDF com as marcas de assinatura e o manifesto de assinaturas
try (InputStream printerFriendly = signerClient.getDocumentContent(documentId, DocumentDownloadTypes.PRINTERFRIENDLYVERSION)) {
Files.copy(printerFriendly, Paths.get("printer-friendly.pdf"), StandardCopyOption.REPLACE_EXISTING);
}
import * as fs from "fs";
import { ActionStatus, DocumentDownloadTypes, DocumentStatus } from "signer-node-client";
// 1. Verifique o status
const details = (await documentsApi.apiDocumentsIdGet(documentId)).data;
// details.isConcluded: o fluxo inteiro terminou
// details.flowActions[i].status === ActionStatus.Completed: aquele participante terminou
if (!details.hasSignature) {
return; // por enquanto só o Original pode ser baixado
}
// 2. Signatures: o arquivo assinado. Não existe para documentos cancelados, recusados ou expirados.
if (
details.status !== DocumentStatus.Canceled &&
details.status !== DocumentStatus.Refused &&
details.status !== DocumentStatus.Expired
) {
// responseType "arraybuffer": sem ele, o axios decodifica o arquivo como texto e o corrompe
const signed = await documentsApi.apiDocumentsIdContentGet(documentId, DocumentDownloadTypes.Signatures, {
responseType: "arraybuffer",
});
fs.writeFileSync("signed.pdf", Buffer.from(signed.data as unknown as ArrayBuffer));
}
// 3. PrinterFriendlyVersion: um PDF com as marcas de assinatura e o manifesto de assinaturas
const printerFriendly = await documentsApi.apiDocumentsIdContentGet(documentId, DocumentDownloadTypes.PrinterFriendlyVersion, {
responseType: "arraybuffer",
});
fs.writeFileSync("printer-friendly.pdf", Buffer.from(printerFriendly.data as unknown as ArrayBuffer));
use Lacuna\Signer\Model\ActionStatus;
use Lacuna\Signer\Model\DocumentDownloadTypes;
use Lacuna\Signer\Model\DocumentsDocumentModel;
use Lacuna\Signer\Model\DocumentStatus;
// 1. Verifique o status
$details = new DocumentsDocumentModel($signerClient->getDocumentDetails($documentId));
// $details->getIsConcluded(): o fluxo inteiro terminou
// $details->getFlowActions()[$i]["status"] == ActionStatus::COMPLETED: aquele participante terminou
if (!$details->getHasSignature()) {
return; // por enquanto só o Original pode ser baixado; getDocumentContent devolveria o JSON do erro
}
// 2. Signatures: o arquivo assinado. Não existe para documentos cancelados, recusados ou expirados.
if (!in_array($details->getStatus(), array(DocumentStatus::CANCELED, DocumentStatus::REFUSED, DocumentStatus::EXPIRED))) {
$signed = $signerClient->getDocumentContent($documentId, DocumentDownloadTypes::SIGNATURES);
file_put_contents("signed.pdf", $signed);
}
// 3. PrinterFriendlyVersion: um PDF com as marcas de assinatura e o manifesto de assinaturas
$printerFriendly = $signerClient->getDocumentContent($documentId, DocumentDownloadTypes::PRINTER_FRIENDLY_VERSION);
file_put_contents("printer-friendly.pdf", $printerFriendly);
O cliente é criado como em Criar documentos. Em produção, saiba que um documento mudou pelos webhooks, em vez de fazer polling dos detalhes.
Como cada cliente informa o erro, quando chamado sem a verificação prévia:
- C#: o
GetDocumentContentAsynclança umaSignerApiException. - Java: o
getDocumentContentlança umaRestUnreachableExceptionpara qualquer erro HTTP, sem o código de status nem o código de erro; por isso, consulte o documento antes. Os demais métodos lançam umaRestErrorException, cujosgetStatusCode(),getErrorCode()egetErrorMessage()trazem o status e ocodee amessagedoErrorModel. - Node.js: a promise é rejeitada com o erro do axios;
error.response.statustraz o status eerror.response.data, oErrorModel(comresponseType: "arraybuffer", em bytes). - PHP: o
getDocumentContentnão lança exceção, como explica o aviso abaixo.
No cliente PHP, getDocumentContent não lança exceção em erros HTTP: ele devolve o corpo da resposta de erro, o JSON do ErrorModel, como se fosse o arquivo. Salvo sem verificação, esse conteúdo vira um "arquivo" que contém o erro. Consulte o documento antes, como descrito acima.
Exemplos no GitHub: C# · Java · PHP · Node.js
Listar documentos
É possível listar os documentos de acordo com diferentes padrões e necessidades. Os parâmetros disponíveis estão descritos na API de Listagem de Documentos. Entre os tipos de listagem possíveis:
- Documentos pendentes para um determinado participante
- Documentos concluídos
- Listar por pastas
- Listar por organização
Filtrar por status
O parâmetro status filtra pelo status do documento: Pending, Paused, Concluded, Refused, Canceled, Expired, PendingOrRefused ou CanceledOrExpired. O valor Pending também traz os documentos pausados. Para listar só os pausados, use Paused.
Filtrar por participante
Para listar os documentos de um participante, envie dois parâmetros juntos:
| Parâmetro | Descrição |
|---|---|
participantQ | O texto a pesquisar, por exemplo o CPF ou o e-mail do participante. |
participantQueryType | Onde pesquisar o texto: Name, Identifier, Email ou Phone. |
Sem os dois parâmetros, o Signer não filtra por participante. Disponível a partir da versão 3.0.0, o parâmetro participantSituation filtra pela situação da ação do participante:
| Valor | Documentos listados |
|---|---|
Pending | O participante ainda precisa agir, e o documento está em andamento ou pausado. |
Completed | O participante já agiu: assinou, aprovou ou recusou. |
Sem participantSituation, a listagem traz todas as situações.
GET /api/documents?participantQ=81976153069&participantQueryType=Identifier&participantSituation=Pending
Pastas
Para listar as pastas da organização da chave de API, use GET /api/folders. O parâmetro q pesquisa pelo nome, e parentId com filterByParent=true lista as subpastas de uma pasta. Para listar os documentos de uma pasta, use o parâmetro folderId em GET /api/documents.
A interface web usa GET /api/folders/search para pesquisar as pastas que o usuário acessa em todas as organizações. Essa rota não aceita chave de API.