Pular para o conteúdo

Guia de Integração

Este guia apresenta o passo a passo para enviar documentos para assinatura no XSigner a partir do seu sistema, acompanhar o andamento e obter o documento assinado.

  • Credenciais de usuário de serviço (e-mail, senha e código) fornecidas pela equipe Xjur
  • Subscription key (X-XJUR-SUBSCRIPTION-KEY)
  • Usuário de serviço habilitado para o XSigner pela equipe Xjur
  • Documentos em PDF ou Word (.pdf, .doc, .docx) com até 25 MB cada
  • Nome completo e e-mail de cada signatário
AmbienteURL Base
Produçãohttps://apim-xjur-prd.xjur.com.br/connect
Homologaçãohttp://apim-xjur-qa.xjur.com.br/connect
sequenceDiagram
  participant S as Seu sistema
  participant C as XJUR Connect
  participant X as Xjur (XSigner)
  participant A as Signatário

  opt Upload prévio (multipart)
      S->>C: POST /xsigner/documentos (arquivo)
      C->>X: armazena o documento
      C-->>S: 201 { documentoId }
  end
  S->>C: POST /xsigner/envelopes (documentos + signatários)
  C->>X: armazena os documentos em base64 (se houver)
  C->>X: resolve papéis por nome
  C->>X: cria envelope (plataforma xsigner)
  X-->>A: e-mail com link de assinatura
  X-->>C: envelope criado
  C-->>S: 201 EnvelopeResponse (envelopeId, links)

  loop até status = Assinado ou Cancelado
      S->>C: GET /xsigner/envelopes/{envelopeId}
      C-->>S: status do envelope e de cada signatário
  end

  A->>X: assina pelo link
  S->>C: GET /xsigner/envelopes/{envelopeId}/documento-assinado
  C-->>S: PDF final (application/pdf)

Chame POST /Autenticacao/AuthenticateUserService com as credenciais do usuário de serviço e guarde o campo token. Veja Obtendo o Token JWT.

Cada signatário precisa de um papel (Contratante, Contratada, Testemunha, Representante legal…). Os papéis são cadastrados por cliente no Xjur.

GET /xsigner/papeis-signatario HTTP/1.1
Host: apim-xjur-qa.xjur.com.br/connect
Authorization: Bearer <token>
X-XJUR-SUBSCRIPTION-KEY: <sua-chave>
[
{ "papelSignatarioId": 5, "nome": "Contratante", "ativo": true },
{ "papelSignatarioId": 6, "nome": "Testemunha", "codigo": "TEST", "ativo": true }
]

No payload do envelope você pode informar papelSignatarioId (mais rápido) ou papel com o nome exato (o XJUR Connect resolve o id).

Há duas formas de entregar os arquivos, e elas podem ser combinadas no mesmo envelope:

FormaComoQuando usar
Upload dedicadoPOST /xsigner/documentos (multipart/form-data) devolve um documentoIdArquivos grandes, reutilização do mesmo documento em mais de um envelope, ou quando o seu sistema já trabalha com upload de arquivos
Inline no envelopeCampo conteudoBase64 em documentos[] do POST /xsigner/envelopesUma única chamada resolve tudo; ideal para arquivos pequenos

Upload dedicado:

POST /xsigner/documentos HTTP/1.1
Host: apim-xjur-qa.xjur.com.br/connect
Authorization: Bearer <token>
X-XJUR-SUBSCRIPTION-KEY: <sua-chave>
Content-Type: multipart/form-data; boundary=----limite
------limite
Content-Disposition: form-data; name="arquivo"; filename="contrato.pdf"
Content-Type: application/pdf
<bytes do arquivo>
------limite
Content-Disposition: form-data; name="descricao"
Contrato principal
------limite--
{ "documentoId": 98765, "nomeArquivo": "contrato.pdf", "descricao": "Contrato principal", "tamanho": 184320 }

Com cURL:

Terminal window
curl -X POST https://apim-xjur-qa.xjur.com.br/connect/xsigner/documentos \
-H "Authorization: Bearer $TOKEN" \
-H "X-XJUR-SUBSCRIPTION-KEY: $SUBSCRIPTION_KEY" \
-F "arquivo=@contrato.pdf" \
-F "descricao=Contrato principal"

Extensões aceitas: .pdf, .doc, .docx, até 25 MB por arquivo.

CampoTipoObrigatórioDescrição
assuntostringSimAssunto do e-mail enviado aos signatários (até 100 caracteres)
mensagemstringNãoTexto do e-mail (até 1000 caracteres)
codigostringNãoCódigo livre do integrador; útil para localizar o envelope depois (GET /xsigner/envelopes?codigo=)
enviarPorOrdembooleanNãotrue envia o link ao próximo signatário só depois que o anterior assinar
departamentoIdintegerNãoDepartamento responsável; usa o padrão do cliente quando omitido
documentosarraySimAo menos um documento
signatariosarraySimAo menos um signatário

Cada item aceita uma das formas:

FormaCampos
Documento já enviado (passo 3)documentoId
Arquivo inlinenomeArquivo + conteudoBase64 (+ descricao)
  • Extensões aceitas: .pdf, .doc, .docx.
  • conteudoBase64 aceita o prefixo data URI (data:application/pdf;base64,...).
  • A ordem dos documentos no array é a ordem em que aparecem no PDF final.
  • ordensSignatariosPermitidos (opcional) restringe quais signatários veem aquele documento, referenciando o campo ordem dos signatários.
CampoTipoObrigatórioDescrição
nomestringSimNome completo (nome e sobrenome)
emailstringSimE-mail que receberá o link. Não pode se repetir dentro do envelope
papelSignatarioIdintegerUm dos doisId do papel (passo 2)
papelstringUm dos doisNome do papel (passo 2)
ordemintegerSe enviarPorOrdem = truePosição na sequência de assinatura (1, 2, 3…). Quando omitida, usa a posição no array
celularstringNãoCelular com DDD (informativo; o link é sempre enviado por e-mail)
codigostringNãoCódigo livre do integrador
POST /xsigner/envelopes HTTP/1.1
Host: apim-xjur-qa.xjur.com.br/connect
Authorization: Bearer <token>
X-XJUR-SUBSCRIPTION-KEY: <sua-chave>
Content-Type: application/json
{
"assunto": "Contrato de prestação de serviços para assinatura",
"mensagem": "Por favor, assine o contrato em anexo.",
"codigo": "PEDIDO-2026-000123",
"enviarPorOrdem": true,
"documentos": [
{ "documentoId": 98765 },
{ "nomeArquivo": "anexo-a.pdf", "conteudoBase64": "JVBERi0xLjQK...", "ordensSignatariosPermitidos": [1] }
],
"signatarios": [
{ "nome": "Maria Silva", "email": "maria.silva@email.com", "papel": "Contratante", "ordem": 1 },
{ "nome": "João Souza", "email": "joao.souza@email.com", "papelSignatarioId": 6, "ordem": 2 }
]
}

A resposta 201 traz o envelope completo. Guarde o envelopeId e, se precisar, o signatarioId de cada signatário: todas as demais operações usam esses ids.

O XSigner não envia webhooks para sistemas externos. Consulte o envelope periodicamente (por exemplo, a cada 15 minutos) até que status seja Assinado ou Cancelado:

GET /xsigner/envelopes/1532 HTTP/1.1

Em cada signatário, status indica PendenteAssinatura, Assinado, Recusado ou Excluido, e dataAssinatura, documentoIdentificacao e ip são preenchidos após a assinatura. Quando um signatário recusa o documento, o envelope fica Cancelado e motivoCancelamento informa quem recusou e por quê.

Para localizar envelopes em lote, use a listagem com filtros:

GET /xsigner/envelopes?status=AguardandoSignatarios&codigo=PEDIDO-2026&limit=50 HTTP/1.1
AçãoRequisição
Adicionar signatárioPOST /xsigner/envelopes/{envelopeId}/signatarios com o mesmo formato de signatário do passo 4
Corrigir e-mail, nome ou celularPATCH /xsigner/envelopes/{envelopeId}/signatarios/{signatarioId} com { "email": "novo@email.com" }
Remover signatárioDELETE /xsigner/envelopes/{envelopeId}/signatarios/{signatarioId}
Reenviar o e-mail com o linkPOST /xsigner/envelopes/{envelopeId}/signatarios/{signatarioId}/reenviar-link
Obter o link para enviar por outro canalGET /xsigner/envelopes/{envelopeId}/signatarios/{signatarioId}/link

Só é possível alterar, remover ou reenviar o link de signatários com status PendenteAssinatura. Se o signatário removido era o último pendente, o envelope é concluído automaticamente.

Quando status for Assinado:

GET /xsigner/envelopes/1532/documento-assinado HTTP/1.1

A resposta é o PDF final (application/pdf, Content-Disposition: attachment) contendo os documentos e a página de assinaturas. Alternativamente, o campo documentoAssinado.url do envelope traz uma URL temporária para download direto.

POST /xsigner/envelopes/1532/cancelar HTTP/1.1

Envelopes já assinados não podem ser cancelados.

public async Task<int> EnviarParaAssinatura(string token, string codigoPedido, byte[] pdf)
{
var client = new HttpClient { BaseAddress = new Uri("https://apim-xjur-prd.xjur.com.br/connect/") };
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
client.DefaultRequestHeaders.Add("X-XJUR-SUBSCRIPTION-KEY", subscriptionKey);
var payload = new
{
assunto = $"Contrato {codigoPedido} para assinatura",
codigo = codigoPedido,
documentos = new[] { new { nomeArquivo = "contrato.pdf", conteudoBase64 = Convert.ToBase64String(pdf) } },
signatarios = new[]
{
new { nome = "Maria Silva", email = "maria.silva@email.com", papel = "Contratante" }
}
};
var response = await client.PostAsJsonAsync("xsigner/envelopes", payload);
response.EnsureSuccessStatusCode();
var envelope = await response.Content.ReadFromJsonAsync<JsonElement>();
return envelope.GetProperty("envelopeId").GetInt32();
}
public async Task<string?> ConsultarStatus(HttpClient client, int envelopeId)
{
var envelope = await client.GetFromJsonAsync<JsonElement>($"xsigner/envelopes/{envelopeId}");
return envelope.GetProperty("status").GetString(); // AguardandoSignatarios | Assinado | Cancelado
}
import base64
import requests
BASE = "https://apim-xjur-prd.xjur.com.br/connect"
HEADERS = {
"Authorization": f"Bearer {token}",
"X-XJUR-SUBSCRIPTION-KEY": subscription_key,
}
def criar_envelope(codigo_pedido: str, caminho_pdf: str) -> dict:
with open(caminho_pdf, "rb") as f:
conteudo = base64.b64encode(f.read()).decode()
payload = {
"assunto": f"Contrato {codigo_pedido} para assinatura",
"codigo": codigo_pedido,
"documentos": [{"nomeArquivo": "contrato.pdf", "conteudoBase64": conteudo}],
"signatarios": [
{"nome": "Maria Silva", "email": "maria.silva@email.com", "papel": "Contratante"},
],
}
r = requests.post(f"{BASE}/xsigner/envelopes", json=payload, headers=HEADERS)
r.raise_for_status()
return r.json()
def baixar_assinado(envelope_id: int, destino: str) -> None:
r = requests.get(f"{BASE}/xsigner/envelopes/{envelope_id}/documento-assinado", headers=HEADERS)
r.raise_for_status()
with open(destino, "wb") as f:
f.write(r.content)
  • Use codigo com o identificador do seu sistema: é a única forma de relacionar o envelope ao seu registro e facilita a conciliação em GET /xsigner/envelopes?codigo=.
  • Consulte o status em intervalos razoáveis; assinaturas dependem de ação humana e podem levar dias.
  • Envie os documentos já na versão final: depois de criado, o envelope não aceita troca de documentos.
  • Guarde envelopeId e signatarioId; o hashEnvelope é devolvido apenas para rastreabilidade.