Después de timbrar
Saldo de timbres
Consultar cuántos timbres quedan y su historial de movimientos.
Facty es prepago: cada CFDI que emites —factura, nota de crédito, complemento de pago, recibo de nómina, retención— y cada cancelación consumen un timbre.
Una integración que timbra debería vigilar el saldo y avisarle al usuario antes de que se quede en cero, no después.
Saldo actual
GET /api/authenticated/{org}/billing/balance
Scope: billing.read
{ "balance": 1240, "updatedAt": "2026-08-28T18:04:11.000Z" }
También viene en GET /context, como timbreBalance — igualmente condicionado a
que la llave tenga billing.read. Si tu llave no lo trae, ese campo llega null.
Historial de movimientos
GET /api/authenticated/{org}/billing/ledger?limit=25&cursor=…
Scope: billing.read. Devuelve { "entries": [...], "nextCursor": ... } con
compras, consumos y reembolsos.
Un timbrado que falla reembolsa su timbre automáticamente; verás el cargo y el abono como dos movimientos.
Paquetes disponibles
GET /api/authenticated/billing/packages
No lleva organización en la URL: es una lista de precios global. Requiere una API key válida, sin scope específico.
{
"packages": [
{
"id": "clxpk1…",
"slug": "estandar",
"label": "Estándar",
"quantity": 500,
"priceMxnCents": 45000,
"unitPriceMxnCents": 90,
"isPopular": true
}
]
}
Los precios vienen en centavos de peso: 45000 son $450.00 MXN.
Quedarse sin timbres
Un timbrado sin saldo responde:
{
"error": "INSUFFICIENT_TIMBRES",
"code": "INSUFFICIENT_TIMBRES",
"requestId": "8de1…",
"required": 1
}
Con HTTP 402. No reintentes: reintentar no crea saldo. Lo correcto es
detener la cola y enseñarle al usuario un enlace a la sección de facturación de
Facty para que compre.
Un patrón que vale la pena
Antes de una corrida grande —una nómina quincenal, un lote de facturación mensual— compara el saldo contra lo que vas a emitir:
saldo = get("/billing/balance")["balance"]
if saldo < len(recibos):
raise NeedsTimbres(f"Se necesitan {len(recibos)} timbres y hay {saldo}.")
Es mucho mejor avisar antes de empezar que dejar la nómina timbrada a la mitad.
Y en el flujo normal, timbresRemaining viene en la respuesta de cada timbrado
—sin necesidad de un GET extra— así que puedes avisar cuando cruce un umbral:
res = post("/invoices", body=payload)
if res.get("timbresRemaining") is not None and res["timbresRemaining"] < 50:
notify("Quedan pocos timbres en Facty.")
Recarga automática
Desde Facty (Configuración → Facturación) el usuario puede activar la recarga automática: cuando el saldo baja de un umbral, se compra un paquete con el método de pago guardado. Si tu integración factura en volumen, vale la pena sugerírselo.