Incluida en todos los planes — sin coste extra

Tu software factura. Fatora hace el resto.

¿Tu SaaS, CRM o aplicación no tiene módulo de facturación marroquí? Un botón en tu lado, una llamada HTTP en el nuestro: Fatora emite la factura o el presupuesto en la numeración del comerciante, con su sello, su logo y todas las menciones del artículo 145 del código fiscal — PDF incluido, entregado por WhatsApp, email o código QR.

  • Facturas y presupuestos conformes: ICE, identificador fiscal, IVA detallado, importe en letras, secuencia continua
  • Entrega a tu manera: WhatsApp, email o un código QR imprimible — el cliente escanea y descarga
  • Modificación en texto libre: escribe el cambio, la IA lo aplica
  • Logo, sello y datos de la empresa gestionables por API

Obtener la clave API

  1. 1El comerciante abre su conversación de WhatsApp con Fatora-Bot
  2. 2Escribe simplemente «api»
  3. 3El bot responde con su clave personal (fk_…) — pégala en tu aplicación

La clave pertenece a cada comerciante y está incluida en su plan, desde la prueba gratuita. «api reset» la regenera en cualquier momento. Las facturas API consumen la cuota del plan; los presupuestos son gratuitos e ilimitados.

En marcha en 5 minutos

Una sola petición emite un documento. Los precios son sin impuestos por defecto; pasa "priceIsTtc": true si tus importes son con IVA — Fatora reconstruye la base.

Petición
curl -X POST https://bot.swiviq.com/v1/documents \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "invoice",
    "client": { "name": "ATLAS DIGITAL SARL", "ice": "001122334455667", "type": "company" },
    "items": [
      { "description": "Abonnement CRM — pack annuel", "quantity": 1, "unitPrice": 4800 },
      { "description": "Formation équipe (2 jours)", "quantity": 2, "unitPrice": 1500 }
    ],
    "sendToEmail": "client@exemple.ma"
  }'
Respuesta — 201
{
  "number": "FAT-2026-0042",
  "type": "invoice",
  "status": "issued",
  "issueDate": "2026-08-15",
  "client": { "name": "ATLAS DIGITAL SARL", "ice": "001122334455667", "type": "company" },
  "items": [
    { "description": "Abonnement CRM — pack annuel", "quantity": 1, "unitPrice": 4800, "vatRate": 20 },
    { "description": "Formation équipe (2 jours)", "quantity": 2, "unitPrice": 1500, "vatRate": 20 }
  ],
  "totals": { "ht": 7800, "vat": 1560, "ttc": 9360, "currency": "MAD" },
  "pdfUrl": "https://bot.swiviq.com/f/a1b2c3d4e5",
  "qrcodeUrl": "https://bot.swiviq.com/qr/a1b2c3d4e5.png",
  "whatsapp": { "owner": "sent", "client": "skipped" },
  "email": { "client": "sent" }
}
★ Único de Fatora

La modificación en texto libre

Ningún esquema de patch que aprender. Tu usuario escribe la corrección en un campo de texto, tú nos la pasas tal cual — el mismo motor de IA que entiende a los comerciantes en dariya por WhatsApp la descodifica y la aplica.

Petición
curl -X POST https://bot.swiviq.com/v1/documents/FAT-2026-0042/modify \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "instruction": "le client est en fait STE ATLAS DIGITAL MAROC SARL,
                    et remplace la formation par 3 jours à 1200 dh le jour"
  }'
Respuesta — 200
{
  "number": "FAT-2026-0042",
  "client": { "name": "STE ATLAS DIGITAL MAROC SARL", "ice": "001122334455667", "type": "company" },
  "items": [
    { "description": "Abonnement CRM — pack annuel", "quantity": 1, "unitPrice": 4800, "vatRate": 20 },
    { "description": "Formation équipe", "quantity": 3, "unitPrice": 1200, "vatRate": 20 }
  ],
  "totals": { "ht": 8400, "vat": 1680, "ttc": 10080, "currency": "MAD" },
  "pdfUrl": "https://bot.swiviq.com/f/a1b2c3d4e5",
  "applied": "le client est en fait STE ATLAS DIGITAL MAROC SARL, et remplace…"
}

El documento conserva su número (sin hueco en la secuencia), el PDF se regenera, los totales se recalculan. Si la instrucción no se entiende, la API responde 422 con una explicación — nunca una modificación arriesgada.

Entrega al cliente: WhatsApp, email o código QR

Emitir no basta — el cliente final debe recibir su documento. Tres canales, combinables, reutilizables a voluntad: una factura perdida se reenvía en una llamada.

WhatsApp

"sendToPhone" al crear, o POST /send con channel "whatsapp": el PDF llega a la conversación del cliente, a nombre del comerciante.

Email

"sendToEmail" al crear, o channel "email": el cliente recibe un mensaje cuidado con la factura adjunta — la misma plantilla del bot.

Código QR

Cada documento expone "qrcodeUrl": un PNG para mostrar en caja, imprimir en un ticket o integrar en tu interfaz. El cliente escanea, la factura se descarga.

Petición
curl -X POST https://bot.swiviq.com/v1/documents/FAT-2026-0042/send \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "email", "to": "client@exemple.ma" }'
Respuesta — 200
{ "ok": true, "number": "FAT-2026-0042",
  "channel": "email", "to": "client@exemple.ma", "status": "sent" }

Referencia de endpoints

✓ Cada ejemplo de abajo fue reproducido tal cual contra la API de producción el 15/08/2026 — las respuestas mostradas son las reales.

POST/v1/documents

Emitir una factura o presupuesto

"type": "invoice" (por defecto) o "quote". Opciones: "priceIsTtc", "vatRate" por línea o global, "sendToPhone" y "sendToEmail" para entrega inmediata, "notify": false para no avisar al comerciante. Responde 201 con número, totales, enlace PDF y código QR.

Ver el ejemplo probado
Petición
curl -X POST https://bot.swiviq.com/v1/documents \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "invoice",
    "client": { "name": "ATLAS DIGITAL SARL", "ice": "001122334455667", "type": "company" },
    "items": [
      { "description": "Abonnement CRM — pack annuel", "quantity": 1, "unitPrice": 4800 },
      { "description": "Formation équipe (2 jours)", "quantity": 2, "unitPrice": 1500 }
    ],
    "sendToEmail": "client@exemple.ma"
  }'
Respuesta
{
  "number": "FAT-2026-0042",
  "type": "invoice",
  "status": "issued",
  "issueDate": "2026-08-15",
  "client": { "name": "ATLAS DIGITAL SARL", "ice": "001122334455667", "type": "company" },
  "items": [
    { "description": "Abonnement CRM — pack annuel", "quantity": 1, "unitPrice": 4800, "vatRate": 20 },
    { "description": "Formation équipe (2 jours)", "quantity": 2, "unitPrice": 1500, "vatRate": 20 }
  ],
  "totals": { "ht": 7800, "vat": 1560, "ttc": 9360, "currency": "MAD" },
  "pdfUrl": "https://bot.swiviq.com/f/a1b2c3d4e5",
  "qrcodeUrl": "https://bot.swiviq.com/qr/a1b2c3d4e5.png",
  "whatsapp": { "owner": "sent", "client": "skipped" },
  "email": { "client": "sent" }
}
POST/v1/documents/{number}/modify

Modificar en texto libre

El cuerpo lleva una única "instruction" en texto libre (francés, dariya o inglés). Mismo número, PDF regenerado, un campo "applied" confirma la instrucción entendida.

Ver el ejemplo probado
Petición
curl -X POST https://bot.swiviq.com/v1/documents/FAT-2026-0042/modify \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "instruction": "le client est en fait STE ATLAS DIGITAL MAROC SARL,
                    et remplace la formation par 3 jours à 1200 dh le jour"
  }'
Respuesta
{
  "number": "FAT-2026-0042",
  "client": { "name": "STE ATLAS DIGITAL MAROC SARL", "ice": "001122334455667", "type": "company" },
  "items": [
    { "description": "Abonnement CRM — pack annuel", "quantity": 1, "unitPrice": 4800, "vatRate": 20 },
    { "description": "Formation équipe", "quantity": 3, "unitPrice": 1200, "vatRate": 20 }
  ],
  "totals": { "ht": 8400, "vat": 1680, "ttc": 10080, "currency": "MAD" },
  "pdfUrl": "https://bot.swiviq.com/f/a1b2c3d4e5",
  "applied": "le client est en fait STE ATLAS DIGITAL MAROC SARL, et remplace…"
}
POST/v1/documents/{number}/send

Entregar o reenviar un documento

{ "channel": "whatsapp" | "email", "to": número o dirección }. El PDF se regenera si falta — reutilizable cuantas veces haga falta.

Ver el ejemplo probado
Petición
curl -X POST https://bot.swiviq.com/v1/documents/FAT-2026-0042/send \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "email", "to": "client@exemple.ma" }'
Respuesta
{ "ok": true, "number": "FAT-2026-0042",
  "channel": "email", "to": "client@exemple.ma", "status": "sent" }
GET/qr/{token}.png

Código QR de descarga (público)

El PNG del QR que apunta al PDF. Sin autenticación: el token es el secreto. Intégralo directamente en un <img> o imprímelo en un ticket.

Ver el ejemplo probado
Petición
<!-- directement dans votre page -->
<img src="https://bot.swiviq.com/qr/a1b2c3d4e5.png" width="180" alt="QR facture">

# ou en téléchargement
curl -o facture-qr.png https://bot.swiviq.com/qr/a1b2c3d4e5.png
Respuesta
HTTP 200 — image/png, 600 × 600 px
Cache-Control: public, max-age=86400, immutable
GET/v1/documents

Listar documentos

Los últimos documentos, del más reciente al más antiguo. "limit" hasta 50, "type" para filtrar facturas ("invoice") o presupuestos ("quote").

Ver el ejemplo probado
Petición
curl -H "Authorization: Bearer fk_votre_cle" \
  "https://bot.swiviq.com/v1/documents?limit=5&type=invoice"
Respuesta
[
  {
    "number": "FAT-2026-0042",
    "type": "invoice",
    "status": "issued",
    "issueDate": "2026-08-15",
    "client": { "name": "STE ATLAS DIGITAL MAROC SARL", "ice": "001122334455667" },
    "totals": { "ht": 8400, "vat": 1680, "ttc": 10080, "currency": "MAD" },
    "pdfUrl": "https://bot.swiviq.com/f/a1b2c3d4e5",
    "qrcodeUrl": "https://bot.swiviq.com/qr/a1b2c3d4e5.png"
  },
  { "number": "FAT-2026-0041", "...": "..." }
]
GET/v1/documents/{number}

Leer un documento

Líneas, totales, enlace PDF, código QR — útil para mostrar el estado en tu interfaz o verificar una modificación.

Ver el ejemplo probado
Petición
curl -H "Authorization: Bearer fk_votre_cle" \
  https://bot.swiviq.com/v1/documents/FAT-2026-0042
Respuesta
{
  "number": "FAT-2026-0042",
  "type": "invoice",
  "status": "issued",
  "issueDate": "2026-08-15",
  "client": { "name": "STE ATLAS DIGITAL MAROC SARL", "ice": "001122334455667", "type": "company" },
  "items": [
    { "description": "Abonnement CRM — pack annuel", "quantity": 1, "unitPrice": 4800, "vatRate": 20 },
    { "description": "Formation équipe", "quantity": 3, "unitPrice": 1200, "vatRate": 20 }
  ],
  "totals": { "ht": 8400, "vat": 1680, "ttc": 10080, "currency": "MAD" },
  "pdfUrl": "https://bot.swiviq.com/f/a1b2c3d4e5",
  "qrcodeUrl": "https://bot.swiviq.com/qr/a1b2c3d4e5.png"
}
GET/v1/account

Cuenta y cuota

Perfil de empresa, plan activo, cuota usada/restante. También es la forma más simple de comprobar que una clave es válida.

Ver el ejemplo probado
Petición
curl -H "Authorization: Bearer fk_votre_cle" \
  https://bot.swiviq.com/v1/account
Respuesta
{
  "company": {
    "name": "ATLAS SERVICES SARL", "ice": "002233445566778",
    "address": "Agdal, Rabat", "defaultVatRate": 20,
    "taxRegime": "normal", "hasLogo": true, "hasStamp": true
  },
  "plan": { "key": "p100", "label": "100 factures / mois", "priceMAD": 90 },
  "quota": { "used": 12, "limit": 100, "remaining": 88, "ok": true }
}
PUT/v1/company

Actualizar la empresa

Campos aceptados: companyName, ice, if, taxePro, rc, address, email, defaultVatRate, paymentTerms. Solo se modifican los campos enviados.

Ver el ejemplo probado
Petición
curl -X PUT https://bot.swiviq.com/v1/company \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "address": "12 rue Oued Fès, Agdal, Rabat",
    "paymentTerms": "Virement à 30 jours"
  }'
Respuesta
{
  "ok": true,
  "company": {
    "name": "ATLAS SERVICES SARL", "ice": "002233445566778",
    "address": "12 rue Oued Fès, Agdal, Rabat", "defaultVatRate": 20
  }
}
POST/v1/company/logo

Subir el logo

Cuerpo: { "image": "<base64 o data-URI png/jpeg>" } (6 MB máx). Limpiado y recortado automáticamente, luego aplicado a los próximos PDF.

Ver el ejemplo probado
Petición
curl -X POST https://bot.swiviq.com/v1/company/logo \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d "{ \"image\": \"data:image/png;base64,$(base64 -w0 logo.png)\" }"
Respuesta
{ "ok": true, "logo": "saved",
  "appliesTo": "toutes les prochaines factures" }
POST/v1/company/stamp

Subir el sello

Mismo formato que el logo. Fondo eliminado por extracción de tinta (basta una foto del sello sobre papel), luego estampado en cada PDF.

Ver el ejemplo probado
Petición
curl -X POST https://bot.swiviq.com/v1/company/stamp \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "Content-Type: application/json" \
  -d "{ \"image\": \"data:image/png;base64,$(base64 -w0 cachet.jpg)\" }"
Respuesta
{ "ok": true, "stamp": "saved",
  "appliesTo": "toutes les prochaines factures" }

Códigos de error

Todo error devuelve un JSON con dos campos constantes: "error" (código máquina estable, para comprobar en tu código) y "message" (explicación en claro, mostrable tal cual). El 402 añade "used", "limit" y "reason" para construir tu propia pantalla de cuota.

400Petición inválidaCódigos: invalid_json (cuerpo ilegible), empty_body (cuerpo vacío — comprueba que ningún salto de línea rompe tus cabeceras), missing_client, missing_items, invalid_channel, invalid_phone, invalid_email, invalid_image. El mensaje dice exactamente qué campo corregir.
401Clave ausente o inválidamissing_api_key: añade la cabecera Authorization: Bearer fk_… · invalid_api_key: clave desconocida o revocada por «api reset» — pide la nueva al comerciante.
402Cuota del plan alcanzadaquota_exceeded: la respuesta lleva used/limit/reason. Los presupuestos no cuentan. El comerciante sube de plan en dos mensajes de WhatsApp.
403Cuenta suspendidaaccount_suspended: la cuenta del comerciante está suspendida — contacta contact@swiviq.com.
404Documento no encontradonot_found: ningún documento con ese número en ESTA cuenta — cada clave solo ve sus propios documentos.
409Documento anuladocancelled: el documento fue anulado (abono emitido) — ya no puede modificarse ni reenviarse. Emite uno nuevo.
413Cuerpo demasiado grandebody_too_large: 8 MB máximo — comprime el logo o el sello antes de subirlo.
422Instrucción no entendidainstruction_not_understood: la IA no pudo aplicar el cambio con seguridad — reformula con más precisión. Nada fue modificado.
429Demasiadas peticionesrate_limited: 60 peticiones/minuto por clave — reduce el ritmo o encola, luego reintenta.
500Error internointernal: reintenta; si persiste, escribe a contact@swiviq.com con el cuerpo de la respuesta.
Respuesta
HTTP 402
{
  "error": "quota_exceeded",
  "reason": "trial",
  "used": 2,
  "limit": 2,
  "message": "Quota d'essai atteint (2 factures). Le commerçant peut passer
              au plan supérieur depuis son WhatsApp Fatora."
}

Preguntas de integración

¿Cuánto cuesta la API?

Nada más que el plan Fatora del comerciante, prueba gratuita incluida. Las facturas API cuentan en la cuota del plan como las dictadas por WhatsApp; los presupuestos son gratuitos e ilimitados.

¿Quién posee la clave: yo (el editor) o mi usuario?

Cada comerciante tiene su propia clave, ligada a su cuenta y su numeración. Tu aplicación guarda la clave que el usuario pega — sin cuenta central que gestionar, cada cliente paga su propio plan.

Mis importes son con IVA — ¿qué hago?

Añade "priceIsTtc": true. Fatora reconstruye la base sin impuestos dividiendo por uno más el tipo, línea a línea.

¿El comerciante es autónomo, sin IVA?

Su régimen fiscal está registrado en su cuenta y se impone a la API: envíe lo que envíe tu aplicación, sus documentos salen sin IVA, con la mención adecuada.

¿Qué pasa cuando se alcanza la cuota?

La API responde 402 con used, limit y un mensaje listo para mostrar. El comerciante cambia de plan en dos mensajes de WhatsApp.