FirmARDigital

Documentación para desarrolladores

Referencia API · Webhooks

Eventos para sincronizar tu sistema

Recibí cambios de estado en tu backend sin depender únicamente de polling. Configurá endpoints desde el panel Enterprise.

Firmados

HMAC SHA-256

Reintentables

Hasta 8 intentos

Persistentes

Historial por endpoint

Eventos disponibles

signer.enrolled
signing_session.created
signing_session.signed

Envelope

El evento siempre conserva este formato. Persistí `id` antes de procesarlo para que una entrega reintentada no ejecute dos veces tu lógica de negocio.

jsonFirmARDigital API
{
  "id": "evt_01J...",
  "type": "signing_session.signed",
  "api_version": "2026-07-01",
  "created_at": "2026-08-01T12:00:00.000Z",
  "data": { "document_id": "doc_123", "status": "SIGNED" }
}

Headers enviados

HeaderUso
x-firmar-event-idIdentificador idempotente del evento.
x-firmar-event-typeTipo del evento que se está entregando.
x-firmar-timestampUnix timestamp en segundos usado en la firma.
x-firmar-signatureFormato `t=<timestamp>,v1=<hmac-sha256>`.

Verificar la firma

Usá el body crudo, no el JSON serializado, y compará con una función de tiempo constante.

javascriptFirmARDigital API
const rawBody = await request.text();
const signature = request.headers.get("x-firmar-signature") ?? "";
const timestamp = request.headers.get("x-firmar-timestamp") ?? "";
const signed = `${timestamp}.${rawBody}`;
const expected = crypto
  .createHmac("sha256", WEBHOOK_SECRET)
  .update(signed)
  .digest("hex");

const [, version] = signature.split(",");
const received = version?.replace("v1=", "") ?? "";

if (
  received.length !== expected.length ||
  !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))
) {
  throw new Error("Firma de webhook inválida");
}
200

Evento de firma completada

jsonFirmARDigital API
{
  "id": "7d920246-1d14-4f43-a194-2f0c2dc7018c",
  "type": "signing_session.signed",
  "apiVersion": "2026-07-31",
  "createdAt": "2026-08-01T12:00:00.000Z",
  "data": {
    "documentId": "cme0tc1tw0003s6a1c4g2n8fj",
    "status": "SIGNED"
  }
}