Factu API Documentación

Tu primera boleta

Emite una boleta de pruebas en cinco minutos. No necesitas conocer SUNAT: mandas lo que vendiste y recibes el comprobante con su PDF.

POSThttps://cpe-dev.facturamovilai.me/v1/emisores/TU_RUC/comprobantes

Cabecera Authorization: Bearer TU_LLAVE. Es la misma llave en pruebas y en producción: lo que cambia es la dirección (cpe-dev o cpe-prod).

Solicitud

curl -X POST "https://cpe-dev.facturamovilai.me/v1/emisores/TU_RUC/comprobantes" \
  -H "Authorization: Bearer TU_LLAVE" \
  -H "Content-Type: application/json" \
  -d '{
  "tipo": "BOLETA",
  "serie": "B001",
  "referencia_externa": "venta-3101",
  "precios_incluyen_igv": true,
  "cliente": {
    "tipo_documento": "SIN_DOCUMENTO"
  },
  "items": [
    {
      "descripcion": "Fideos",
      "cantidad": "3",
      "valor_unitario": "3.50"
    }
  ]
}'
const respuesta = await fetch("https://cpe-dev.facturamovilai.me/v1/emisores/TU_RUC/comprobantes", {
  method: "POST",
  headers: {
    "Authorization": "Bearer TU_LLAVE",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "tipo": "BOLETA",
    "serie": "B001",
    "referencia_externa": "venta-3101",
    "precios_incluyen_igv": true,
    "cliente": {
      "tipo_documento": "SIN_DOCUMENTO"
    },
    "items": [
      {
        "descripcion": "Fideos",
        "cantidad": "3",
        "valor_unitario": "3.50"
      }
    ]
  }),
});

console.log(respuesta.status, await respuesta.json());
# pip install requests
import requests

respuesta = requests.post(
    "https://cpe-dev.facturamovilai.me/v1/emisores/TU_RUC/comprobantes",
    headers={"Authorization": "Bearer TU_LLAVE"},
    json={
        "tipo": "BOLETA",
        "serie": "B001",
        "referencia_externa": "venta-3101",
        "precios_incluyen_igv": True,
        "cliente": {
            "tipo_documento": "SIN_DOCUMENTO",
        },
        "items": [
            {
                "descripcion": "Fideos",
                "cantidad": "3",
                "valor_unitario": "3.50",
            },
        ],
    },
)

print(respuesta.status_code, respuesta.json())

Respuestas

{
  "id": "BOLETA-B001-36",
  "emisor": "TU_RUC",
  "ambiente": "dev",
  "tipo": "BOLETA",
  "serie": "B001",
  "numero": 36,
  "estado": "ACEPTADO",
  "mensaje": "El documento fue enviado correctamente y aceptado por SUNAT.",
  "total": "10.50",
  "referencia_externa": "venta-3101",
  "pdf_factuapi_a4_url": "https://cpe-dev.facturamovilai.me/v1/pdf/<token>",
  "desglose": {
    "gravado": "8.90",
    "exonerado": "0.00",
    "inafecto": "0.00",
    "igv": "1.60",
    "total": "10.50",
    "items": [
      {
        "descripcion": "Fideos",
        "valor_unitario": "2.966102",
        "igv": "1.60",
        "total": "10.50"
      }
    ]
  }
}
estado Significa
ACEPTADO el comprobante existe ante SUNAT
RECHAZADO SUNAT lo procesó y lo rechazó. Llega con 201, no con un error: lee mensaje
PENDIENTE SUNAT sigue procesando. Consúltalo más tarde

La respuesta puede traer campos adicionales a los que ves aquí: usa los de estos ejemplos.

Lo que no mandaste: el número del comprobante, el IGV calculado, el ambiente, ningún código de SUNAT. De eso se encarga la API.

El pdf_factuapi_a4_url es público: puedes mostrarlo o enviarlo tal cual al comprador.