Configuración

API Pública

Timbra facturas directo desde tu sistema, sin usar el portal — modo relay (tú sellas) o modo sellar (nosotros armamos el XML).

Conceptos básicos

  • API key: token que viaja en cada llamada, header X-Api-Key. Tienes dos, una por ambiente — nunca las compartas ni las subas a un repositorio público.
  • Sandbox vs. producción: lo decide cuál de tus dos keys uses, no la URL. La de sandbox nunca cobra timbre ni tiene valor fiscal; la de producción sí, y solo funciona si tu cuenta está certificada.
  • Modo relay: tú construyes y sellas el XML del CFDI con tu propio CSD; la API solo lo timbra. Nunca vemos tu llave privada.
  • Modo sellar: subes tu CSD a Mi Empresa y nos mandas solo los datos del comprobante (receptor + conceptos); nosotros armamos el XML, lo sellamos y lo timbramos.
  • Certificación: permiso manual que activa soporte una vez que probaste bien en sandbox — sin esto, tu key de producción ni siquiera se puede generar.
  • Cobro: cada timbrado exitoso en producción descuenta 1 timbre de tu saldo, igual que si lo hicieras desde el portal. Sandbox nunca cobra.
Conceptos básicos de la API pública de facturación electrónica de TimbraMX

Timbrar un CFDI — Modo relay

Envía un CFDI que ya generaste y sellaste con tu CSD — el timbrado ante el SAT lo hacemos nosotros. El ambiente (sandbox o producción) lo decide cuál de tus dos API keys uses; la URL es siempre la misma.

Endpoint:

POST /api/v1/facturas

Headers:

Content-Type: application/json
X-Api-Key: tu_api_key
Idempotency-Key: opcional, ver más abajo

Body:

{ "xml": "<XML del CFDI ya sellado, en base64>" }

Respuesta exitosa (201):

{
  "ok": true,
  "data": {
    "id": "b3f1a2c4-...",
    "estado": "timbrada",
    "uuidFiscal": "E95BE615-A8AD-4C33-8E9C-C7612FBF6C9F",
    "pac": "-",
    "timbradaEn": "2026-09-11T17:00:00.000Z",
    "xml": "<XML ya timbrado, con su UUID, en base64>"
  }
}

Ejemplos de código

curl:

curl -X POST https://app.timbra-mx.com/api/v1/facturas \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: tu_api_key" \
  -d '{"xml":"<xml del CFDI ya sellado, en base64>"}'

Node.js (fetch nativo):

const respuesta = await fetch("https://app.timbra-mx.com/api/v1/facturas", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Api-Key": "tu_api_key",
  },
  body: JSON.stringify({ xml: xmlEnBase64 }),
});
const resultado = await respuesta.json();

Python (requests):

import requests

resultado = requests.post(
    "https://app.timbra-mx.com/api/v1/facturas",
    headers={"X-Api-Key": "tu_api_key"},
    json={"xml": xml_en_base64},
).json()

Timbrar un CFDI — Modo sellar

No construyes tú el XML: subes tu CSD a Mi Empresa y nos mandas solo los datos del comprobante. Requiere que el cliente (receptor) y la serie ya existan en tu cuenta — créalos primero en Clientes y Series si no los tienes. Es el mismo endpoint que el modo relay: se detecta automáticamente porque el body trae conceptos en vez de xml.

Body:

{
  "receptorRfc": "XAXX010101000",
  "serie": "F",
  "formaPago": "01",
  "metodoPago": "PUE",
  "moneda": "MXN",
  "conceptos": [
    {
      "claveProdServ": "84111506",
      "claveUnidad": "E48",
      "descripcion": "Servicio de consultoria",
      "cantidad": 1,
      "valorUnitario": 1000,
      "impuestos": [
        { "impuesto": "002", "categoria": "traslado", "tipoFactor": "Tasa", "tasaIva": 0.16 }
      ]
    }
  ]
}

Alcance actual: solo CFDI de Ingreso simple, sin complementos (Carta Porte, Comercio Exterior, etc.) — para esos casos usa el modo relay.

Validar sin timbrar, y cancelar

Valida un CFDI en modo relay (XSD del SAT + reglas de negocio que aplica el PAC) sin gastar ningún intento real de timbrado — siempre regresa 200 con valido: true/false, un XML inválido no es un error de la petición.

POST /api/v1/facturas/validar
{ "xml": "PHNmZGk6Q29tcHJvYmFudGUg..." }

{
  "ok": true,
  "data": { "valido": false, "errores": ["[VAL-04] Falta capturar \"RFC\" en Receptor."] }
}

Para cancelar un CFDI ya timbrado por esta misma API key:

POST /api/v1/facturas/:id/cancelar
{ "motivo": "02", "uuidReemplazo": null }

motivo es la clave del catálogo c_MotivoCancelacion del SAT: 01 con relación (requiere uuidReemplazo), 02 sin relación, 03 la operación no se llevó a cabo, 04 operación nominativa de factura global.

Idempotencia

Si tu petición se cae por timeout de red y no sabes si de verdad timbró, no reintentes a ciegas: manda la misma Idempotency-Key y te regresamos el comprobante que ya existe, sin timbrar ni cobrar dos veces.

X-Api-Key: tu_api_key
Idempotency-Key: pedido-8214

Cualquier string que tú elijas, único por operación (ej. el id de tu propio pedido). Si reintentas con la misma clave, la respuesta trae idempotente: true en vez de crear un comprobante nuevo. Aplica tanto al modo relay como al modo sellar.

Errores comunes

No tienes timbres disponibles. Compra mas timbres para poder timbrar.

Igual que timbrando desde el portal, la API descuenta 1 timbre por CFDI exitoso en producción — sin saldo, la llamada falla con 402.

El complemento API requiere activarlo primero - contactanos por el chat de soporte para contratarlo.

El módulo de API es un complemento aparte que debe estar contratado en tu cuenta antes de poder generar o usar cualquier API key.

Esta factura ya esta siendo timbrada por otra peticion. Reintenta en unos segundos si quedo en 'En proceso'.

Si mandas dos peticiones para el mismo idempotency-key casi al mismo tiempo, la segunda recibe este error 409 en vez de timbrar dos veces.

Preguntas frecuentes

¿Cómo obtengo mi API key de producción?

Primero prueba tu integración completa con la key de sandbox (gratis, sin valor fiscal). Cuando funcione bien, contacta a soporte por el chat para que certifiquen tu cuenta — solo entonces se puede generar la key de producción.

¿Puedo timbrar Carta Porte o Comercio Exterior por la API?

Con el modo sellar no, solo CFDI de Ingreso simple. Con el modo relay sí, porque tú armas el XML completo con cualquier complemento y la API solo lo timbra.

¿Qué pasa si mi API key de sandbox expira?

Expira sola a los 90 días si no la regeneras — es una medida de seguridad para que una key de pruebas olvidada no quede viva para siempre. Genera una nueva desde la vista API en cualquier momento.