Signature Requests
Gerenciamento de requisições de assinatura eletrônica.
Endpoints
| Método | Endpoint | Descrição | Permissão |
|---|---|---|---|
| POST | /api/v1/esignature/requests | Criar requisição | ESIGNATURE_CREATE |
| POST | /api/v1/esignature/requests/from-template | Criar de template | ESIGNATURE_CREATE |
| GET | /api/v1/esignature/requests | Listar requisições | ESIGNATURE_READ |
| GET | /api/v1/esignature/requests/:id | Obter requisição | ESIGNATURE_READ |
| POST | /api/v1/esignature/requests/:id/cancel | Cancelar requisição | ESIGNATURE_CREATE |
| POST | /api/v1/esignature/requests/:id/resend | Reenviar requisição | ESIGNATURE_CREATE |
| GET | /api/v1/esignature/requests/:id/download | Download documento assinado | ESIGNATURE_READ |
| DELETE | /api/v1/esignature/requests/:id | Excluir requisição | ESIGNATURE_DELETE |
Atributos da Requisição
| Campo | Tipo | Descrição |
|---|---|---|
title | string | Título da requisição |
message | string | Mensagem para os signatários |
status | enum | Status: DRAFT, SENT, VIEWED, PARTIALLY_SIGNED, COMPLETED, DECLINED, EXPIRED, CANCELLED |
businessId | string | ID de referência do negócio (ex: ID do contrato) |
templateId | string | ID do template usado (se aplicável) |
templateName | string | Nome do template usado |
viewUrl | string | URL para visualização da requisição |
expiresAt | datetime | Data de expiração |
completedAt | datetime | Data de conclusão |
createdAt | datetime | Data de criação |
updatedAt | datetime | Data da última atualização |
createdBy | string | ID do usuário que criou |
Atributos do Signatário
| Campo | Tipo | Descrição |
|---|---|---|
name | string | Nome do signatário |
email | string | E-mail do signatário |
order | number | Ordem de assinatura (1, 2, 3...) |
status | enum | Status: PENDING, SENT, VIEWED, SIGNED, DECLINED |
signingUrl | string | URL para o signatário assinar |
sentAt | datetime | Data do envio do e-mail |
viewedAt | datetime | Data da visualização |
signedAt | datetime | Data da assinatura |
declinedAt | datetime | Data da recusa |
declineReason | string | Motivo da recusa |
Widgets
Widgets são elementos posicionados no documento para coleta de informações.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
type | enum | Sim | signature, text, date, checkbox |
signerId | string | Não | ID/referência do signatário |
page | number | Sim | Número da página (começando em 1) |
x | number | Sim | Posição X em pontos |
y | number | Sim | Posição Y em pontos |
width | number | Não | Largura em pontos |
height | number | Não | Altura em pontos |
required | boolean | Não | Se é obrigatório |
label | string | Não | Rótulo do campo |
Tipos de Widget
| Tipo | Descrição | Uso comum |
|---|---|---|
signature | Campo de assinatura | Assinatura digital do signatário |
text | Campo de texto | Nome completo, cargo, etc. |
date | Campo de data | Data da assinatura |
checkbox | Caixa de seleção | Aceite de termos |
Criar Requisição
POST /api/v1/esignature/requests
Cria uma nova requisição de assinatura.
Atributos
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
title | string | Sim | Título da requisição (max 255) |
message | string | Não | Mensagem para signatários (max 2000) |
configId | uuid | Não | ID da configuração do provedor (usa default se omitido) |
businessId | string | Não | ID de referência do negócio (max 100) |
expiresInDays | number | Não | Dias até expirar (1-365) |
fileId | uuid | Condicional | ID do arquivo no File Storage |
fileBase64 | string | Condicional | Arquivo em base64 |
fileName | string | Condicional | Nome do arquivo (obrigatório com fileBase64) |
signers | array | Sim | Lista de signatários (mín. 1) |
widgets | array | Não | Posicionamento de campos |
Você deve fornecer um dos seguintes: fileId (referência ao File Storage) ou fileBase64 + fileName (documento embutido).
Estrutura do Signatário
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim | Nome do signatário (max 255) |
email | string | Sim | E-mail válido (max 255) |
order | number | Não | Ordem de assinatura (default: 1) |
- cURL
- JavaScript
- JavaScript (com File Storage)
curl -X POST 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests' \
-H 'Authorization: Bearer SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"data": {
"type": "signature-request",
"attributes": {
"title": "Contrato de Prestação de Serviços",
"message": "Por favor, assine o contrato anexo.",
"businessId": "contract-2024-001",
"expiresInDays": 7,
"fileBase64": "JVBERi0xLjQK...",
"fileName": "contrato.pdf",
"signers": [
{ "name": "João Silva", "email": "joao@empresa.com", "order": 1 },
{ "name": "Maria Santos", "email": "maria@cliente.com", "order": 2 }
],
"widgets": [
{ "type": "signature", "page": 1, "x": 100, "y": 200, "width": 200, "height": 50 },
{ "type": "signature", "page": 1, "x": 400, "y": 200, "width": 200, "height": 50 },
{ "type": "date", "page": 1, "x": 100, "y": 150, "label": "Data" }
]
}
}
}'
// Converter arquivo para base64
const fileBuffer = await fs.promises.readFile('./contrato.pdf');
const fileBase64 = fileBuffer.toString('base64');
const response = await fetch('https://e-signature.stg.catalisa.app/api/v1/esignature/requests', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
type: 'signature-request',
attributes: {
title: 'Contrato de Prestação de Serviços',
message: 'Por favor, assine o contrato anexo.',
businessId: 'contract-2024-001',
expiresInDays: 7,
fileBase64,
fileName: 'contrato.pdf',
signers: [
{ name: 'João Silva', email: 'joao@empresa.com', order: 1 },
{ name: 'Maria Santos', email: 'maria@cliente.com', order: 2 },
],
widgets: [
{ type: 'signature', page: 1, x: 100, y: 200, width: 200, height: 50 },
{ type: 'signature', page: 1, x: 400, y: 200, width: 200, height: 50 },
{ type: 'date', page: 1, x: 100, y: 150, label: 'Data' },
],
},
},
}),
});
const { data } = await response.json();
console.log(`Requisição criada: ${data.id}`);
console.log(`Status: ${data.attributes.status}`);
console.log(`URL de visualização: ${data.attributes.viewUrl}`);
// Listar signatários
data.relationships.signers.data.forEach(signer => {
console.log(`${signer.attributes.name}: ${signer.attributes.signingUrl}`);
});
// Usando referência ao File Storage
const response = await fetch('https://e-signature.stg.catalisa.app/api/v1/esignature/requests', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
type: 'signature-request',
attributes: {
title: 'Contrato de Prestação de Serviços',
businessId: 'contract-2024-001',
fileId: '550e8400-e29b-41d4-a716-446655440010', // ID do File Storage
signers: [
{ name: 'João Silva', email: 'joao@empresa.com' },
],
},
},
}),
});
const { data } = await response.json();
console.log(`Requisição criada: ${data.id}`);
Resposta
{
"data": {
"type": "signature-request",
"id": "550e8400-e29b-41d4-a716-446655440000",
"links": {
"self": "/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000"
},
"attributes": {
"title": "Contrato de Prestação de Serviços",
"message": "Por favor, assine o contrato anexo.",
"status": "SENT",
"businessId": "contract-2024-001",
"viewUrl": "https://opensign.example.com/view/abc123",
"expiresAt": "2024-01-22T10:30:00Z",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z",
"createdBy": "550e8400-e29b-41d4-a716-446655440001"
},
"relationships": {
"signers": {
"data": [
{
"type": "signer",
"id": "550e8400-e29b-41d4-a716-446655440002",
"attributes": {
"name": "João Silva",
"email": "joao@empresa.com",
"order": 1,
"status": "SENT",
"signingUrl": "https://opensign.example.com/sign/xyz789",
"sentAt": "2024-01-15T10:30:05Z"
}
},
{
"type": "signer",
"id": "550e8400-e29b-41d4-a716-446655440003",
"attributes": {
"name": "Maria Santos",
"email": "maria@cliente.com",
"order": 2,
"status": "PENDING"
}
}
]
}
}
},
"links": {
"self": "/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000"
}
}
Criar de Template
POST /api/v1/esignature/requests/from-template
Cria uma requisição de assinatura a partir de um template do provedor.
Atributos
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
templateId | string | Sim | ID do template no provedor |
title | string | Sim | Título da requisição (max 255) |
message | string | Não | Mensagem para signatários (max 2000) |
configId | uuid | Não | ID da configuração do provedor |
businessId | string | Não | ID de referência do negócio |
expiresInDays | number | Não | Dias até expirar (1-365) |
signers | array | Sim | Lista de signatários |
fieldValues | object | Não | Valores para campos do template |
- cURL
- JavaScript
curl -X POST 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests/from-template' \
-H 'Authorization: Bearer SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"data": {
"type": "signature-request",
"attributes": {
"templateId": "tpl_abc123",
"title": "Contrato de Trabalho - João Silva",
"message": "Segue o contrato para assinatura.",
"businessId": "employee-2024-001",
"expiresInDays": 5,
"signers": [
{ "name": "João Silva", "email": "joao@empresa.com", "order": 1 },
{ "name": "RH Empresa", "email": "rh@empresa.com", "order": 2 }
],
"fieldValues": {
"nome_funcionario": "João Silva",
"cpf": "123.456.789-00",
"cargo": "Desenvolvedor Senior",
"salario": "R$ 15.000,00",
"data_inicio": "01/02/2024"
}
}
}
}'
const response = await fetch('https://e-signature.stg.catalisa.app/api/v1/esignature/requests/from-template', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
type: 'signature-request',
attributes: {
templateId: 'tpl_abc123',
title: 'Contrato de Trabalho - João Silva',
message: 'Segue o contrato para assinatura.',
businessId: 'employee-2024-001',
expiresInDays: 5,
signers: [
{ name: 'João Silva', email: 'joao@empresa.com', order: 1 },
{ name: 'RH Empresa', email: 'rh@empresa.com', order: 2 },
],
fieldValues: {
nome_funcionario: 'João Silva',
cpf: '123.456.789-00',
cargo: 'Desenvolvedor Senior',
salario: 'R$ 15.000,00',
data_inicio: '01/02/2024',
},
},
},
}),
});
const { data } = await response.json();
console.log(`Requisição criada do template: ${data.id}`);
console.log(`Template usado: ${data.attributes.templateName}`);
Listar Requisições
GET /api/v1/esignature/requests
Lista as requisições de assinatura da organização com suporte a paginação e filtros.
Parâmetros de Query
| Parâmetro | Tipo | Descrição |
|---|---|---|
page[number] | number | Número da página (default: 1) |
page[size] | number | Itens por página (default: 20, max: 100) |
filter[status] | enum | Filtrar por status |
filter[businessId] | string | Filtrar por ID de negócio |
- cURL
- JavaScript
# Listar todas
curl -X GET 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests' \
-H 'Authorization: Bearer SEU_TOKEN'
# Com filtros
curl -X GET 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests?filter[status]=SENT&page[size]=10' \
-H 'Authorization: Bearer SEU_TOKEN'
# Filtrar por businessId
curl -X GET 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests?filter[businessId]=contract-2024-001' \
-H 'Authorization: Bearer SEU_TOKEN'
// Listar todas as requisições pendentes
const params = new URLSearchParams({
'filter[status]': 'SENT',
'page[size]': '10',
});
const response = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests?${params}`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
const { data, meta, links } = await response.json();
console.log(`Total: ${meta.totalItems} requisições`);
console.log(`Página ${meta.currentPage} de ${meta.totalPages}`);
data.forEach(request => {
console.log(`${request.attributes.title}: ${request.attributes.status}`);
});
// Navegar para próxima página
if (links.next) {
const nextPage = await fetch(links.next, { headers: { 'Authorization': `Bearer ${token}` }});
// ...
}
Resposta
{
"data": [
{
"type": "signature-request",
"id": "550e8400-e29b-41d4-a716-446655440000",
"links": {
"self": "/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000"
},
"attributes": {
"title": "Contrato de Prestação de Serviços",
"status": "SENT",
"businessId": "contract-2024-001",
"expiresAt": "2024-01-22T10:30:00Z",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
}
],
"meta": {
"totalItems": 45,
"totalPages": 5,
"currentPage": 1,
"pageSize": 10
},
"links": {
"self": "/api/v1/esignature/requests?page[number]=1&page[size]=10",
"first": "/api/v1/esignature/requests?page[number]=1&page[size]=10",
"last": "/api/v1/esignature/requests?page[number]=5&page[size]=10",
"next": "/api/v1/esignature/requests?page[number]=2&page[size]=10"
}
}
Obter Requisição
GET /api/v1/esignature/requests/:id
Obtém uma requisição específica com seus signatários.
- cURL
- JavaScript
curl -X GET 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000' \
-H 'Authorization: Bearer SEU_TOKEN'
const requestId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${requestId}`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
const { data } = await response.json();
console.log(`Título: ${data.attributes.title}`);
console.log(`Status: ${data.attributes.status}`);
console.log(`Expira em: ${data.attributes.expiresAt}`);
// Verificar status dos signatários
data.relationships.signers.data.forEach(signer => {
const { name, email, status, signedAt } = signer.attributes;
console.log(`${name} (${email}): ${status}`);
if (signedAt) {
console.log(` Assinado em: ${signedAt}`);
}
});
Cancelar Requisição
POST /api/v1/esignature/requests/:id/cancel
Cancela uma requisição de assinatura pendente.
Apenas requisições com status DRAFT, SENT, VIEWED ou PARTIALLY_SIGNED podem ser canceladas.
- cURL
- JavaScript
curl -X POST 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000/cancel' \
-H 'Authorization: Bearer SEU_TOKEN'
const requestId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${requestId}/cancel`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
},
});
const { data } = await response.json();
console.log(`Status: ${data.attributes.status}`); // CANCELLED
Resposta
{
"data": {
"type": "signature-request",
"id": "550e8400-e29b-41d4-a716-446655440000",
"attributes": {
"title": "Contrato de Prestação de Serviços",
"status": "CANCELLED",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T14:00:00Z"
}
}
}
Reenviar Requisição
POST /api/v1/esignature/requests/:id/resend
Reenvia os e-mails de assinatura para signatários pendentes.
Atributos
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
signerEmail | string | Não | E-mail específico para reenvio (se omitido, reenvia para todos pendentes) |
- cURL
- JavaScript
# Reenviar para todos os signatários pendentes
curl -X POST 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000/resend' \
-H 'Authorization: Bearer SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{}'
# Reenviar para um signatário específico
curl -X POST 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000/resend' \
-H 'Authorization: Bearer SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"data": {
"attributes": {
"signerEmail": "maria@cliente.com"
}
}
}'
const requestId = '550e8400-e29b-41d4-a716-446655440000';
// Reenviar para todos
const response = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${requestId}/resend`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({}),
});
const result = await response.json();
console.log(result.message); // "Signature request resent successfully"
// Reenviar para um signatário específico
const responseSpecific = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${requestId}/resend`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
attributes: {
signerEmail: 'maria@cliente.com',
},
},
}),
});
Resposta
{
"message": "Signature request resent successfully"
}
Download Documento Assinado
GET /api/v1/esignature/requests/:id/download
Obtém a URL para download do documento assinado.
O documento só está disponível para download quando a requisição tem status COMPLETED.
- cURL
- JavaScript
curl -X GET 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000/download' \
-H 'Authorization: Bearer SEU_TOKEN'
const requestId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${requestId}/download`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
const { downloadUrl, expiresAt } = await response.json();
console.log(`URL de download: ${downloadUrl}`);
console.log(`Expira em: ${expiresAt}`);
// Baixar o arquivo
const fileResponse = await fetch(downloadUrl);
const fileBuffer = await fileResponse.arrayBuffer();
await fs.promises.writeFile('./contrato-assinado.pdf', Buffer.from(fileBuffer));
console.log('Documento salvo!');
Resposta
{
"downloadUrl": "https://storage.example.com/signed/abc123.pdf?signature=xyz",
"expiresAt": "2024-01-15T11:30:00Z"
}
A URL de download expira em 15 minutos. Solicite uma nova URL se necessário.
Excluir Requisição
DELETE /api/v1/esignature/requests/:id
Exclui uma requisição de assinatura.
A exclusão é permanente. Requisições com status COMPLETED ou DECLINED são mantidas para auditoria por padrão.
- cURL
- JavaScript
curl -X DELETE 'https://e-signature.stg.catalisa.app/api/v1/esignature/requests/550e8400-e29b-41d4-a716-446655440000' \
-H 'Authorization: Bearer SEU_TOKEN'
const requestId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${requestId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`,
},
});
if (response.status === 204) {
console.log('Requisição excluída com sucesso');
}
Resposta
Status 204 No Content em caso de sucesso.
Fluxo Completo de Integração
Exemplo de integração completa monitorando status de assinatura:
async function sendContractForSignature(contractData) {
// 1. Criar requisição
const createResponse = await fetch('https://e-signature.stg.catalisa.app/api/v1/esignature/requests', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
type: 'signature-request',
attributes: {
title: `Contrato - ${contractData.clientName}`,
businessId: contractData.contractId,
expiresInDays: 7,
fileBase64: contractData.pdfBase64,
fileName: `contrato-${contractData.contractId}.pdf`,
signers: contractData.signers,
},
},
}),
});
const { data: request } = await createResponse.json();
console.log(`Requisição criada: ${request.id}`);
return request;
}
async function checkSignatureStatus(requestId) {
const response = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${requestId}`, {
headers: { 'Authorization': `Bearer ${token}` },
});
const { data } = await response.json();
return data.attributes.status;
}
async function downloadSignedContract(requestId) {
const response = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${requestId}/download`, {
headers: { 'Authorization': `Bearer ${token}` },
});
const { downloadUrl } = await response.json();
const fileResponse = await fetch(downloadUrl);
return await fileResponse.arrayBuffer();
}
// Uso
const request = await sendContractForSignature({
clientName: 'Empresa ABC',
contractId: 'CTR-2024-001',
pdfBase64: '...',
signers: [
{ name: 'João Silva', email: 'joao@empresa.com', order: 1 },
{ name: 'Cliente ABC', email: 'contato@abc.com', order: 2 },
],
});
// Aguardar conclusão (ou usar webhooks)
const status = await checkSignatureStatus(request.id);
if (status === 'COMPLETED') {
const signedPdf = await downloadSignedContract(request.id);
// Salvar documento assinado
}
Boas Práticas
- Use businessId - Vincule requisições a entidades do seu sistema
- Configure webhooks - Receba notificações em tempo real
- Defina prazos - Use
expiresInDayspara evitar requisições pendentes indefinidamente - Posicione widgets - Melhora UX dos signatários
- Use templates - Para documentos recorrentes com campos fixos
- Armazene URLs - As URLs de assinatura podem ser compartilhadas diretamente