Documentación API
La API REST de Timbrify te permite integrar facturación electrónica CFDI 4.0 en cualquier sistema. Todas las peticiones van a https://api.timbrify.com/v1 y devuelven JSON.
https://sandbox.timbrify.com/v1 para probar sin generar CFDIs reales. Las API Keys de sandbox empiezan con tbf_test_.Instalación rápida
# npm
npm install @timbrify/sdk
# yarn
yarn add @timbrify/sdk
# Python
pip install timbrifyAutenticación
Timbrify usa API Keys en el header Authorization: Bearer <key>. Genera tus keys desde el panel de tu comercio en Configuración → API Keys.
// TypeScript / Node.js
const response = await fetch('https://api.timbrify.com/v1/invoices', {
headers: {
'Authorization': `Bearer ${process.env.TIMBRIFY_API_KEY}`,
'Content-Type': 'application/json',
},
});Scopes de API Key
Cada API Key puede limitarse a scopes específicos para seguir el principio de mínimo privilegio. Los scopes disponibles son:
| Scope | Descripción |
|---|---|
| invoices:write | Crear y timbrar CFDIs |
| invoices:read | Consultar facturas y descargar PDF/XML |
| invoices:cancel | Cancelar CFDIs ante el SAT |
| webhooks:manage | Crear y editar endpoints de webhook |
| merchants:read | Consultar datos del comercio y sucursales |
Timbrar CFDI
Genera y timbra un Comprobante Fiscal Digital por Internet (CFDI) versión 4.0. El CFDI queda sellado por el PAC autorizado (vía Facturapi) y listo para uso fiscal de forma instantánea.
Parámetros del cuerpo
| Parámetro | Tipo | Req. | Descripción |
|---|---|---|---|
| emisor | object | Sí | Datos del emisor: rfc, nombre, regimenFiscal |
| receptor | object | Sí | Datos del receptor: rfc, nombre, usoCfdi, regimenFiscalReceptor, domicilioFiscal |
| conceptos | array | Sí | Arreglo de conceptos con descripcion, cantidad, valorUnitario, claveProdServ, claveUnidad |
| serie | string | No | Serie de la factura (default: "A") |
| formaPago | string | No | Clave SAT de forma de pago (ej: "03" = transferencia) |
| metodoPago | string | No | "PUE" (pago en una exhibición) o "PPD" (parcialidades) |
| sendEmail | boolean | No | Enviar CFDI al email del receptor (default: true) |
Ejemplo de petición
await client.invoices.stamp({
emisor: {
rfc: 'PMS901231L84',
nombre: 'PEMEX TRANSFORMACION INDUSTRIAL',
regimenFiscal: '601', // General de Ley
},
receptor: {
rfc: 'GOML8902154P3',
nombre: 'LAURA GOMEZ MENDOZA',
usoCfdi: 'G03', // Gastos en general
regimenFiscalReceptor: '605',
domicilioFiscal: '06600',
},
conceptos: [{
descripcion: 'Gasolina Magna',
cantidad: 24.6,
valorUnitario: 17.16, // 17.16 × 24.6 = 422.14
claveProdServ: '15101514',
claveUnidad: 'LTR',
impuestos: {
traslados: [{
base: 422.14,
impuesto: '002', // IVA
tipoFactor: 'Tasa',
tasaOCuota: '0.160000',
importe: 67.54,
}],
},
}],
formaPago: '04',
metodoPago: 'PUE',
});Respuesta
{
"success": true,
"invoice": {
"id": "inv_01HPQR2X4Y7Z",
"uuid": "A4F2E918-3D1C-4B2A-9E87-F1234567890A",
"folio": "TBF-00482",
"serie": "A",
"status": "stamped",
"total": 489.68,
"subtotal": 422.14,
"iva": 67.54,
"pac": "facturama",
"stamped_at": "2026-02-23T10:30:00.000Z",
"pdf_url": "https://cdn.timbrify.com/pdf/A4F2E918.pdf",
"xml_url": "https://cdn.timbrify.com/xml/A4F2E918.xml"
}
}Manejo de errores
Timbrify usa códigos HTTP estándar. Los errores devuelven un objeto JSON con code y message descriptivos.
| HTTP | Código | Descripción |
|---|---|---|
| 200 | — | Operación exitosa |
| 400 | INVALID_RFC | El RFC del receptor no existe o está cancelado en el SAT |
| 400 | INVALID_CFDI | Error en la estructura del XML (parámetros inválidos) |
| 401 | UNAUTHORIZED | API Key inválida o expirada |
| 402 | QUOTA_EXCEEDED | Límite mensual de CFDIs alcanzado |
| 429 | RATE_LIMITED | Demasiadas peticiones. Ver Rate limits |
| 503 | PAC_UNAVAILABLE | PAC no disponible. Reintentar en 30s |
Webhooks
Timbrify envía eventos HTTP POST a tu endpoint cuando ocurren cambios en facturas. Todos los webhooks incluyen firma HMAC-SHA256 para verificación.
Eventos disponibles
| Evento | Descripción |
|---|---|
| invoice.stamped | CFDI timbrado exitosamente |
| invoice.cancelled | CFDI cancelado en el SAT |
| invoice.email_sent | Email enviado al receptor |
| invoice.complement_generated | Complemento de pago (REP) generado |
| qr.scanned | QR ticket escaneado por consumidor |
Verificar firma HMAC
import { createHmac } from 'crypto';
export function verifyWebhook(payload: string, signature: string, secret: string) {
const expected = createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expected}` === signature;
}
// En tu endpoint Fastify / Express:
const isValid = verifyWebhook(
req.rawBody,
req.headers['x-timbrify-signature'],
process.env.TIMBRIFY_WEBHOOK_SECRET
);Rate limits
Los límites protegen la estabilidad de la plataforma. Si excedes el límite, recibirás un error 429 RATE_LIMITED.
| Plan | Peticiones/min | Timbrados/min |
|---|---|---|
| Consumidor | 30 | 10 |
| Comercio (Starter) | 120 | 60 |
| Negocio (Pro) | 300 | 120 |
| Enterprise | Custom | Custom |
Los headers X-RateLimit-Remaining y X-RateLimit-Reset se incluyen en cada respuesta.
SDKs
SDKs oficiales con tipado completo, reintentos automáticos y manejo de errores integrado.
| Lenguaje | Paquete | Instalación |
|---|---|---|
| TypeScript / Node.js | @timbrify/sdk | npm install @timbrify/sdk |
| Python | timbrify | pip install timbrify |
| PHP | timbrify/sdk | composer require timbrify/sdk |
Todos los SDKs soportan reintentos automáticos en errores 5xx, rate limit con backoff exponencial, y validación de scopes antes del envío.