Inicio rápido
En este tutorial se lleva una plantilla publicada hasta un PDF firmado y sellado. Se utiliza una clave de
prueba, por lo que no se factura nada y todos los documentos llevan la marca de agua TEST.
-
Cree una clave de API
Sección titulada «Cree una clave de API»Las claves de API se crean en el panel, en Configuración › Claves de API. Elija Prueba para este tutorial: la clave empieza por
bf_test_. La clave completa solo se muestra una vez; guárdela en una variable de entorno.Ventana de terminal export BONA_FIDE_API_KEY=bf_test_…Cada petición la envía como
Authorization: Bearer …(ox-api-key: …). Consulte Autenticación. -
Localice su plantilla
Sección titulada «Localice su plantilla»Las plantillas se diseñan en el panel (suba un PDF o un documento de Word y coloque los campos, o redáctela en el modo Documento) y después se publican. Obtenga la lista para conocer el ID:
Ventana de terminal curl https://api.bonafidesign.com/v1/templates \-H "Authorization: Bearer $BONA_FIDE_API_KEY"const res = await fetch('https://api.bonafidesign.com/v1/templates', {headers: { Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}` },});const { data } = await res.json(); // [{ id: 'tpl_…', name: 'Mutual NDA', latestVersion: 3, … }]import os, requestsAPI = "https://api.bonafidesign.com"headers = {"Authorization": f"Bearer {os.environ['BONA_FIDE_API_KEY']}"}templates = requests.get(f"{API}/v1/templates", headers=headers).json()["data"]GET /v1/templates/{id}/versions/latestdevuelve losrolesy losfieldsde la versión, así como el JSON Schema de susvariables. La página de la plantilla en el panel también incluye un apartado Usar en la API con una petición preparada para esa versión concreta. -
Cree un sobre
Sección titulada «Cree un sobre»POST /v1/envelopesgenera la plantilla con sus variables, fija la versión e inicia el enrutamiento. Indique un destinatario por rol (los roles CC son opcionales). Envíe unaIdempotency-Keypara que un reintento no pueda enviar el sobre dos veces.Ventana de terminal curl https://api.bonafidesign.com/v1/envelopes \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-H "Idempotency-Key: onboarding-8841" \-d '{"template": "tpl_…","version": "latest","variables": {"client": { "name": "Acme Robotics, Inc." },"effective_date": "2026-10-13"},"recipients": [{ "role": "client", "name": "Jane Doe", "email": "jane@acme.dev" }],"delivery": "embedded","externalId": "user_8841","dedupeOn": "external_id"}'const res = await fetch('https://api.bonafidesign.com/v1/envelopes', {method: 'POST',headers: {Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}`,'Content-Type': 'application/json','Idempotency-Key': 'onboarding-8841',},body: JSON.stringify({template: 'tpl_…',version: 'latest',variables: { client: { name: 'Acme Robotics, Inc.' }, effective_date: '2026-10-13' },recipients: [{ role: 'client', name: 'Jane Doe', email: 'jane@acme.dev' }],delivery: 'embedded',externalId: 'user_8841',dedupeOn: 'external_id',}),});if (res.status === 422) {// RFC 9457 problem: one entry per error, each with a JSON Pointer such as /variables/client/nameconsole.error((await res.json()).errors);}const envelope = await res.json(); // { id: 'env_…', status: 'sent', recipients: [{ id: 'rcp_…', … }] }res = requests.post(f"{API}/v1/envelopes",headers={**headers, "Idempotency-Key": "onboarding-8841"},json={"template": "tpl_…","version": "latest","variables": {"client": {"name": "Acme Robotics, Inc."}, "effective_date": "2026-10-13"},"recipients": [{"role": "client", "name": "Jane Doe", "email": "jane@acme.dev"}],"delivery": "embedded","externalId": "user_8841","dedupeOn": "external_id",},)if res.status_code == 422:print(res.json()["errors"]) # [{"pointer": "/variables/client/name", "message": "…"}]envelope = res.json()La respuesta es
201 Createdcon el sobre:{"id": "env_8Gm2kQ4rT1","organization": "org_…","template": "tpl_…","templateVersion": 3,"status": "sent","seal": "not_started","testMode": true,"recipients": [{"id": "rcp_5Jw0pLs9Xe","role": "client","name": "Jane Doe","email": "jane@acme.dev","order": 1,"status": "sent","verification": "email_otp","completedAt": null}],"documentHash": "9f2c…","sealedDocumentHash": null,"externalId": "user_8841","metadata": {},"createdAt": "2026-10-13T13:58:04.512Z","completedAt": null}deliverydetermina cómo se llega a los destinatarios:email(el valor predeterminado) envía a cada destinatario un enlace de firma por correo electrónico cuando le toca;embeddedynoneno envían ningún correo, y es usted quien abre las sesiones de firma (paso siguiente). -
Deje que el destinatario firme
Sección titulada «Deje que el destinatario firme»Genere una sesión de firma para el destinatario desde su backend. Las sesiones son de corta duración (
ttlSeconds, de 60 a 3600; 600 por defecto) y de un solo uso.Ventana de terminal curl https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/sessions \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-d '{"recipient": "rcp_5Jw0pLs9Xe","mode": "embedded","allowedOrigins": ["https://app.example.com"]}'Pase el
tokendevuelto (bfs_…) a su página y renderice el componente web:<script type="module" src="https://js.bonafidesign.com/v1"></script><bf-signing session="bfs_…"></bf-signing><script>document.querySelector('bf-signing').addEventListener('completed', (e) => console.log('signed', e.detail.envelope));</script>Wrappers para React y Vue, eventos y modelo de seguridad: Firma integrada.
Ventana de terminal curl https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/sessions \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-d '{ "recipient": "rcp_5Jw0pLs9Xe", "mode": "hosted", "returnUrl": "https://app.example.com/done" }'Redirija al firmante a la
urldevuelta (https://sign.bonafidesign.com/s/bfs_…). La página alojada está pensada en primer lugar para el móvil y no requiere ninguna cuenta.Con la verificación predeterminada,
email_otp, el firmante confirma un código de seis dígitos que recibe en su correo electrónico antes de enviar. En modo de prueba, los correos solo se entregan a los miembros de su organización, así que utilice su propia dirección mientras hace pruebas. -
Reciba un aviso al completarse
Sección titulada «Reciba un aviso al completarse»Registre un endpoint de webhook en Configuración › Webhooks (o con
POST /v1/webhook-endpoints) y guarde el secretowhsec_…. Cuando firma el último destinatario, recibeenvelope.completed, con todas las variables y todos los valores introducidos endata.values. El PDF sellado llega a continuación conenvelope.sealed.import express from 'express';import { Webhook } from 'standardwebhooks';const wh = new Webhook(process.env.BONA_FIDE_WEBHOOK_SECRET!);const app = express();app.post('/hooks/bona-fide', express.raw({ type: 'application/json' }), async (req, res) => {const event = wh.verify(req.body, req.headers as Record<string, string>) as { type: string; data: any };if (event.type === 'envelope.completed') await saveValues(event.data.envelope.id, event.data.values);if (event.type === 'envelope.sealed') await fetchSealedPdf(event.data.envelope.id);res.sendStatus(204);});Descargue el PDF sellado (el documento con su certificado de finalización y su sello de tiempo):
Ventana de terminal curl -o signed.pdf "https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/document?version=sealed" \-H "Authorization: Bearer $BONA_FIDE_API_KEY"Lista completa de eventos, reintentos y verificación manual: Webhooks.
Paso a producción
Sección titulada «Paso a producción»Sustituya la clave de prueba por una clave bf_live_. Los sobres de producción no llevan marca de agua, el correo
se envía a cualquier destinatario y los sobres completados se descuentan de su plan
(Planes y límites). Todo lo que crea una clave hereda su modo, sus listas solo muestran ese
modo y los sobres de prueba solo avisan a los endpoints de webhook en modo de prueba, así que registre también un
endpoint de producción.