SignXP Docs

Enviar um documento

POST /api/v1/documents

Cria o documento, posiciona os campos de assinatura nas coordenadas informadas e convida o primeiro signatário. Responde 202 Accepted — o processamento do PDF é assíncrono.

Corpo da requisição

{
  "external_id": "contrato-2026-0001",
  "source_system": "meu-erp",
  "title": "Contrato de Prestação de Serviços",
  "callback_url": "https://meu-sistema.com.br/webhooks/signxp",
  "download_policy": "all_signed",
  "customer": { "reference": "cli-4471", "name": "Acme Indústria Ltda." },
  "evidence": { "document": true, "selfie": true },
  "pdf_base64": "JVBERi0xLjcK...",
  "signers": [
    {
      "key": "contratante",
      "name": "Maria Souza",
      "email": "maria@empresa.com.br",
      "tax_id": "529.982.247-25",
      "role": "SIGNER",
      "signing_order": 1
    },
    {
      "key": "contratada",
      "name": "João Lima",
      "email": "joao@fornecedor.com.br",
      "signing_order": 2
    }
  ],
  "fields": [
    { "signer_key": "contratante", "type": "SIGNATURE", "page": 3, "x": 12.5, "y": 78 },
    { "signer_key": "contratada",  "type": "SIGNATURE", "page": 3, "x": 55,   "y": 78 },
    { "signer_key": "contratante", "type": "INITIALS",  "page": 1, "x": 80,   "y": 90, "width": 14, "height": 7 }
  ]
}

Campos

Campo Tipo Obrigatório Descrição
title string sim Nome do documento, exibido ao signatário e no painel.
pdf_base64 string sim* PDF em base64. *Alternativamente envie pdf como upload multipart (máx. 20 MB).
signers array sim Ao menos um signatário.
fields array sim* Ao menos um campo, e todo signatário com papel SIGNER precisa de pelo menos um. *Não se aplica (e é recusado) quando placement é interactive ou signature_page.
external_id string não O identificador do documento no seu sistema. Deve ser único por licença.
source_system string não Nome do sistema de origem, útil quando você integra vários.
callback_url url não Recebe as notificações de mudança de status.
download_policy enum não all_signed (padrão), anytime ou disabled. Ignorado quando a sua conta desliga a entrega pelo SignXP — veja verificação.
delivery enum não Quem entrega o link ao signatário: email (padrão) ou none. Veja "Entregando o link você mesmo", abaixo.
customer objeto não O seu cliente, aquele para quem o documento foi emitido. Veja "Separando o acervo por cliente", abaixo.
evidence.document bool não Exigir foto da frente e do verso do documento de identidade.
evidence.selfie bool não Exigir selfie segurando o documento.
evidence.geo bool não Pedir a geolocalização do signatário no momento da assinatura.
placement enum não Onde a assinatura entra no PDF. inline (padrão) traz as coordenadas aqui; interactive cria o documento sem campos e devolve uma tela de posicionamento — veja posicionamento assistido; signature_page dispensa campos e coleta as assinaturas numa Página de Assinaturas anexada ao fim do documento.

Os três campos de evidence são de três estados: true exige, false dispensa e omitir deixa valer o que a sua licença já traz configurado. Mande-os apenas quando este documento precisar de algo diferente do padrão.

Signatários

Campo Descrição
key Identificador do signatário dentro deste documento. É o que liga o signatário aos campos.
name Nome do signatário, obrigatório. Vai para o Termo de Evidências.
email Opcional. Quando informado, é para lá que o convite vai. Sem ele, o SignXP não notifica essa pessoa — nem convite, nem conclusão, nem recusa — e a entrega do link fica por sua conta.
tax_id CPF ou CNPJ, opcional. Com ou sem máscara. É o que permite à validação por IA conferir se o documento de identidade fotografado pertence a quem você convidou. Enviar um número inválido recusa o envio com 422; se você não o tem, omita o campo — o próprio signatário informa na hora de assinar.
role SIGNER (padrão), APPROVER, VIEWER, CC ou ASSISTANT. Apenas SIGNER assina.
signing_order Ordem da assinatura. Signatários com o mesmo número assinam em paralelo; o número seguinte só é convidado quando o anterior conclui. Sem signing_order, todos são convidados de uma vez.

Separando o acervo por cliente

Se o seu software emite documentos para vários clientes seus, mande quem é o cliente de cada envio:

{
  "customer": {
    "reference": "cli-4471",
    "name": "Acme Indústria Ltda."
  }
}
Campo Descrição
customer.reference O identificador do cliente no seu sistema. É por ele que o acervo é agrupado e filtrado.
customer.name Nome do cliente na data do envio. Viaja junto para o histórico não mudar quando o cadastro mudar.

O objeto inteiro é opcional — a maioria das integrações não separa carteira. A reference não é conferida contra cadastro nenhum: quem manda o identificador é você, e basta usar sempre o mesmo valor para o mesmo cliente.

No portal, os documentos passam a ser filtráveis por cliente, e o licenciado pode manter uma carteira com esses mesmos identificadores.

Entregando o link você mesmo

Por padrão, quem convida o signatário somos nós: assim que o documento fica pronto, sai um e-mail com o link de assinatura. Isso atrapalha quando o canal do seu cliente é outro — WhatsApp, SMS, ou a própria tela do seu sistema. A pessoa recebe um e-mail que não vai abrir e o link "de verdade" chega por outro caminho.

Enviando delivery: "none", nenhum e-mail sai e a entrega passa a ser sua:

{
  "title": "Contrato de Prestação de Serviços",
  "delivery": "none",
  "pdf_base64": "JVBERi0xLjcK...",
  "signers": [
    { "key": "cliente", "name": "Marina Alves", "email": "marina@empresa.com.br" }
  ],
  "fields": [
    { "signer_key": "cliente", "type": "SIGNATURE", "page": 1, "x": 15, "y": 78 }
  ]
}

O link de cada signatário sai na consulta de status, no campo signing_url. Ele não vem na resposta do envio: o PDF ainda está sendo processado e os links só existem depois disso. Espere o documento sair de draft e pegue os links:

GET /api/v1/documents/128
{
  "id": 128,
  "status": "pending",
  "delivery": "none",
  "signers": [
    {
      "key": "cliente",
      "email": "marina@empresa.com.br",
      "status": "pending",
      "signing_url": "https://app.signxp.com.br/assinar/9f2c7a1b..."
    }
  ]
}

Alguns pontos que valem saber:

  • O email do signatário é opcional — veja a seção seguinte. Quando ele existe e o delivery é none, o endereço fica registrado no Termo de Evidências e recebe o aviso de conclusão, mas não o convite.
  • A ordem de assinatura continua valendo. Com signing_order, o link do segundo signatário só passa a existir quando o primeiro conclui; consulte o status de novo para pegá-lo.
  • O modo é gravado no documento e aparece como delivery na consulta de status.
  • delivery não tem relação com o ambiente: uma chave sk_test_ nunca envia e-mail, com ou sem ele.

O link de assinatura é a credencial. Quem o tem assina no lugar da pessoa. Entregue-o pelo mesmo canal em que você já identifica o seu cliente, e nunca em um lugar público.

Se em vez de entregar o link você quer que a pessoa assine dentro da sua tela, veja assinatura embutida.

Signatário sem e-mail

Nem todo cliente final tem e-mail. Como quem entrega o link é você, o campo é opcional — basta omiti-lo:

{
  "signers": [
    { "key": "cliente", "name": "Marina Alves" },
    { "key": "contratante", "name": "Acme Ltda.", "email": "contratos@acme.com.br" }
  ]
}

Um documento pode misturar os dois casos, como no exemplo: o contratante recebe o convite por e-mail normalmente, e o cliente recebe o link pelo seu canal.

O que muda para quem está sem e-mail:

  • Nenhum aviso nosso chega até ele — nem convite, nem conclusão, nem recusa.
  • O signing_url dele sai na consulta de status, como o dos demais. É o único caminho até essa pessoa, então guarde-o ou entregue-o na hora.
  • No Termo de Evidências, a linha de identificação vem sem o endereço. Mande o tax_id sempre que tiver: com o e-mail ausente, ele passa a ser o identificador forte da pessoa — e é o que permite à validação por IA conferir o documento fotografado.

Opcional não quer dizer "aceita qualquer coisa": um endereço malformado continua devolvendo 422. Falhar no envio é melhor do que descobrir semanas depois que o convite nunca saiu.

Posicionando os campos

Cada item de fields diz onde a assinatura será carimbada no PDF.

Campo Tipo Obrigatório Descrição
signer_key string sim Precisa corresponder a uma key da lista de signatários.
page inteiro sim Número da página, começando em 1.
x número sim Distância da borda esquerda, em % da largura da página (0 a 100).
y número sim Distância do topo, em % da altura da página (0 a 100).
width número não Largura do campo, em % da largura da página. Padrão: 20.
height número não Altura do campo, em % da altura da página. Padrão: 8.
type enum não SIGNATURE (padrão) ou INITIALS para rúbrica.
label string não Rótulo livre exibido no painel do SignXP. Não aparece no documento.

O sistema de coordenadas

A origem é o canto superior esquerdo da página, e os valores são percentuais — não milímetros nem pontos. Assim o mesmo campo funciona em A4, Carta ou paisagem, sem conversão.

  (0,0)                                   (100,0)
    +---------------------------------------+
    |                                       |
    |        x -------->                    |
    |        +---------------+   ^          |
    |   y    |   assinatura  |   | height   |
    |   |    +---------------+   v          |
    |   v    <---- width ---->              |
    |                                       |
    +---------------------------------------+
  (0,100)                                (100,100)

Um campo com x: 12.5, y: 78, width: 20, height: 8 começa a 12,5% da esquerda e a 78% do topo, ocupando 20% da largura e 8% da altura da página.

Use o Posicionador de campos. Você abre o PDF, arrasta o retângulo onde a assinatura deve ficar e copia o bloco fields pronto. O arquivo é lido pelo próprio navegador e não é enviado a lugar nenhum.

Quem escolhe o lugar é o usuário do seu sistema, e não o seu código? Então não envie fields: use o posicionamento assistido e o SignXP devolve uma tela pronta para ele clicar onde cada assinatura vai.

Regras de validação

  • x + width e y + height não podem passar de 100. Um campo que vaza da página é recusado com 422 no ato do envio.
  • A page precisa existir no PDF. Como o total de páginas só é conhecido ao abrir o arquivo, essa conferência acontece no processamento: se a página não existir, o documento fica failed e ninguém é convidado, com o motivo no campo error da consulta de status.
  • O PDF precisa ser legível pelo nosso motor de selagem. Arquivos corrompidos ou protegidos por senha também resultam em failed — é melhor falhar no envio do que entregar ao signatário um contrato que não poderá ser selado no final.

Assinando sem posicionar campos

Nem todo documento tem lugar marcado para assinar — e nem todo integrador quer calcular coordenadas. Enviando placement: "signature_page", o campo fields deixa de ser exigido (e passa a ser recusado, para você não achar que mandou coordenadas que serão ignoradas):

{
  "title": "Contrato de Prestação de Serviços",
  "placement": "signature_page",
  "pdf_base64": "JVBERi0xLjQK...",
  "signers": [
    { "key": "cliente", "name": "Marina Alves", "email": "marina@empresa.com.br" }
  ]
}

As páginas do seu PDF chegam intactas ao signatário. Na cópia certificada, o SignXP anexa ao fim do contrato uma Página de Assinaturas com a assinatura desenhada de cada pessoa, nome, e-mail, data, hora e IP — e só depois dela vem o Termo de Evidências.

O que não muda: o signatário continua desenhando a assinatura e passando pelas mesmas evidências que a sua licença exige. O documento também não passa por posicionamento — ele já nasce pronto e os convites saem assim que o preparo termina, sem placement_url na resposta.

Resposta

{
  "id": 128,
  "status": "draft",
  "status_url": "https://api.signxp.com.br/api/v1/documents/128"
}

Guarde o id: ele identifica o documento nas consultas e nos callbacks.

Idempotência

Um POST que sofre timeout pode ter sido processado. Para não criar o documento duas vezes, envie um cabeçalho Idempotency-Key com um valor único por operação:

Idempotency-Key: contrato-2026-0001-envio-1
  • Mesma chave + mesmo conteúdo → devolvemos 200 com o documento original, sem criar outro.
  • Mesma chave + conteúdo diferente → 409.
  • Sem Idempotency-Key, um external_id repetido também devolve 409, com o id do documento já existente.

Testar agora

Execute a chamada de verdade contra o ambiente de teste, com dados fictícios já preenchidos.

Envia um contrato de exemplo com dois signatários fictícios. No ambiente de teste nenhum e-mail é disparado: o link de assinatura vem na consulta de status.

Só chaves de teste (sk_test_) são aceitas aqui: elas não enviam e-mail ao signatário nem consomem a sua quota. A chave fica apenas nesta aba do navegador.

Esta não parece uma chave de teste. Emita uma em Chaves de API.

O pdf_base64 já vem preenchido com um contrato de exemplo de uma página.