Inicio Funciones Precios Comparar Seguridad API Integraciones Guías English Iniciar sesión
Desarrolladores

API de LuzardoFax

Envía y recibe faxes, recupera documentos e integra el fax en tus propios sistemas. Disponible en todos los planes de LuzardoFax.

Base URL https://luzardofax.com/api/v1

Quickstart

Envía tu primer fax en cinco minutos.

Tres pasos: crea una API key, envía un fax y recibe el resultado.

  • 1. Crea una API key — en tu cuenta, ve a Ajustes → API → Nueva API key. La API key se muestra una sola vez; guárdala en un secrets manager, nunca en código del lado del cliente ni en un repositorio público.
  • 2. Envía un fax — una solicitud, con el archivo incluido:
curl -X POST https://luzardofax.com/api/v1/faxes \
    -H "Authorization: Bearer lfx_live_YOUR_KEY" \
    -H "Idempotency-Key: $(uuidgen)" \
    -F "to=+13055551234" \
    -F "to_name=Dr. Smith" \
    -F "subject=Referral" \
    -F "[email protected]"

Recibirás 202 Accepted — el fax está queued, todavía no delivered:

{
    "data": {
      "id": 103,
      "reference": "LFX-S-1-103",
      "object": "fax",
      "status": "queued",
      "to": "+13055551234",
      "pages": 1
    },
    "request_id": "req_9f2c1a8b4d"
  }
  • 3. Obtén el resultado — configura un webhook (recomendado) o haz polling GET /faxes/{id}.
Autenticación

Autenticación y scopes.

Cada solicitud lleva tu API key en el encabezado Authorization . No existe una alternativa mediante query parameter a propósito: las keys en URLs terminan en los logs del servidor.

Authorization: Bearer lfx_live_a1b2c3d4...

Las API keys tienen scopes. Concede solo lo que necesita la integración:

  • fax:send — enviar faxes
  • fax:read — leer metadatos, status y documentos de fax
  • contacts:read — leer la libreta de direcciones
  • numbers:read — leer los números de fax de la cuenta
  • account:read — leer el plan, el uso y los webhooks

Las API keys se almacenan con hash de nuestro lado. No podemos volver a mostrarte una API key después de crearla; si se pierde o queda expuesta, revócala y crea una nueva. La revocación entra en vigor de inmediato.

Manejo de API keys

Guarda las API keys del lado del servidor en un secrets manager o una variable de entorno. Nunca las incluyas en JavaScript del navegador, apps móviles ni repositorios públicos. Rótalas si se va un desarrollador que tenía acceso.

Idempotencia

Nunca envíes el mismo fax dos veces.

Si tu conexión se interrumpe después de que recibimos una solicitud pero antes de que recibas la respuesta, volver a intentarlo a ciegas enviaría el fax otra vez. Envía un Idempotency-Key header con un valor único para cada fax y eso no puede ocurrir.

Idempotency-Key: 8f14e45f-ea6f-4c0b-9d3a-1c2b7e9a4d55
  • Misma key, misma solicitud — devolvemos la respuesta original con el header Idempotent-Replay: true. No se envía un segundo fax.
  • Misma key, todavía en procesamiento — 409 request_in_progress. Vuelve a intentarlo en un momento.
  • Misma key, solicitud diferente — 422 idempotency_key_reused. Usa una key nueva para un fax nuevo.
  • Las keys se conservan durante 24 horas y están limitadas a tu cuenta.

Usa un UUID por cada fax saliente. Si una solicitud falla antes de completarse, la key se libera para que puedas volver a intentarlo de forma segura.

Ciclo de vida del fax

Qué significa cada status del fax.

Un fax pasa por estos estados:

queued  →  sending  →  delivered
                     ↘  failed
  (converting)  — when a DOCX needs conversion first
  • queued — aceptado, esperando para enviarse
  • converting — un archivo DOCX se está convirtiendo a PDF
  • sending — transmisión en curso con el operador
  • delivered — el equipo receptor confirmó la recepción
  • failed — consulta recipients[].error para ver el motivo (línea ocupada, sin respuesta, no es una máquina de fax)
  • partial — fax con varios destinatarios donde algunos tuvieron éxito y otros fallaron

202 Accepted significa que aceptamos el fax, no que llegó. La entrega se confirma mediante el fax.delivered webhook o consultando el status.

POST /faxes

Envío de faxes.

POST /api/v1/faxes — multipart/form-data. Scope: fax:send.

  • to — número de fax del destinatario en E.164 (+13055551234). Repite el campo para varios destinatarios, hasta 20.
  • to_name — opcional, se empareja por posición con to
  • subject, notes — opcional, se usa en la carátula
  • cover_id — opcional, una carátula de tu cuenta
  • files — uno o más archivos adjuntos

Archivos: PDF, DOCX, JPG, PNG, TIFF. Hasta 25 MB cada uno, hasta 20 por fax. DOCX se convierte del lado del servidor antes del envío, lo que agrega una breve demora.

Debes enviar al menos un archivo o un cover_id para enviar solo una carátula.

Endpoints

Lectura de faxes, contactos y cuenta.

  • GET /faxes — lista. Query: limit (máx. 100), offset, direction (inbound/outbound), status, created_after, created_before. Devuelve total y has_more.
  • Sincronización incremental: pasa el created_at del fax más reciente que ya tienes como created_after (UTC, ISO 8601) y solo recibirás lo nuevo. Ambos límites de fecha son exclusivos. Los resultados se ordenan created_at DESC, id DESC, lo que se mantiene estable entre páginas.
  • GET /faxes/{id} — un fax, incluido el status y error de cada destinatario.
  • GET /faxes/{id}/pdf — el documento en sí, como application/pdf.
  • GET /contacts — libreta de direcciones. Query: q, limit, offset.
  • GET /numbers — números de fax activos en la cuenta.
  • GET /account — plan, páginas usadas, límite de páginas y ciclo de facturación.

Todas las marcas de tiempo están en UTC. Todos los endpoints de lista devuelven el mismo envelope: { data: { object: "list", data: [...], total, limit, offset, has_more } }.

Aviso sobre PHI

GET /faxes/{id}/pdf devuelve un documento que puede contener información médica protegida. No registres el response body ni expongas estas URLs a clientes que no deban ver PHI.

Webhooks

Recibe avisos cuando ocurre algo.

En lugar de hacer polling, danos un endpoint HTTPS y te notificamos. Configúralo en Ajustes → API → Webhooks o mediante la API:

  • GET /api/v1/webhooks — lista tus endpoints. Scope: webhooks:read (account:read también se acepta para compatibilidad con versiones anteriores).
  • POST /api/v1/webhooks — crea uno. Body: url (se requiere HTTPS), events (array, opcional; el valor predeterminado es todos), description. El signing secret se devuelve una sola vez. Scope: webhooks:write.
  • DELETE /api/v1/webhooks/{id} — elimínalo. Scope: webhooks:write.

Eventos: fax.delivered, fax.partial, fax.failed, fax.received.

Los faxes con varios destinatarios generan un solo evento, no uno por destinatario. Recibirás fax.delivered cuando todos los destinatarios tuvieron éxito, fax.failed cuando todos fallaron y fax.partial cuando el resultado es mixto. En todos los casos, el payload incluye el desglose por destinatario, así que revisa data.recipients[] para ver exactamente qué números se completaron.

Cada entrega se ve así:

{
    "id": "evt_7c3f9a1b2e4d6f8a0b1c",
    "type": "fax.delivered",
    "created": 1784580000,
    "data": {
      "id": 103,
      "reference": "LFX-S-1-103",
      "object": "fax",
      "status": "delivered",
      "pages": 1,
      "recipients": [{ "to": "+13055551234", "status": "delivered", "error": null }]
    }
  }

Los payloads de webhook nunca contienen el contenido de los documentos de fax — solo metadatos operativos del fax, como status, cantidad de páginas y números de destinatarios. Trata esos metadatos como información sensible y protégelos adecuadamente en flujos de trabajo de salud. Si necesitas el documento, recupéralo con tu API key.

Verificación de la firma. Cada solicitud incluye:

X-LuzardoFax-Signature: t=1784580000,v1=5257a869e7ecebeda32affa62cdca3fa...
  X-LuzardoFax-Event: fax.delivered

Calcula HMAC-SHA256 de "{t}.{raw_body}" usando el signing secret de tu endpoint y compáralo con v1 mediante una comparación en tiempo constante:

const crypto = require('crypto');
  
  function verify(rawBody, header, secret, toleranceSeconds = 300) {
    const parts = Object.fromEntries(
      header.split(',').map(p => p.split('='))
    );
    const expected = crypto
      .createHmac('sha256', secret)
      .update(parts.t + '.' + rawBody)
      .digest('hex');
  
    // constant-time comparison
    const ok = crypto.timingSafeEqual(
      Buffer.from(expected), Buffer.from(parts.v1)
    );
    // reject old timestamps (replay protection)
    const fresh = Math.abs(Date.now()/1000 - Number(parts.t)) < toleranceSeconds;
    return ok && fresh;
  }

Usa el raw request body, antes de cualquier análisis de JSON; un JSON serializado nuevamente no coincidirá.

Reintentos y duplicados. Volvemos a intentarlo hasta 6 veces con exponential backoff (30s, 2m, 8m, 32m, 2h, 8h) hasta que tu endpoint devuelva un 2xx. Eso significa que puedes recibir el mismo evento más de una vez. Guarda el evento id e ignora las repeticiones; haz que tu handler sea idempotente.

Devuelve un 2xx rápidamente (en menos de 10 segundos). Haz el trabajo pesado después de responder o lo tratamos como un timeout y volvemos a intentarlo.

Envío de eventos a herramientas que no pueden manejar PHI

Algunas plataformas de automatización, como Zapier y similares, no admiten información médica protegida y no firman un BAA. También conservan una copia de cada ejecución en su propio historial, por lo que una advertencia en tu flujo de trabajo no es suficiente.

Para esos casos, crea una API key con el zapier:events:read scope. Los endpoints de webhook creados con esa key reciben un payload reducido, sin PHI :

  • Incluye: evt_id, type, occurred_at, direction, status, page_count, y error_code de una lista cerrada.
  • Nunca incluye: el fax id, la referencia LFX, números de fax, subject, sender name, cost ni el raw provider error.

El scope es mutuamente excluyente con fax:send, fax:read, contacts:read y numbers:read. Una key no puede tener ambos, por lo que una integración que recibe estos eventos nunca puede darse la vuelta y recuperar el documento. Funciona junto con webhooks:read, webhooks:write y account:read.

Referencia

Errores y rate limits.

Todos los errores tienen la misma estructura:

{
    "error": {
      "type": "quota_error",
      "code": "page_limit_reached",
      "message": "Sending this fax would exceed your plan limit."
    },
    "request_id": "req_9f2c1a8b4d"
  }

Incluye el request_id cuando contactes a soporte — nos permite encontrar la solicitud exacta.

  • 400 invalid_request — parámetros ausentes o con formato incorrecto
  • 401 authentication_error — API key ausente, inválida o revocada
  • 403 permission_error — la API key no tiene el scope requerido
  • 402 quota_error — se alcanzó el límite de páginas o el envío está pausado en la cuenta
  • 404 not_found — el recurso no existe o pertenece a otra cuenta
  • 409 request_in_progress — la misma Idempotency-Key todavía está en procesamiento
  • 422 idempotency_key_reused — key reutilizada con un body diferente
  • 429 rate_limit_error — reduce la velocidad; consulta Retry-After
  • 500 api_error — de nuestro lado. Vuelve a intentarlo con la misma Idempotency-Key.

Rate limits: 120 solicitudes por minuto por API key. Cada respuesta incluye X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset.

API keys activas por plan: Solo 3 · Plus 5 · Team 10 · Business 25. Las API keys revocadas no cuentan.

Cuota: los faxes enviados mediante la API cuentan contra el mismo límite mensual de páginas que la app. Al 110% de tu límite, el envío y la recepción se pausan hasta que agregues páginas.

Cumplimiento

Seguridad y HIPAA.

Esta API puede transportar información médica protegida cuando se usa en flujos de trabajo regulados por HIPAA. LuzardoFax admite esos flujos bajo un BAA (Business Associate Agreement o Acuerdo de Socio Comercial) firmado, pero la forma en que construyes y operas tu integración es tu responsabilidad.

  • Solo HTTPS. Se rechaza HTTP sin cifrar, incluidos los endpoints de webhook.
  • API keys del lado del servidor. Nunca en código del navegador, apps móviles ni repositorios públicos.
  • Mínimo privilegio. Concede solo los scopes que necesita la integración.
  • Rota las API keys cuando se vaya un desarrollador que tenía acceso y revócalas de inmediato si alguna queda expuesta.
  • Evita registrar PHI. No registres request bodies ni response bodies de endpoints de fax.
  • No pongas PHI en URLs ni en query parameters; terminan en access logs y analytics.
  • Protege tu endpoint de webhook y verifica cada firma antes de actuar sobre un payload.
En palabras sencillas

Usar esta API no hace por sí solo que tu organización cumpla con HIPAA. El cumplimiento depende de tu propio análisis de riesgos, políticas, salvaguardas y de cómo construyas y operes los sistemas alrededor de esta integración. LuzardoFax es responsable de sus obligaciones conforme al BAA aplicable y la ley; los clientes siguen siendo responsables de la seguridad y el cumplimiento de sus propias aplicaciones, infraestructura, políticas y flujos de trabajo.

¿Preguntas sobre la API? Escribe a [email protected] e incluye el request_id.