Un POST. Enviado a firmar.
Una API REST para enviar PDF a firmar y seguir a cada firmante, webhooks firmados para cada paso, claves de idempotencia y códigos de error estables. Las claves API y los webhooks están incluidos en el plan Enterprise.
Lo que puedes construir: firmas desde tu propio softwarecurl https://api.wesign.now/v1/signing-requests \
-H "Authorization: Bearer $WSK_KEY" \
-H "Idempotency-Key: order-123/sign" \
-F "file=@contract.pdf" \
-F 'signers=[{"email":"jane@acme.com","role":"client"}]' \
-F "placement=auto_append"
# → 201 Created
# {
# "documentId": "8a1e4f9a-…",
# "status": "pending",
# "signers": [{
# "role": "client",
# "signingUrl": "https://acme.wesign.now/en/sign/…",
# "emailed": true, …
# }], …
# }Una API, webhooks y una documentación que también leen tus herramientas.
API REST
Envía un PDF, sigue a cada firmante, envía un recordatorio o retira la solicitud, y descarga el PDF sellado y su registro de auditoría. Claves Bearer, respuestas JSON y una especificación OpenAPI 3.1 con un id para cada operación.
Resumen de la APIWebhooks firmados
signing_request.sent, .viewed, .signed, document.completed y más, cada uno firmado con HMAC-SHA256. Una entrega fallida se reintenta durante unas 45 horas; desde el registro de entregas puedes volver a enviarla.
Eventos de webhookDocumentación para asistentes de IA
llms.txt enumera cada página de la documentación, llms-full.txt las contiene todas en texto plano, y openapi.json la forma exacta de solicitudes y respuestas. Dáselos a tu asistente de programación.
Para asistentes de IAEjemplos concretos.
Cuatro llamadas que necesitan la mayoría de las integraciones. Nombres de campo como en la especificación OpenAPI.
1. Envío con colocación por ancla
Pon en tu PDF un marcador como [[ls:signature:buyer]]. Colocamos ahí el campo de firma del comprador y ocultamos el marcador. ¿Sin marcador en el PDF? Añadimos una página de firma.
POST /v1/signing-requests
Content-Type: multipart/form-data
file=@offer.pdf # the PDF contains [[ls:signature:buyer]]
signers=[{"email":"buyer@acme.com","role":"buyer","name":"Ann Buyer"}]
placement=anchors2. Varios firmantes, en orden
Tres firmantes, uno tras otro. El firmante 2 recibe la invitación solo cuando el firmante 1 ha firmado.
POST /v1/signing-requests
Content-Type: multipart/form-data
file=@contract.pdf
signing_mode=sequential
placement=auto_append
signers=[
{"email":"founder@acme.com","role":"founder"},
{"email":"investor@vc.example","role":"investor"},
{"email":"witness@law.example","role":"witness"}
]3. Receptor de webhook
Comprueba la marca de tiempo y el HMAC sobre el cuerpo sin procesar y luego actúa según el evento.
// Node + Express. The full verifier (Node and PHP) is in the docs.
app.post('/wesign/callback', express.raw({ type: 'application/json' }), (req, res) => {
// X-WeSign-Signature: t=<unix seconds>,v1=<hex> (two v1 for 24 h after a rotation)
const parts = (req.get('x-wesign-signature') ?? '').split(',')
const t = parts[0]?.startsWith('t=') ? parts[0].slice(2) : ''
if (!t || Math.abs(Date.now() / 1000 - Number(t)) > 300) return res.status(401).end()
const expected = crypto.createHmac('sha256', SECRET)
.update(`${t}.${req.body}`).digest()
const valid = parts.filter((p) => p.startsWith('v1=')).some((p) => {
const got = Buffer.from(p.slice(3), 'hex')
return got.length === expected.length && crypto.timingSafeEqual(got, expected)
})
if (!valid) return res.status(401).end()
const evt = JSON.parse(req.body.toString('utf8'))
if (evt.event === 'document.completed') {
// fetch evt.signed_pdf_url with your API key, compare evt.sha256, keep a copy
}
res.sendStatus(200)
})4. Reintento idempotente
La misma clave con el mismo cuerpo en 24 horas repite la primera respuesta, así que un reintento tras un error de red nunca envía dos veces.
POST /v1/signing-requests
Idempotency-Key: order-123/sign
# First call: 201 Created
# Same key + same body (24 h): 201, the same body, Idempotent-Replayed: true
# Same key while the first runs: 409 idempotency_in_progress + Retry-After
# Same key + a different body: 422 idempotency_key_reuseLo que puedes construir hoy.
Cada patrón usa la API REST y los webhooks. Las tarjetas enlazan con la documentación que lo describe.
Con send_emails: false no enviamos ninguna invitación por correo, y el enlace de cada firmante vuelve en la respuesta para tu propio correo, SMS o app. Los recordatorios y el correo de finalización siguen saliendo de nosotros.
send_emailsSu paso HTTP llama a la API con tu clave y su paso de webhook recibe nuestros eventos una vez que lo registras con POST /v1/hooks. No hay nada que instalar.
Hooks para herramientas de automatizaciónTu handler recibe el cambio de etapa del CRM, envía el contrato y actualiza el registro cuando nuestro webhook avisa de la firma. El handler lo operas tú; no hay una app de CRM.
Receta de CRMDocassemble, Pandoc o LaTeX escribe los marcadores de ancla en el PDF, un POST lo envía y descargas el PDF firmado cuando llega document.completed.
Receta de generadorHaz que el agente escriba marcadores como [[ls:signature:client]] en el borrador: ahí quedan los campos. Cada firma la sigue haciendo una persona que abre su enlace.
Receta de agenteCrea en tu servidor una sesión de corta duración y muestra la vista de firma en un iframe de tu propio sitio. Tus firmantes no necesitan cuenta.
Firma integradaNo disponible: un SDK, un sandbox o claves de prueba, ni apps o plug-ins para otras herramientas.
Hecho para producción.
Claves Bearer, dos alcances
Cada clave pertenece a un solo workspace. Una clave full llama a toda la API; una clave embedded solo gestiona sesiones de firma integrada. Limita una clave a tus direcciones IP; una revocación surte efecto al momento.
60 solicitudes por minuto y clave
Una ventana fija por clave en todos los endpoints /v1. Las respuestas correctas llevan las cabeceras RateLimit-*; un 429 lleva Retry-After.
Códigos de error estables
Cada error es un JSON con un mensaje legible (error), un code estable y, donde ayuda, meta. Compara el code; el mensaje puede cambiar.
PDF sellados y verificables
El PDF firmado lleva un sello PAdES que cualquier lector compatible puede verificar. El registro de auditoría lista cada evento con su hora, el correo y la dirección IP enmascarada del firmante, y cada verificación por código SMS.
El acceso a la API viene con Enterprise.
Las claves API y los webhooks forman parte del plan Enterprise. Cuéntanos qué quieres conectar. La documentación es pública, así que puedes leerla antes.
