SignXP Docs

Canais

Esta página é para quem embute o SignXP dentro do próprio produto e o oferece aos clientes dele — um ERP, um CRM, um SaaS vertical. É diferente da integração comum: lá existe uma conta e uma chave; aqui existem dezenas ou centenas, uma por cliente seu, e nenhuma delas passa por uma tela nossa.

Acesso por contrato. A API de canal não é auto-serviço: o segredo é emitido junto do contrato. Se você chegou aqui pela integração comum, a página que você procura é Autenticação.

O modelo

Cada cliente seu vira uma conta completa no SignXP — com licença, quota, marca, chaves e acervo próprios.

Poderia ser diferente: uma conta só para você, com um identificador de cliente em cada documento. Não é, e a razão é prática. Quota, marca do e-mail, domínio de assinatura, segredo de callback e separação do acervo são todos por conta. Numa conta coletiva, seus clientes disputariam a mesma quota, receberiam e-mails com a marca errada, e um veria o contrato do outro no acervo.

Você continua sendo o dono da relação: provisiona, suspende, reativa e acompanha o consumo de todos por esta API. O que muda é que cada cliente tem o próprio compartimento.

Base e autenticação

POST /api/partner/v1/tenants HTTP/1.1
Host: admin.signxp.com.br
Authorization: Bearer pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

O segredo pk_ identifica o canal e vale para todas as rotas desta página. Ele não é uma chave de API de assinatura: não envia documento nenhum. As chaves sk_live_/sk_test_ que assinam documentos são de cada conta, e saem no provisionamento.

Um segredo de canal desativado responde 403 — o segredo está certo, o contrato é que acabou.

Provisionar uma conta

POST /api/partner/v1/tenants
{
  "external_ref": "tenant-4711",
  "name": "Solar Prime Engenharia",
  "person_type": "company",
  "document": "19.131.243/0001-97",
  "legal_name": "Solar Prime Engenharia Ltda",
  "zip_code": "01310-100",
  "street": "Avenida Paulista",
  "street_number": "1578",
  "city": "São Paulo",
  "state": "SP",
  "technical_contact_name": "Marina Alves",
  "technical_contact_email": "marina@solarprime.com.br",
  "plan": "canal-basico",
  "embed_origins": ["https://app.solarprime.com.br"]
}

O external_ref é o id do cliente no seu sistema, e é o que torna a chamada idempotente: repetir com o mesmo valor devolve a conta que já existe em vez de criar uma segunda. Mande sempre o mesmo valor — um timeout de rede não pode virar cadastro duplicado.

O plan é opcional; sem ele vale o plano do seu contrato de canal. Sem nenhum dos dois a conta nasce sem plano e não assina nada — útil se você quer criar o cadastro antes de vender o módulo.

O cadastro da empresa é obrigatório aqui (ao contrário do que acontece quando a equipe SignXP licencia pela tela). Por API não existe um "depois" em que alguém volta para completar a ficha, e uma empresa sem CNPJ não tem como ser identificada nem faturada no dia em que ela mesma contratar um plano.

A resposta

{
  "reference": "solar-prime-engenharia",
  "external_ref": "tenant-4711",
  "name": "Solar Prime Engenharia",
  "status": "active",
  "billing_mode": "partner",
  "plan": "canal-basico",
  "monthly_document_quota": 25,
  "keys": {
    "live": "sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "test": "sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
  "callback_secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Guarde as chaves. Elas existem em claro uma única vez, nesta resposta. Repetir a chamada devolve 200 com os mesmos dados e sem o bloco keys — um retry de rede não pode trocar as credenciais de uma conta que já está integrada e funcionando. Quem perdeu o valor emite outra em Chaves.

O reference é o identificador da conta no SignXP. Ele volta nos callbacks e é o caminho de todas as rotas seguintes — guarde-o ao lado do seu external_ref.

Códigos de resposta

Código Significado
201 Conta criada. É a única resposta que traz as chaves.
200 Já existia com esse external_ref. Idempotente, sem chaves.
409 O CNPJ já pertence a outra conta do SignXP.
422 Cadastro incompleto ou inválido.
503 Não foi possível concluir — repita a chamada.

O 409 merece atenção: ele significa que a empresa já é cliente do SignXP, por conta própria ou por outro canal. A resposta traz o reference dela e um same_partner dizendo se é sua. Criar de novo daria à mesma empresa duas licenças, duas quotas e dois pagadores — então a saída é vincular a conta que já existe, falando com o cliente.

{
  "message": "Esta empresa já tem uma conta no SignXP.",
  "reference": "solar-prime-engenharia",
  "name": "Solar Prime Engenharia",
  "same_partner": false
}

O 503 vem com "retryable": true e significa que nada foi criado — a resposta é binária de propósito: ou existe uma conta pronta com credenciais na mão, ou não existe nada e repetir recomeça limpo. Nunca entregamos uma chave antes de a conta estar operante do outro lado, porque uma chave que responde 401 nos primeiros minutos derruba justamente o "ativar com um clique".

Operar uma conta

Todas as rotas abaixo usam o reference devolvido no provisionamento. Conta de outro canal responde 404 — você nunca enxerga o que não é seu.

GET    /api/partner/v1/tenants
GET    /api/partner/v1/tenants/{reference}
PATCH  /api/partner/v1/tenants/{reference}
POST   /api/partner/v1/tenants/{reference}/suspend
POST   /api/partner/v1/tenants/{reference}/resume
GET    /api/partner/v1/tenants/{reference}/usage
POST   /api/partner/v1/tenants/{reference}/keys
POST   /api/partner/v1/tenants/{reference}/portal-link

O PATCH aceita name, technical_contact_name, technical_contact_email, embed_origins e plan. O cadastro fiscal (documento, razão social, endereço) fica de fora: é a identidade da empresa, e quem a corrige é ela mesma ou a equipe SignXP.

Suspender corta a emissão de documentos novos e nada mais. O cliente continua acessando o que já assinou, e a URL de verificação de cada documento continua respondendo. Foi decisão de produto: ninguém deveria perder o acervo por ter parado de contratar.

Consumo e o aviso de franquia

GET /api/partner/v1/tenants/{reference}/usage
{
  "period": "2026-08",
  "documents_used": 20,
  "documents_limit": 25,
  "documents_remaining": 5,
  "percent_used": 80,
  "reference": "solar-prime-engenharia",
  "external_ref": "tenant-4711"
}

Use o percent_used para avisar o cliente antes de a franquia acabar. Sem esse aviso, o primeiro sinal de que o limite estourou é uma recusa da API no meio de uma venda — e a essa altura você já perdeu a chance de oferecer o upgrade com calma.

Estourar a quota não gera cobrança extra para o canal: gera o bloqueio, e o caminho de saída é o cliente contratar um plano direto no SignXP, pelo link de acesso ao portal.

A fronteira do canal

Quando um cliente seu contrata um plano diretamente com o SignXP, ele passa a billing_mode: "direct". Ele continua sendo do seu canal — você segue atualizando contatos, nome e origens de embed, e segue lendo o consumo. O que muda é o comercial: plan e suspend passam a responder 409.

É proposital. A partir do momento em que a conta paga o SignXP, o plano e o interruptor deixam de ser do canal — nenhum parceiro deve conseguir rebaixar ou desligar uma conta que paga por fora.

Emitir uma chave nova

POST /api/partner/v1/tenants/{reference}/keys
{ "name": "Rotação", "environment": "live" }

A resposta traz o token em claro. A chave anterior continua válida — quem a revoga é o painel do SignXP ou o próprio cliente. Derrubá-la aqui cortaria a integração no instante em que a substituta ainda não foi publicada do seu lado.

Enviando documentos

Daqui para a frente é a API de assinatura normal, autenticada com a chave sk_live_ da conta do cliente. Não existe um envio "de canal": quota, validação, idempotência e preparo são exatamente os mesmos.

Uma recomendação que vale para quase todo canal: como o PDF sai de um template seu, as coordenadas dos campos são estáveis. Use placement: "inline" com coordenadas fixas por template e o cliente nunca vê uma tela de posicionamento — o documento sai pronto do seu app. O posicionamento assistido só se justifica quando o layout varia documento a documento.

Callback de canal

Os callbacks de todas as suas contas chegam numa URL só, assinados com um segredo só — o do canal, entregue junto do pk_. É a razão de o canal existir como conceito: sem isso você guardaria um callback_secret por cliente só para conferir assinatura.

Cada entrega diz de quem é, no corpo e no cabeçalho:

{
  "event": "document.awaiting_review",
  "id": 128,
  "reference": "solar-prime-engenharia",
  "external_id": "proposta-4711-0003",
  "status": "awaiting_review"
}
X-SignXP-Reference: solar-prime-engenharia

A URL do canal é o padrão, não uma imposição: se um envio trouxer callback_url próprio, ele ganha, e a entrega vai assinada com o segredo daquela conta. Um padrão não sobrepõe uma escolha feita na chamada.

A validação da assinatura é idêntica à da integração comum — só a chave muda. Veja os exemplos em Callbacks.

Acesso ao portal sob demanda

Seu cliente vive dentro do seu produto e não deveria precisar de mais um login. Mas três coisas só existem no portal do SignXP: contratar um plano quando a franquia acaba, liberar um documento retido pela validação por IA, e ver o acervo completo.

Para isso existe o link de uso único:

POST /api/partner/v1/tenants/{reference}/portal-link
{
  "email": "marina@solarprime.com.br",
  "target": "reviews"
}
{
  "url": "https://app.signxp.com.br/acesso/xxxxxxxx",
  "expires_at": "2026-08-07T14:35:00-03:00",
  "target": "reviews"
}

A conta no portal é criada na primeira vez, sem senha e sem convite por e-mail. O link abre a sessão direto na tela pedida.

target Leva para
plans Contratar ou trocar de plano.
reviews Fila de validação manual — documentos esperando conferência.
documents Acervo.
billing Faturas e assinatura.
dashboard Painel (padrão).

Peça o link no clique do usuário, não no cadastro dele. Ele vale cinco minutos, morre no primeiro uso, e emitir um novo invalida o anterior — a URL é a credencial, e uma credencial guardada em banco ou em log é uma credencial vazada.

Um 409 aqui significa que o e-mail informado já pertence a outra conta do SignXP. Contas nunca trocam de dono por esta rota, nem para o canal que provisionou o cliente: use outro endereço.

O ciclo que fecha

A combinação que mais importa na prática:

  1. Seu cliente envia uma proposta pela API, com a chave dele.
  2. Todos assinam, mas a validação por IA não fecha o veredito de uma imagem.
  3. Você recebe document.awaiting_review na URL do canal, com o reference.
  4. Seu app mostra "1 documento aguardando sua conferência" para aquele cliente.
  5. No clique, você pede um portal-link com target: "reviews".
  6. Ele confere, aprova, e o documento conclui — e volta para o seu app.

Sem o passo 3 o documento fica parado sem ninguém saber que a espera é de uma pessoa, não de um signatário.