factura.bo Guía Swagger ReDoc Tipo de cambio Estado

factura.bo — Guía de integración

API REST de facturación electrónica para Bolivia, integrada con el SIAT de Impuestos Nacionales. Esta guía te lleva de cero a tu primera factura en minutos.

Documentación interactiva (Swagger): https://api.factura.bo/docs


1. Entornos

Entorno URL Base SIAT
Sandbox (pruebas) https://apisandbox.factura.bo Piloto
Producción https://api.factura.bo Real

Los endpoints son idénticos en ambos entornos. Desarrolla contra sandbox y cambia la URL base al pasar a producción.

2. Autenticación

Todas las peticiones protegidas llevan tu API Key en la cabecera:

X-API-KEY: tu_api_key

La API Key identifica a tu empresa (NIT) y su configuración: modalidad de facturación, créditos disponibles y token SIAT. Se obtiene en el panel de administración o contactando a gm@simplifyit.com.bo.

3. Formato de respuesta

Todos los endpoints responden el mismo envelope:

{
  "ok": true,
  "datos": { },
  "error": null,
  "timestamp": "2026-07-02T14:30:00+00:00"
}
HTTP Significado
200 Operación exitosa (ok: true)
400 Datos inválidos, falta configuración, o el SIAT rechazó el documento
402 Créditos de facturación agotados
403 API Key inválida, cliente inactivo, o email en sandbox (ver §8)
404 Recurso no encontrado / punto de venta no sincronizado
409 Ya hay una operación en curso con la misma X-Idempotency-Key, o intentaste revertir una anulación sobre una factura que no está ANULADA — reintenta o esperá unos segundos
502 El SIAT no respondió, se cayó a mitad de la operación, o rechazó con un error no HTTP

3.1 Rechazos del SIAT

Cuando tu request llegó bien pero Impuestos Nacionales lo rechazó, el error viene como HTTP 400 o 502 con este formato:

{
  "detail": "El SIAT rechazó la factura: [{'codigo': 1040, 'descripcion': 'FECHA DE EMISION NO SE ENCUENTRA EN EL RANGO DE CONTINGENCIA ...'}]"
}

detail siempre empieza con una frase fija ("El SIAT rechazó...") seguida de la lista de mensajes tal cual los devolvió el SIAT — parseá por el patrón 'codigo': X si necesitás manejar casos específicos en tu código.

Código Significa Qué hacer
123 CUFD fuera de tolerancia (vencido) Llamá a POST /v1/sincronizar — el CUFD vence cada 24h
981 El evento significativo tiene fecha_fin en el futuro, o se solapa con otro ya registrado Registrá el evento después de que termine el corte, nunca antes; no declares ventanas que se crucen con eventos previos
984 El CUFD no corresponde a la ventana del evento declarado Normalmente se resuelve solo; si persiste, resincronizá CUFD y reintentá
902 "Cafc no encontrado" Falta el campo cafc en una factura offline de tipo de evento 5, 6 o 7 Ver §7.1 — esos tres tipos exigen CAFC
1040 La fecha de emisión de una factura offline queda fuera del rango [inicio, fin] del evento Declará la ventana con el fecha_emision real de tus facturas, no con tu reloj local (ver §7)
1047 El número de factura excede el rango autorizado por tu CAFC Pedí al SIN un CAFC nuevo con un rango mayor
954 El paquete de contingencia supera las 500 facturas permitidas Mandá los paquetes de a 500 como máximo
1002 / 1006 CUF o CUFD del archivo no coincide con lo esperado por el SIAT en un paquete No mezcles facturas de eventos o CUFD distintos en un mismo paquete
1049 En una nota de crédito/débito, la línea codigo_detalle_transaccion=1 no replica exacto la cantidad/precio de la factura original Ver §6 — esa línea tiene que ser una copia exacta del ítem original

4. Primeros pasos (quickstart)

Paso 1 — Sincroniza tu punto de venta

Obtiene los códigos CUIS y CUFD del SIAT. El CUFD vence cada 24 h: llama a este endpoint todos los días antes de facturar (idealmente con un cron a las 00:05 hora Bolivia).

curl -X POST https://apisandbox.factura.bo/v1/sincronizar \
  -H "X-API-KEY: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "nit": 123456789,
    "codigo_sistema": "TU_CODIGO_SISTEMA",
    "sucursal": 0,
    "punto_venta": 0
  }'

Paso 2 — Descarga los catálogos (una vez)

curl -X POST https://apisandbox.factura.bo/v1/sincronizar/catalogos \
  -H "X-API-KEY: $API_KEY" -H "Content-Type: application/json" \
  -d '{"nit": 123456789, "codigo_sistema": "TU_CODIGO_SISTEMA"}'

Se descargan los 18 catálogos del SIAT en una sola llamada. Luego consulta cualquiera con GET /v1/catalogos/{nombre}: actividades, actividades_documento_sector, eventos_significativos, fecha_hora, leyendas, mensajes_servicios, metodos_pago, motivos_anulacion, paises, productos_servicios, tipos_documento_identidad, tipos_documento_sector, tipos_emision, tipos_factura, tipos_habitacion, tipos_moneda, tipos_punto_venta, unidades_medida.

Paso 3 — Emite tu primera factura

curl -X POST https://apisandbox.factura.bo/v1/facturas \
  -H "X-API-KEY: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "emisor": {
      "sucursal": 0,
      "punto_venta": 0,
      "actividad_economica": "620000"
    },
    "cliente": {
      "tipo_documento": 5,
      "numero_documento": "987654321",
      "razon_social": "ACME S.R.L.",
      "correo": "cliente@acme.bo"
    },
    "metodo_pago": 1,
    "items": [
      {
        "codigo_producto": "SRV-001",
        "codigo_sin": 83141,
        "descripcion": "Desarrollo de software",
        "cantidad": 1,
        "unidad_medida": 58,
        "precio_unitario": 1500.00
      }
    ]
  }'

Respuesta:

{
  "ok": true,
  "datos": {
    "cuf": "3001000100001000000001241220000071",
    "numero_factura": 42,
    "estado": "EMITIDA",
    "url_pdf": "https://storage.googleapis.com/...",
    "url_xml": "https://storage.googleapis.com/...",
    "pdf_base64": "JVBERi0xLjQK...",
    "respuesta_siat": { "transaccion": true }
  }
}

Guarda el CUF: es el identificador único de la factura para consultas, anulaciones y notas de crédito.

Idempotencia (evita facturas duplicadas)

Una factura recibida por el SIAT no puede revertirse, solo anularse. Para que un timeout o un reintento de red nunca genere un duplicado fiscal, envía el header opcional X-Idempotency-Key con un valor único por operación (el ID de tu pedido, un UUID, etc.):

curl -X POST https://apisandbox.factura.bo/v1/facturas \
  -H "X-API-KEY: $API_KEY" \
  -H "X-Idempotency-Key: pedido-4521" \
  -H "Content-Type: application/json" -d '{ ... }'

Las claves se recuerdan por 30 días. No aplica dentro de /v1/facturas/lote.

5. Sectores soportados (15)

Cada tipo de actividad usa su propio endpoint con campos específicos. Si tu actividad no tiene sector especial, usa el general (POST /v1/facturas).

Código SIAT Sector Endpoint
1 Compra y Venta (general) POST /v1/facturas
2 Alquiler de Bien Inmueble POST /v1/facturas/alquiler
3 Exportación de bienes POST /v1/facturas/exportacion
4 Exportación en Libre Consignación POST /v1/facturas/exportacion-libre-consignacion
6 Servicio Turístico y Hospedaje (Ley 292, sin crédito fiscal) POST /v1/facturas/turismo
8 Tasa Cero (libros, transporte internacional) POST /v1/facturas/tasa-cero
11 Sector Educativo POST /v1/facturas/educacion
13 Servicio Básico (agua, gas, electricidad) POST /v1/facturas/servicio-basico
14 Alcanzada por el ICE POST /v1/facturas/ice
16 Hotel POST /v1/facturas/hotel
17 Hospital y Clínica POST /v1/facturas/hospital
28 Exportación de Servicios POST /v1/facturas/exportacion-servicios
24 Nota Fiscal Crédito/Débito POST /v1/notas/fiscal
47 Nota Crédito/Débito/Descuento POST /v1/notas
48 Nota Crédito/Débito con ICE POST /v1/notas/ice

La lista siempre actualizada: GET /v1/catalogos/sectores (no requiere pasos previos).

Campos comunes a toda factura

Campo Tipo Descripción
emisor.sucursal int 0 = casa matriz
emisor.punto_venta int 0 si solo tienes uno
emisor.actividad_economica string Código CAEB (catálogo actividades)
cliente.tipo_documento int 1=CI, 2=CEX, 3=Pasaporte, 4=Otro, 5=NIT
cliente.numero_documento string "0" para consumidor final
cliente.razon_social string Obligatorio con NIT
metodo_pago int 1=Efectivo, 2=Tarjeta, 7=Transferencia (catálogo metodos_pago)
moneda int 1=BOB (defecto), 2=USD
tipo_cambio float Solo si moneda != 1. Usa el oficial: GET /ExchangeRate
descuento_adicional float Descuento global en Bs
contingencia bool true = emisión offline (ver §7)
codigo_excepcion int 1 = emitir aunque el NIT del cliente sea inválido
numero_tarjeta string Primeros 4 + últimos 4 dígitos, el resto enmascarado con asteriscos: 1234****5678
cafc string Código de Autorización de Facturación por Contingencia. Solo con contingencia: true y tipo_evento 5, 6 o 7 (ver §7.1)

Campos comunes por ítem

Campo Tipo Descripción
codigo_producto string Tu código interno
codigo_sin int Código del catálogo productos_servicios del SIAT
descripcion string Texto que aparece en la factura
cantidad float Hasta 5 decimales
unidad_medida int Catálogo SIAT (58=Servicio, 1=Unidad, 2=Kg…)
precio_unitario float En la moneda de la factura
descuento float Descuento de este ítem en Bs
numero_serie / numero_imei string Solo sector Compra y Venta (1). Para equipos con número de serie o IMEI que el SIAT exige rastrear

Facturación por lotes (hasta 20 por llamada)

Para emisiones masivas (mensualidades, ciclos de servicios básicos, cierres de día) envía varias facturas en un solo request con éxito parcial: cada una se procesa de forma independiente y las fallidas se reportan por índice sin afectar a las demás.

curl -X POST https://apisandbox.factura.bo/v1/facturas/lote \
  -H "X-API-KEY: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "facturas": [
      {"sector": 1,  "factura": { ...igual que POST /v1/facturas... }},
      {"sector": 11, "factura": { ...igual que POST /v1/facturas/educacion... }}
    ]
  }'

La respuesta indica total, exitosas, fallidas y un array resultados donde resultados[i] corresponde a facturas[i]: las exitosas traen su CUF y enlaces; las fallidas, el motivo. Corrige solo esas y reenvíalas en otro lote. Las notas de crédito/débito no se aceptan en lote.

6. Notas de crédito / débito

Ajustan o revierten una factura ya emitida sin eliminarla. Referencia obligatoria a la factura original, y el detalle no es una copia simple de la factura original: por cada ítem que ajustás mandás dos líneas, distinguidas por codigo_detalle_transaccion — esto no es un "motivo", es una etiqueta estructural que el SIAT exige:

monto_total_devuelto se calcula sobre las líneas tipo 2, nunca sobre la factura original. monto_efectivo_credito_debito no es el mismo valor: equivale al 13% (IVA) de monto_total_devuelto, redondeado a 2 decimales.

curl -X POST https://apisandbox.factura.bo/v1/notas \
  -H "X-API-KEY: $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "emisor": {"sucursal": 0, "punto_venta": 0, "actividad_economica": "620000"},
    "cliente": {"tipo_documento": 5, "numero_documento": "987654321", "razon_social": "ACME S.R.L."},
    "cuf_factura_original": "3001000100001000000001241220000071",
    "numero_factura_original": 42,
    "fecha_emision_factura_original": "2026-06-15",
    "monto_total_original": 1500.00,
    "monto_total_devuelto": 500.00,
    "monto_efectivo_credito_debito": 65.00,
    "items": [
      {
        "nro_item": 1,
        "codigo_producto": "SRV-001",
        "codigo_sin": 83141,
        "descripcion": "Desarrollo de software",
        "cantidad": 1,
        "precio_unitario": 500.00,
        "codigo_detalle_transaccion": 1
      },
      {
        "nro_item": 1,
        "codigo_producto": "SRV-001",
        "codigo_sin": 83141,
        "descripcion": "Desarrollo de software",
        "cantidad": 1,
        "precio_unitario": 500.00,
        "codigo_detalle_transaccion": 2
      }
    ]
  }'

El XSD del SIAT exige un mínimo de 2 líneas de detalle en total, aunque solo estés ajustando un ítem.

7. Contingencia (emisión offline)

Cuando pierdas conexión con el SIAT:

1. POST /v1/contingencia/evento          → registra el corte (ver tipos de evento abajo)
2. POST /v1/facturas                     → emite normalmente con "contingencia": true
3. POST /v1/contingencia/paquete         → al volver la conexión, envía todo lo acumulado
4. POST /v1/contingencia/validar-paquete → confirma que el SIAT procesó el paquete (codigo_recepcion del paso 3)

Las facturas offline quedan en estado OFFLINE y recién pasan a EMITIDA (y descuentan su crédito) en el paso 4, una por una, según lo que el SIAT confirme para cada archivo — no en el paso 3. El SIAT procesa los paquetes de forma asíncrona: la validación del paso 4 puede haber archivos observados (rechazados individualmente) aunque transaccion: true a nivel paquete — esos quedan OFFLINE sin cobrarse. Revisá siempre datos.mensajes, no solo el código HTTP. Podés llamar al paso 4 más de una vez para el mismo codigo_recepcion (por ejemplo, mientras esperás a que el SIAT termine de procesar) sin riesgo de que te cobre dos veces.

Importante — registrá el evento DESPUÉS del corte, no antes. fecha_fin nunca puede quedar en el futuro (el SIAT lo rechaza con código 981), y la ventana [fecha_inicio, fecha_fin] tiene que cubrir el momento real en que emitiste cada factura offline. Si tu servidor y el nuestro tienen aunque sea un pequeño desfase de reloj, construí la ventana con el campo fecha_emision que te devuelve cada factura emitida (no con tu reloj local) para evitar el código 1040 ("fecha de emisión fuera del rango de contingencia").

7.1 Tipos de evento y cuándo necesitás CAFC

Código Descripción ¿Necesita cafc?
1 Corte del servicio de internet No
2 Inaccesibilidad al servicio web de la Administración Tributaria No
3 Ingreso a zonas sin internet por despliegue de punto de venta No
4 Venta en lugares sin internet No
5 Virus informático o falla de software
6 Cambio de infraestructura de sistema o falla de hardware
7 Corte de suministro de energía eléctrica

La diferencia real: los tipos 1-4 son problemas de conectividad — tu sistema sigue funcionando y puede firmar XML localmente, solo se corta el enlace con el SIAT. Los tipos 5-7 son casos donde tu propio sistema no pudo operar — para esos, el SIAT exige un CAFC (Código de Autorización de Facturación por Contingencia), que se pide directamente a soporte del SIN (no es autoservicio como el CAFC de facturas manuales impresas). Una vez que lo tengas, incluilo como campo cafc en cada factura que emitas con "contingencia": true para esos tipos de evento — sin él, el envío del paquete se rechaza con código 902 ("Cafc no encontrado"). El CAFC viene con un rango de números de factura autorizados; si lo excedés, el SIAT rechaza con código 1047 y hay que pedir uno nuevo con un rango mayor.

Para auditar los cortes registrados:

GET /v1/contingencia/eventos?fecha=2026-07-01   → eventos significativos de esa fecha ante el SIAT

8. Consultas y anulación

GET  /v1/facturas                             → historial con filtros (?desde=&hasta=&estado=&nit_cliente=&limite=)
GET  /v1/facturas/{cuf}                       → una factura (estado local + URLs de PDF/XML)
GET  /v1/facturas/{cuf}/estado-siat           → verificación EN TIEMPO REAL ante el SIAT
POST /v1/facturas/{cuf}/anular                → anulación (motivo, ver tabla abajo)
POST /v1/facturas/{cuf}/revertir-anulacion    → revierte una anulación: la factura vuelve a estar vigente
motivo Descripción
1 Factura mal emitida
2 Nota crédito-débito mal emitida
3 Datos de emisión incorrectos
4 Factura o nota crédito-débito devuelta

(catálogo vigente: GET /v1/catalogos/motivos_anulacion)

La reversión solo aplica a facturas en estado ANULADA (responde 409 en otro caso) y emite el webhook factura.anulacion_revertida al confirmarse.

Acceso público para el cliente final (sin autenticación)

Cada factura emitida devuelve url_publica: un enlace permanente que puedes enviar a tu cliente por email, WhatsApp o QR. El CUF actúa como token de acceso.

GET /f/{cuf}          → página de verificación (estado, emisor, fecha, descargas)
GET /f/{cuf}/pdf      → descarga el PDF tamaño A4 (enlace siempre vigente)
GET /f/{cuf}/ticket   → descarga el ticket de 80mm para impresoras térmicas
GET /f/{cuf}/xml      → descarga el XML fiscal

Cada emisión devuelve ambos formatos gráficos: url_pdf (A4, para email y archivo) y url_ticket (80mm, para el punto de venta).

A diferencia de url_pdf/url_xml (URLs firmadas que expiran), los enlaces /f/{cuf}/... nunca caducan: generan una URL fresca en cada descarga.

Email automático al cliente

Si al emitir incluyes cliente.correo, la factura se envía automáticamente por email con el PDF adjunto y el enlace público de verificación.

Para reenviarla (o enviarla a otra dirección):

curl -X POST "https://api.factura.bo/v1/facturas/{cuf}/reenviar-email?email=otro@correo.com" \
  -H "X-API-KEY: $API_KEY"

Si omites ?email=, se usa el correo registrado al emitir.

En sandbox nunca se envían emails. Las facturas de prueba no generan correos al cliente final, aunque incluyas cliente.correo, y el endpoint de reenvío responde 403. Así puedes probar con datos reales sin riesgo de notificar a nadie. El envío automático también puede activarse o desactivarse por cuenta en producción (responde 403 si está desactivado).

9. Webhooks (notificaciones en tiempo real)

En vez de consultar el estado repetidamente, registra una URL de tu servidor y recibe los eventos cuando ocurren:

curl -X POST https://apisandbox.factura.bo/v1/webhooks \
  -H "X-API-KEY: $API_KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://tu-sistema.com/webhooks/facturabo", "eventos": ["factura.*", "creditos.bajos"]}'

La respuesta incluye un secreto (whsec_...) que solo se muestra una vez.

Eventos disponibles: factura.emitida, factura.offline, factura.anulada, factura.anulacion_revertida, nota.emitida, contingencia.paquete_enviado, creditos.bajos, siat.caido, siat.recuperado, webhook.prueba. Puedes suscribirte con * (todos) o por prefijo (factura.*).

siat.caido / siat.recuperado: te avisan cuando el SIAT de Impuestos Nacionales deja de responder (3 sondeos fallidos consecutivos) y cuando se recupera. Úsalos para activar el modo contingencia automáticamente en tu sistema, sin esperar a que una emisión falle.

Cada entrega va firmada (estándar Standard Webhooks) con estos headers:

Webhook-Id: evt_a1b2c3...        ← único por evento; descarta duplicados con él
Webhook-Timestamp: 1751470000    ← rechaza mensajes con más de 5 min de antigüedad
Webhook-Signature: v1,K5oZfz...  ← HMAC-SHA256 del contenido

Verifica la firma en tu servidor antes de confiar en el evento:

import base64, hashlib, hmac

def verificar_firma(secreto, headers, cuerpo_crudo):
    llave = base64.b64decode(secreto.split("_", 1)[1])
    contenido = f"{headers['webhook-id']}.{headers['webhook-timestamp']}.{cuerpo_crudo}"
    esperada = "v1," + base64.b64encode(
        hmac.new(llave, contenido.encode(), hashlib.sha256).digest()).decode()
    return hmac.compare_digest(esperada, headers["webhook-signature"])

Si tu servidor no responde 2xx, la entrega se reintenta automáticamente con backoff exponencial. Gestión completa:

POST   /v1/webhooks                 → registrar (devuelve el secreto)
GET    /v1/webhooks                 → listar
DELETE /v1/webhooks/{id}            → eliminar
POST   /v1/webhooks/{id}/rotar      → nuevo secreto
POST   /v1/webhooks/{id}/probar     → evento de prueba síncrono (valida tu firma)

10. Utilidades

POST /v1/nit/validar         → valida el NIT del cliente ante el SIAT antes de facturar
GET  /v1/cuenta              → créditos restantes, modalidad, estado
GET  /v1/cuenta/consumo      → historial de créditos consumidos por día o por mes (?desde=&hasta=&agrupar_por=dia|mes)
GET  /v1/cuenta/api-key      → tu API Key y contra qué URL usarla
POST /v1/cuenta/api-key/regenerar → cambia tu API Key por una nueva
GET  /v1/estado              → estado de la API y del SIAT (sin autenticación)
POST   /v1/operaciones/puntos-venta          → registrar un punto de venta nuevo en el SIAT
GET    /v1/operaciones/puntos-venta          → listar puntos de venta registrados
DELETE /v1/operaciones/puntos-venta/{codigo} → cerrar (dar de baja) un punto de venta

Tu API Key

La llave llega por correo al crear la cuenta, y también podés verla en app.factura.bo → Más → API Key. Desde ahí se regenera si se te filtró:

curl -X POST https://api.factura.bo/v1/cuenta/api-key/regenerar \
  -H "X-API-KEY: tu_api_key"

[!WARNING] La llave anterior deja de funcionar en el acto. Todo lo que la esté usando se corta hasta que pegues la nueva.

Si entrás desde el portal con tu sesión, solo el propietario de la cuenta puede ver o cambiar la llave; un usuario con rol cajero puede emitir pero no llevársela.

Consumo de créditos (no solo el saldo)

GET /v1/cuenta te da la foto de hoy. Para entender tu ritmo de consumo — cuánto gastaste esta semana, si el mes pasado tuviste un pico — usá GET /v1/cuenta/consumo:

curl "https://api.factura.bo/v1/cuenta/consumo?desde=2026-07-01&hasta=2026-07-31&agrupar_por=dia" \
  -H "X-API-KEY: $API_KEY"
{
  "ok": true,
  "datos": {
    "desde": "2026-07-01",
    "hasta": "2026-07-31",
    "agrupado_por": "dia",
    "total_consumido": 340,
    "creditos_disponibles": 2790,
    "consumo": [
      {"periodo": "2026-07-01", "creditos_consumidos": 12},
      {"periodo": "2026-07-02", "creditos_consumidos": 9}
    ]
  }
}

Sin desde/hasta, devuelve los últimos 30 días. Solo cuenta facturas y notas emitidas en línea: las offline (contingencia) no descuentan crédito hasta que su paquete es validado por el SIAT.

Estado del SIAT en tiempo real

¿No puedes emitir y sospechas que el SIAT está caído? Consulta factura.bo/estado: sondeamos el SIAT cada 5 minutos con la operación oficial verificarComunicacion y publicamos su estado (OPERATIVO / DEGRADADO / CAIDO), la latencia y el uptime de los últimos 90 días, tanto de producción como del piloto.

La versión JSON es GET /v1/estado — pública, gratuita y sin API key:

{
  "api": {"estado": "OPERATIVO", "ambiente": "produccion"},
  "siat_produccion": {"estado": "OPERATIVO", "ultima_latencia_ms": 840, "uptime_30d": 99.87},
  "siat_piloto": {"estado": "OPERATIVO", "ultima_latencia_ms": 1220, "uptime_30d": 99.62}
}

Para reaccionar sin consultar, suscríbete a los webhooks siat.caido y siat.recuperado (sección 9).

11. Reportes contables

Pensados para el contador de tu empresa:

GET /v1/reportes/libro-ventas?gestion=2026&mes=6   → Libro de Ventas IVA en CSV (formato RCV)
GET /v1/reportes/respaldo?gestion=2026&mes=6       → ZIP con todos los XML y PDF del mes

12. Tipo de cambio BCB (gratuito, sin API Key)

GET /ExchangeRate                    → USD/BOB y UFV oficiales del día
GET /ExchangeRate/history?limit=30   → histórico
GET /ExchangeRate/history/2026-07-01 → una fecha específica

Se actualiza cada noche a las 00:05 hora Bolivia desde el sitio del Banco Central de Bolivia. Úsalo para llenar tipo_cambio en facturas en USD.

13. Modalidades SIAT

Modalidad Cómo funciona Requisito
1 — Electrónica en Línea El servicio firma el XML con tu certificado digital Certificado .p12 (se sube al aprovisionar)
2 — Computarizada en Línea XML sin firma, con código de control Solo token SIAT

La modalidad se configura por empresa al aprovisionarla; el emisor no necesita cambiar nada en sus requests.

14. Buenas prácticas

  1. Renueva el CUFD a diario (cron 00:05 Bolivia) — es la causa #1 de rechazos.
  2. Valida el NIT del cliente antes de emitir para evitar rechazos (o envía codigo_excepcion: 1).
  3. Guarda el CUF de cada factura en tu sistema: lo necesitas para notas y anulaciones.
  4. Monitorea tus créditos con GET /v1/cuenta y recarga antes de agotarlos (HTTP 402).
  5. En cortes de internet usa el flujo de contingencia (§7) — es legal y automático.
  6. Los enlaces url_pdf/url_xml son URLs firmadas con expiración. Para compartir con el cliente final usa url_publica (/f/{cuf}), que nunca caduca y genera descargas frescas en cada acceso.

15. Servidor MCP — factura desde tu asistente de IA

factura.bo expone un servidor MCP (Model Context Protocol): conecta tu asistente de IA (Claude, ChatGPT, Cursor, etc.) y podrás facturar y consultar conversando.

"Emite una factura a ACME S.R.L., NIT 987654321, por 2 horas de consultoría a 500 Bs cada una" → el asistente emite la factura y te devuelve el PDF.

Configuración (ejemplo para Claude Desktop / clientes compatibles):

{
  "mcpServers": {
    "factura-bo": {
      "type": "http",
      "url": "https://api.factura.bo/mcp",
      "headers": { "X-API-KEY": "tu_api_key" }
    }
  }
}

En Claude Code:

claude mcp add --transport http factura-bo https://api.factura.bo/mcp \
  --header "X-API-KEY: tu_api_key"

Herramientas disponibles:

Herramienta Requiere API Key
consultar_tipo_de_cambio — USD y UFV oficiales del BCB No
consultar_estado_siat — ¿está caído el SIAT? Estado y uptime No
listar_sectores — tipos de factura soportados No
consultar_creditos — saldo de tu cuenta
validar_nit — verifica un NIT ante el SIAT
listar_facturas — historial con filtros
consultar_factura — detalle por CUF
emitir_factura — emite factura de Compra y Venta (Sector 1)

Por seguridad, la anulación no está disponible por MCP (es permanente): hazla desde tu sistema o con el API. Para pruebas usa el servidor sandbox: https://apisandbox.factura.bo/mcp.

16. Integración con Odoo

Existe un addon oficial para Odoo 19: SimplifyIT: Facturación Electrónica Bolivia (SIAT) — emisión desde tus facturas de cliente, validación de NIT desde el contacto, anulación, notas de crédito y sincronización diaria del CUFD. Compatible con Odoo Community y Enterprise.


¿Dudas o necesitas tu API Key? Escríbenos a gm@simplifyit.com.bo.


factura.bo — Facturación electrónica para Bolivia (SIAT) · SimplifyIT S.R.L. · gm@simplifyit.com.bo · factura.bo