Crear y enviar un documento

De un PDF a un documento firmado, con Firmame llevando las invitaciones.

Esta guía cubre la integración más común: subes un contrato, defines quién firma y dónde, y Firmame se encarga de invitar a la gente y avisarte cuando terminen.

Lo mínimo que funciona

const response = await services.request({
  url_doc: {
    url: 'https://ejemplo.com/contrato.pdf',
    name: 'contrato.pdf',
  },
  stickers: [
    {
      authority: 'EMAIL_LINK',
      data: '[email protected]',
      page: 0,
      rect: { lx: 330, ly: 300, tx: 530, ty: 400 },
    },
  ],
});

La respuesta trae lo que necesitas guardar:

{
  "document_ticket": "c6279a7c-b3d5-4c71-b417-4687a4f38914",
  "sticker_count": 1,
  "stickers": [{ "sticker_id": "qv3ZzAL3w", "sticker_index": 0, "…": "…" }],
  "document_url": "https://app.firmame.com/pdf/c6279a7c-b3d5-4c71-b417-4687a4f38914/"
}

Guarda document_ticket: es el identificador del documento en todo lo demás, y también llega como firmamex_id en los webhooks. Guarda también los sticker_id si vas a querer corregir un firmante más adelante.

De dónde puede venir el PDF

Manda exactamente una de estas tres:

Firmame lo descarga. Útil cuando el PDF ya vive en tu almacenamiento.

url_doc: {
  url: 'https://ejemplo.com/contrato.pdf',
  name: 'contrato.pdf',
}

Dónde va cada firma

Hay dos formas de decirle a Firmame dónde va cada firma: dibujando el recuadro dentro del documento, o mandando coordenadas explícitas en stickers.

Recuadros automáticos

Si quien redacta o genera el documento puede marcar dónde va la firma, esta es la forma más simple: dibuja el recuadro dentro del PDF con la palabra Firmamex seguida de los datos del firmante. Firmame lo encuentra, lo borra y coloca ahí el área de firma — tu código deja de necesitar coordenadas. Así se ve en la práctica: PDF de ejemplo.

Con coordenadas

Si prefieres fijar la posición desde tu código, cada entrada de stickers es una persona firmando en un lugar. Dos convenciones que conviene tener presentes al calcularla:

page empieza en cero. La primera página es 0.

rect va en coordenadas de PDF, con el origen abajo a la izquierda. La mayoría de los editores gráficos lo pone arriba, así que si tomas las coordenadas de una herramienta de diseño, invierte el eje vertical.

     ty ┌───────────────┐
        │               │
        │   la firma    │
        │               │
     ly └───────────────┘
        lx             tx

  (0,0) = esquina inferior izquierda de la página

Si no conoces de antemano el tamaño de la página —porque el PDF lo genera alguien más— POST /api/pdf/pageData te da sus dimensiones para calcular el rectángulo.

Que Firmame mande las invitaciones

Con lo de arriba tienes un documento firmable, pero el reparto de document_url queda de tu lado. Para que Firmame invite, agrega un workflow y dale email a cada firmante:

const response = await services.request({
  url_doc: { url: 'https://ejemplo.com/contrato.pdf', name: 'contrato.pdf' },
  stickers: [
    {
      authority: 'EMAIL_LINK',
      data: '[email protected]',
      email: '[email protected]',
      page: 0,
      rect: { lx: 330, ly: 300, tx: 530, ty: 400 },
    },
    {
      authority: 'EMAIL_LINK',
      data: '[email protected]',
      email: '[email protected]',
      page: 0,
      rect: { lx: 330, ly: 150, tx: 530, ty: 250 },
    },
  ],
  workflow: {
    subject: 'Contrato de arrendamiento',
    message: 'Te compartimos el contrato para tu firma.',
    remindEvery: '1d',
    ordered: true,
    signersConfig: [{ data: '[email protected]' }, { data: '[email protected]' }],
  },
});

Con ordered: true, Luis no recibe su invitación hasta que Ana firma. Los detalles del flujo — expiración, recordatorios, copias a terceros — están en Flujos de firma.

Enterarte de que ya firmaron

Registra un webhook para document_completed y Firmame te avisa cuando el último firmante termina:

{
  "notification_type": "document_completed",
  "notification_id": "2698",
  "firmamex_id": "c6279a7c-b3d5-4c71-b417-4687a4f38914",
  "document_title": "contrato.pdf"
}

Con ese firmamex_id descargas el documento firmado, eligiendo type: original para el PDF con las firmas tal como se aplicaron, o universal para esas mismas firmas envueltas en un sobre de validación a largo plazo.

const pdf = await services.downloadDocument(firmamexId, 'original');

Ver Descargar un documento firmado para los detalles del endpoint, y Webhooks para el ciclo completo y la política de reintentos.

Descargar el historial

El documento firmado es la mitad del resultado; la otra es su historial: cuándo se creó, cuándo salió cada invitación, cuándo la abrió cada firmante y cuándo firmó. Con el mismo firmamex_id lo bajas en dos formatos.

const eventos = await services.getHistory(firmamexId);
const historial = await services.getHistoryAsPdf(firmamexId);

El JSON te da un arreglo de eventos, del más reciente al más viejo, para mover tu propia interfaz sin esperar los webhooks: GET /api/v1/document/{frmxId}/history/json. Ahí está también el catálogo completo de tipos de evento.

El PDF es el mismo historial armado para entregárselo a alguien, y es el que un paquete de verificación NOM-151 espera: GET /api/v1/document/{frmxId}/history/pdf.

Y después

En esta página