# Cambios

> Lo nuevo en la API, los SDKs y el CLI de Fiscalisto, del más reciente al más antiguo. Nada de lo que ya funciona deja de funcionar sin aviso.

La API se versiona por fecha: cada respuesta dice en el encabezado `Fiscalisto-Version` en qué versión se escribió, y hoy hay una sola, `2026-10-24`. Lo que agregamos (rutas, campos, eventos) llega en la versión que ya usa, sin cambiar nada de lo que existe. Un cambio que no sea compatible será una versión nueva, anunciada aquí y por correo, y su cuenta se queda en la suya hasta que usted la mueva. Ver [Versiones](https://fiscalisto.com/docs/api/versiones).

Reciba cada cambio por correo en [Avisos por correo](/avisos?tema=cambios), o en su lector con el RSS `https://fiscalisto.com/docs/api/cambios.rss`. Las fallas del servicio tienen los suyos en [Estado del servicio](/estado).

## 27 de octubre de 2026

- **La API está abierta.** Cualquier persona puede crear su cuenta API desde el selector de empresa (o desde [API de facturación](/api-facturacion)), timbrar en pruebas sin costo y pasar a producción con sus emisores y sus paquetes de timbres. Su cuenta empieza con 20 timbres de producción de regalo. Ver [Pruebas y producción](https://fiscalisto.com/docs/api/pruebas-y-produccion).
- **Todas las constancias de retenciones con complemento.** `POST /v1/retentions` emite ahora las claves 17 y 19 a 24 con su complemento: `trust_lease` (arrendamiento en fideicomiso), `share_sale` (enajenación de acciones), `prize` (premios), `trust` (fideicomiso no empresarial), `retirement_plan` (planes de retiro 1.1), `mortgage_interest` (intereses hipotecarios) y `financial_derivatives` (operaciones con derivados). Las claves 06 (enajenación de acciones) y 15 (remanente distribuible) ya no piden complemento, como dice el SAT. En `GET /v1/sat_catalogs/retention_codes` solo la 26 queda con `supported: false`. En los SDKs 0.1.9. Ver [Retenciones](https://fiscalisto.com/docs/api/retenciones).
- **Lo declarado sin CFDI aparte.** Cada cruce de `GET /v1/accounting/cross_checks` (y de `/cfdi`) trae `declared_without_cfdi`: lo que la declaración dice que llegó sin factura (ingresos nominales adicionales en `isr_income`, IVA al 16% de cobros sin factura en `vat_charged`). Solo el resto se compara con sus CFDI, así que un hotel que declara cobros sin factura ya no sale con `differs`. En los SDKs 0.1.8. Ver [Contabilidad](https://fiscalisto.com/docs/api/contabilidad).
- **`vat_withheld` cuenta las constancias de retenciones.** El IVA que le retuvieron en el cruce (`GET /v1/accounting/cross_checks`) suma también el de las constancias de retenciones que el emisor recibió, como las de las plataformas de hospedaje, en el mes en que se emitió (como se declara). El ISR de esas constancias se acredita en el ISR provisional según el régimen. En `GET /v1/accounting/cross_checks/cfdi` aparecen con `type` `withholding_certificate`. Ver [Contabilidad](https://fiscalisto.com/docs/api/contabilidad#los-cfdi-de-una-cifra). En los SDKs 0.1.7, `type` del CFDI del cruce incluye `withholding_certificate`.
- **Documentación.** Cada evento tiene su página con el evento completo tal como llega a su webhook, y [Tipos de evento](https://fiscalisto.com/docs/api/webhooks#tipos-de-evento) aparece arriba de Webhooks y Eventos en la referencia, con cada evento enlazado a su página. **Mandar evento de prueba** (`POST /v1/webhook_endpoints/{id}/test`) manda el objeto de cada evento (una cotización, un ticket, una descarga…) en lugar de una factura. La referencia usa todo el ancho de la pantalla, con el código y la respuesta en una columna más ancha, y **Probar** ya no se abre fuera de la pantalla.
- **Listo para agentes de código.** Nueva página [Fiscalisto para agentes de IA](https://fiscalisto.com/docs/api/agentes): cómo conectar el servidor MCP de la documentación en Claude Code, Cursor, VS Code y Codex, y la guía de integración en una página en [`/docs/api/SKILL.md`](https://fiscalisto.com/docs/api/SKILL.md) (una Agent Skill). El MCP tiene `get_started` (esa guía), busca también en inglés («create invoice», «verify webhook signature»), `describe_operation` acepta el método del SDK (`invoices.create`) o palabras, `list_operations` acepta la sección en inglés y `explain_error` sugiere el código parecido. `describe_operation` nombra el objeto que contesta en lugar de repetir sus campos (`full: true` los incluye). `llms-full.txt` escribe los campos de cada objeto una sola vez y pasa de 1.7 a 1.1 MB.
- **SDKs 0.1.6:** `fiscalisto init --agents` deja además la guía en `.claude/skills/fiscalisto/SKILL.md`, y la sección de `AGENTS.md` apunta al MCP, al servidor de prueba y a verificar webhooks. Cada README tiene «Con agentes de IA».
- **Cumplimiento SAT en la API.** Con la e.firma guardada del emisor, `POST /v1/issuers/{id}/compliance_opinion/refresh`, `…/tax_status_certificate/refresh` y `…/sat_mailbox/refresh` traen del SAT la opinión de cumplimiento (32-D), la constancia de situación fiscal y los avisos del buzón tributario (1 timbre por consulta en producción, cada uno una vez cada 10 minutos; regresa si el SAT no contesta). Se leen gratis en `GET /v1/issuers/{id}/compliance_opinion` y `/tax_status_certificate` (con `/pdf`) y en `GET /v1/sat_mailbox_messages`. Nuevo `GET /v1/sat_findings`: los hallazgos de las facturas del emisor por tipo, sin los revisados. En pruebas se inventan al instante. Ver [Cumplimiento SAT](https://fiscalisto.com/docs/api/cumplimiento-sat).
- **SDKs 0.1.5:** opinión, constancia y buzón (`issuers.complianceOpinion`, `satMailboxMessages`, `satFindings`…), sucursales (`branches`), almacenes (`warehouses`), existencias (`products.stock`, `warehouses.stock`), kárdex (`stockMovements`) y ajustes (`stockAdjustments`); `branch` y `warehouse` en las facturas. La 0.1.4 trajo los filtros de eventos (`type` con comodín, `delivery_success`) y `fiscalisto events list --failed` en el CLI.
- **Inventario en la API.** Los productos tienen `track_stock`, `cost`, `barcode` y `min_stock`; nuevas rutas `/v1/warehouses` (con `/stock`), `GET /v1/products/{id}/stock`, `/v1/stock_movements` (el kárdex) y `/v1/stock_adjustments`. Una factura con `product` saca sus existencias del almacén de su sucursal, o del que diga `warehouse`, y cada concepto de la factura dice su `product`. Error nuevo: `inventory_refused`. Ver [Inventario](https://fiscalisto.com/docs/api/inventario).
- **Sucursales en la API.** Nuevas rutas `/v1/branches` para crear, ver, cambiar, archivar y borrar las sucursales de un emisor (cada una con su código postal, su dirección para el PDF y sus series), y `branch` en `POST /v1/invoices`: la factura sale con el `LugarExpedicion`, la hora y la serie de esa sucursal, y sus pagos y notas de crédito la siguen. El objeto de factura dice su `branch`. Errores nuevos: `branch_exists` y `branch_has_invoices`. Ver [Sucursales](https://fiscalisto.com/docs/api/sucursales).
- **Errores más claros.** `stamp_rate_limit` dice cuánto esperar y que repita con la misma `Idempotency-Key`; `idempotency_key_missing` ya no habla solo de facturas (también nómina, retenciones y lotes); un webhook con `http://` o `localhost` le sugiere `fiscalisto listen`.
- **CLI.** `--help` funciona en cada comando (`fiscalisto invoices create --help`); `invoices create` con `--customer` pide `--payment-form` en lugar del error de la API; `issuers get` se lee sin `--json`; los montos en dólares ya no repiten la moneda, y los complementos de pago muestran lo que pagaron en lugar de $0.00.
- **Panel.** Un webhook cuya última entrega falló dice **Con errores**, y los complementos de pago muestran lo que pagaron.
- **`GET /v1/events` filtra como Stripe.** `type` acepta un comodín por recurso (`invoice.*`, `retention.*`) y el nuevo `delivery_success=false` deja los eventos que algún webhook no recibió (`true`, los que llegaron a todos). Ver [Webhooks](https://fiscalisto.com/docs/api/webhooks#reintentos).
- **Reenviar es un intento aparte.** Un reenvío (en el panel) se manda una vez, ahora, sin empezar otra ronda de reintentos; si llega, los reintentos automáticos que faltaban ya no se mandan.
- **Webhooks en el panel, como Stripe.** **Desarrolladores › Webhooks** muestra la lista y el webhook elegido con sus últimos 7 días, sus entregas (filtrables y con enlace propio) y cada intento; **Nuevo webhook** elige primero los eventos, por recurso y con un ejemplo de cada uno. Un webhook de pruebas ya no pide su contraseña para verlo o agregarlo. El Workbench cambia de alto, se abre en pantalla completa, copia un enlace a lo que está viendo y filtra solicitudes (método, ruta, código de error) y eventos.

## 26 de octubre de 2026

- **Nuevos precios de los paquetes grandes.** 10,000 timbres: $4,790 + IVA ($5,556.40 con IVA); 50,000: $22,900 + IVA ($26,564 con IVA); 100,000: $41,900 + IVA ($48,604 con IVA). Los de 500 y 2,000 no cambian, y los paquetes ya comprados conservan sus timbres. Ver **Desarrolladores › Timbres**.
- **Los paquetes de 50,000 y 100,000 timbres se pagan solo por transferencia (SPEI).** Los de 500, 2,000 y 10,000 siguen con tarjeta, OXXO o transferencia, y la **Recarga automática** con tarjeta compra paquetes de hasta 10,000.
- **Nuevo `GET /v1/accounting/cross_checks/cfdi`**: los CFDI que forman lo facturado de una cifra del cruce de un mes (`month`, `key`, también las retenciones de nómina y a proveedores), con lo que aporta cada uno y el ajuste de Impuestos, para ver por qué una cifra `differs`. Ver [Contabilidad](https://fiscalisto.com/docs/api/contabilidad#los-cfdi-de-una-cifra).
- **Facturas en pesos colombianos, florines, rupias y dinares iraquíes con los decimales de c_Moneda.** `COP`, `HUF`, `IDR`, `IRR`, `LBP` y otras se timbraban sin decimales (y `IQD` con 0 en vez de 3), y el PAC las rechazaba por el rango de los impuestos; ahora van con los decimales del catálogo del SAT.
- **El motivo de cancelación `04` es solo para una factura global** (una venta incluida se facturó después a nombre del cliente). En otra factura contesta `cancellation_failed`.
- **Cancelar una constancia con el motivo `01`** revisa que `substitution` sea otra constancia vigente del mismo emisor.
- **«Probar» en la referencia sin llave** funciona solo para quien administra las llaves de la cuenta API (como el panel), y nunca cambia la versión de la API de la cuenta.
- **Guías nuevas:** [Nómina](https://fiscalisto.com/docs/api/nomina) y [Constancias de retenciones](https://fiscalisto.com/docs/api/retenciones). La documentación tiene buscador, y cada operación de la referencia dice qué hace.
- **SDKs 0.1.3:** `fiscalisto init` también deja listo un proyecto de Go, .NET o Java, y `fiscalisto docs` lee la guía de la API para agentes.
- **`GET /v1/quotes?status=` ya no corta la lista antes de tiempo.** Con muchas cotizaciones, solo revisaba las 500 más recientes y contestaba `has_more: false` aunque hubiera más con ese estado; ahora sigue hasta llenar la página.
- **`GET /v1/issuers` con una llave limitada a algunos emisores** trae páginas completas; antes filtraba después de leer la página y podía contestar una lista vacía con `has_more: true`.
- **Dos `POST /v1/retentions/:id/send` a la vez ya no mandan la constancia dos veces**: el segundo contesta `email_failed` («se está enviando»).
- **Una constancia de retenciones que el SAT ya canceló siempre queda cancelada**, aunque falle el registro interno del uso.
- **Los números de las pólizas (`D-202610-00001`) ya no cambian entre consultas** cuando dos son del mismo día y tipo. Un CFDI del mes que llega después sí recorre los que siguen: para relacionarlas use `uuid`.
- **`summary` lee las declaraciones de RESICO de personas físicas** (ingresos percibidos, impuesto mensual, ISR retenido, IVA acreditable del periodo) y más cifras de personas morales tal como las imprime el SAT (IVA retenido, actos al 0% y exentos). Las declaraciones ya guardadas se vuelven a leer de su PDF en la siguiente consulta, sin ir al SAT.
- **El cruce con las retenciones.** `GET /v1/accounting/cross_checks` también compara, en los meses en que hubo, el ISR retenido por salarios contra los recibos de nómina (`isr_withheld_salaries`) y el ISR e IVA retenidos a proveedores contra las facturas recibidas (`isr_withheld_suppliers`, `vat_withheld_suppliers`). Ver [Contabilidad](https://fiscalisto.com/docs/api/contabilidad).
- **Un campo obligatorio vacío dice «no puede estar vacío»** (antes «debe tener al menos 1 caracteres»).
- **Los webhooks ya no se pierden cuando llegan muchos cambios juntos.** Más de 12 eventos a la vez (un lote grande, por ejemplo) no se guardaban, y con muchos destinos que fallaban se dejaban de reintentar las entregas.
- **Las listas con `limit=100` ya no fallan con muchos registros.** `GET /v1/invoices?limit=100` contestaba `500` en cuanto el emisor tenía más de 100 facturas (y lo mismo otras listas y los eventos con muchos objetos); ahora contesta la página completa. Las páginas siguientes (`starting_after`) tardan lo mismo al principio que al final de la lista.
- **Con `Accept-Language: en`, los errores de `limit` y de las fechas (`created_gte`…) dicen en inglés exactamente qué falló**, en vez del mensaje general del código.
- **`GET /v1/sat_catalogs/product_keys` y `unit_keys` ya no contestan `catalog_unavailable` por un fallo de red**: el catálogo se lee de los archivos de la propia aplicación.
- **Las cifras de cada declaración con nombres fijos.** Cada `SatDeclaration` trae `summary`: sus obligaciones (`isr`, `vat`, `isr_salaries`…) con cifras que no cambian de nombre aunque el SAT cambie su formato (`tax_base`, `creditable`, `withheld`, `to_pay`…), `null` donde no se pudo leer. Ver [Las cifras con nombres fijos](https://fiscalisto.com/docs/api/declaraciones-del-sat#las-cifras-con-nombres-fijos).
- **El año de declaraciones mes por mes.** `GET /v1/sat_declarations/calendar` dice por mes qué obligaciones se presentaron, cuáles faltan y cuándo vencen las que siguen. `GET /v1/sat_declarations` filtra también por `month` y `type`.
- **Webhooks de declaraciones:** `sat_declaration.created` al encontrar una nueva y `sat_declaration.updated` al llegar sus archivos o cifras.
- **Contabilidad completa.** Las pólizas (`GET /v1/accounting/journal_entries`) ahora incluyen los pagos de los complementos, la nómina y la depreciación de los activos fijos, y traen `type` (`invoice`, `payment_received`, `payment_made`, `payroll` o `depreciation`). Un PUE se registra cobrado o pagado según su forma de pago. `uuid` y `tax_id` son `null` en la póliza de depreciación. Nuevo `GET /v1/accounting/financial_statements` con el estado de resultados y el balance general del mes, y `GET /v1/accounting/cross_checks`, que compara cada mes lo declarado al SAT con lo facturado. Ver [Contabilidad](https://fiscalisto.com/docs/api/contabilidad).
- **`{periodo}` en una factura recurrente sigue su frecuencia.** En una semanal dice la semana que cubre (`2 al 8 de noviembre`) y en una de varios meses todos sus meses (`1 de noviembre al 31 de diciembre`); antes siempre decía el mes de la fecha. En las mensuales no cambia.
- **Los errores de los campos de una factura llegan en español y con el nombre de la API.** Antes algunos llegaban en inglés (`Invalid input: expected number, received string`, `Too big: expected array to have <=200 items`); ahora dicen, por ejemplo, `items.0.quantity: debe ser un número`, y los campos con formato fijo dicen cuál (`date` es `AAAA-MM-DDTHH:MM:SS` en hora de la Ciudad de México, `product_key` son 8 dígitos).
- **`currency` se revisa contra c_Moneda.** Un código que no existe (`XYZ`) contesta `400` con `param: "currency"`, uno en minúsculas (`usd`) se guarda en mayúsculas, y `exchange_rate` distinto de 1 en pesos (MXN) contesta `400`; antes se timbraba tal cual.
- **`send_email: true` sin correo contesta `400` `parameter_missing`** con `param: "customer.email"`, como ya hacían los pagos. Antes la factura se timbraba y no se mandaba a nadie. Lo mismo al crear una factura recurrente, donde `send_email` es `true` por omisión: sin correo, mande `invoice.customer.email` o `send_email: false`.
- **`metadata` se revisa también en los anticipos**, y un error en ella dice la llave (`metadata.pedido`).
- **Constancias de retenciones:** un periodo que termina después del mes en curso contesta `retention_invalid` (la constancia es de lo ya retenido); `dividends`, `interest` y `foreign_payment` con otra clave (`code` 14, 16 y 18) contestan `400` en vez de no timbrarse, y `totals.exempt` mayor que `totals.operation` dice eso en vez de «los montos no pueden ser negativos».
- **Recibos de nómina:** una fecha que no existe (`2026-02-30`) contesta `400` con `param` (antes se leía como el 2 de marzo); un periodo más largo que la periodicidad del empleado (un mes en una nómina semanal) y un periodo que se cruza con otro recibo vigente del empleado contestan `payroll_invalid`, para no pagar dos veces los mismos días. Pedir el mismo periodo otra vez sigue contestando el recibo que ya tiene. Los errores de empleados dicen `end_date`, `start_date` o `integrated_daily_salary` cuando son de ese campo.
- **Descargas del SAT:** la misma descarga pedida otra vez mientras el SAT trabaja en ella contesta esa misma, sin cobrar otro timbre ni gastar las solicitudes idénticas que acepta el SAT. `counterparty_tax_id` debe ser un RFC, y en `GET /v1/sat_invoices` `date_gte` después de `date_lte` contesta `400` en vez de una lista vacía.
- **Fechas que no existen.** Un día como `2026-02-30` contesta `400` («no es un día del calendario») en todos los campos y filtros de fecha; antes algunos lo leían como el 2 de marzo.
- **Un webhook por dirección.** Crear un endpoint con la `url` de otro (o cambiarle la `url` a la de otro) contesta `400` `endpoint_exists` con el id del que ya la tiene; antes había dos y cada evento llegaba dos veces, por ejemplo al correr dos veces un script de instalación.
- **Claves del SAT revisadas antes del PAC.** Un `product_key` o `unit_key` que no está en c_ClaveProdServ o c_ClaveUnidad contesta `400` con su campo (`items.1.product_key` en una factura), en productos y en facturas; un producto acepta `unit_price` con hasta 6 decimales, como el CFDI, y con `unit_key` sin `unit_name` toma el nombre del catálogo.
- **Clientes revisados al guardarlos.** Un régimen que no es del tipo de persona del RFC (601 a un RFC de 13 caracteres), un régimen o código postal que no está en el catálogo, o un `use` que no va con el régimen contestan `400` con su campo, en vez de guardarse y fallar al facturar. Cambiar solo el correo de un cliente se guarda como antes.
- **SDKs 0.1.2** en los siete paquetes (npm `fiscalisto` y `@fiscalisto/react`, PyPI, Packagist, NuGet, Go y Maven Central), con todo lo de esta fecha y del 25 de octubre: los códigos de error nuevos (como `endpoint_exists`), versiones por fecha, `expand[]` y errores en inglés. Desde ahora cada SDK se publica solo al cambiar la API.
- **Un lote no acepta la misma `reference` dos veces**, para que un pedido no se facture doble: contesta `400` con `param` en la repetida y dice en qué factura del lote ya iba.
- **Una factura recurrente que no se pudo timbrar dice por qué con el código correcto:** `invoice_invalid` cuando Fiscalisto la detuvo antes del PAC (un cliente borrado del catálogo, el plan), `insufficient_balance` sin timbres, e `invoice_rejected` solo cuando la rechazó el PAC o el SAT.
- **Declaraciones del SAT.** `POST /v1/sat_declarations/refresh` entra al SAT con la e.firma guardada del emisor y trae las declaraciones que presentó (provisionales, la anual de persona moral y las de Declaraciones y pagos), con su PDF, su acuse, sus cifras y el coeficiente de utilidad. En producción usa 1 timbre por consulta, una vez cada 10 minutos por emisor; listarlas con `GET /v1/sat_declarations` y bajar sus archivos es gratis. En pruebas trae declaraciones de ejemplo al instante. Ver [Declaraciones del SAT](https://fiscalisto.com/docs/api/declaraciones-del-sat).
- **Varias notas de crédito o pagos a la misma factura a la vez se atienden en orden.** Antes, las que llegaban mientras otra se timbraba recibían `409` y un mensaje que culpaba a la `Idempotency-Key`; ahora esperan su turno (hasta 12 segundos) y se revisan contra el saldo que dejó la anterior.
- **`invoice_invalid` para las reglas que Fiscalisto revisa antes del PAC.** Un pago que excede el saldo, una nota mayor que lo que queda o una factura cancelada contestaban `invoice_rejected`, que es para lo que rechaza el PAC o el SAT.
- **Por qué no se puede pagar una factura.** En vez de «no está abierta para este cliente», el error dice si está cancelada, si es PUE, si es de otro cliente o si ya está pagada.
- **La misma solicitud escrita de otra forma es la misma.** Con una `Idempotency-Key`, el cuerpo se compara como JSON y no byte por byte: el curl con sangría de la guía, un SDK compacto, el `json.dumps` de Python o los campos en otro orden ya no contestan `idempotency_key_reused`. Los parámetros de la URL también se comparan sin importar su orden.
- **Una solicitud repetida contesta con el mismo status.** Repetir un timbrado ya hecho contesta `201` (antes `200`), un lote `202` y una cotización ya facturada `201`, siempre con `idempotent-replayed: true` y con los mismos avisos (`warnings`) que la primera vez.
- **Errores más claros.** Un campo obligatorio que falta dice `parameter_missing` aunque acepte varias formas, `metadata` con otro tipo dice «debe ser un objeto», y un valor enorme (un id de 5,000 caracteres) ya no regresa completo en el mensaje.
- **Dos cambios al mismo objeto a la vez ya no se pisan.** Dos actualizaciones del mismo producto o cliente al mismo tiempo (una cambia `sku`, otra `unit_price`) guardaban solo una; ahora la segunda espera a la primera y se guardan las dos. Si espera más de 15 segundos contesta `409` `request_in_progress`.
- **Un parámetro de la URL que no existe se rechaza.** `GET /v1/invoices?statuss=valid` (con una s de más) contestaba la lista completa sin filtrar; ahora contesta `400` `parameter_unknown` con el parámetro y los que sí acepta ese endpoint.
- **Los entornos de prueba** no pasan de 25 aunque se creen muchos a la vez.
- **`customer` en las listas acepta el id del cliente.** `GET /v1/invoices`, `/v1/receivables` y `/v1/advances` filtran por `customer=RFC` o `customer=cus_…`, el RFC en mayúsculas o minúsculas. Antes un `cus_…` contestaba una lista vacía, y un valor que no es RFC ni cliente ahora contesta `400` en vez de una lista vacía.
- **Clientes, productos y empleados traen `created_at`**, como los demás objetos. En los clientes y productos de antes de hoy es la fecha de su último cambio. **La lista de empleados** sale de la más nueva a la más vieja, como las demás (antes salía en un orden que parecía al azar).
- **Un SKU es de un solo producto.** Crear o cambiar un producto con el SKU de otro contesta `400` `customer_exists` con `param: "sku"` y el nombre del que lo tiene, como ya decía la referencia de errores; antes se guardaban dos productos con el mismo SKU.
- **Repetir un timbrado ya hecho varias veces a la vez contesta la factura a todas.** Antes, mientras una repetición contestaba, las demás que llegaban en ese momento recibían `409` `request_in_progress`.
- **Pruebas acepta 100 solicitudes cada 10 segundos, como producción** (antes 25), para que una suite de pruebas en paralelo no se tope antes con el límite. Los timbrados de prueba siguen con su propio límite.
- **El texto que contesta la factura es el que se timbró.** Saltos de línea, tabuladores y espacios de más en descripciones y nombres se guardan como un espacio, y los caracteres de control se quitan, como ya salían en el XML; antes el JSON y el PDF los conservaban.
- **`npx fiscalisto mock`** compara la `Idempotency-Key` igual que la API y contesta `409` cuando la llave ya se usó con otro cuerpo.

## 25 de octubre de 2026

- **Cancelar ya no usa timbres.** Cancelar facturas y constancias de retenciones es gratis, en la API y en la app.
- **Las descargas del SAT pagan según su tamaño.** En producción, una descarga usa 1 timbre por cada 100 CFDI que trae (al menos 1): el primero al pedirla y los demás cuando el SAT dice cuántos tiene, antes de descargarlos. Sin timbres suficientes termina en `failed`. Ver [Límites](https://fiscalisto.com/docs/api/limites#lo-que-usa-timbres-sin-timbrar).
- **Paquete de 100,000 timbres.** $36,900 + IVA ($42,804 con IVA), unos 37 centavos más IVA por timbre, en **Desarrolladores › Timbres**.
- **Revisar RFC, consultar constancias y descargar del SAT usan timbres.** En producción, revisar RFC en las listas del SAT y consultar constancias usan 1 timbre por cada 10, y cada descarga pedida al SAT usa 1. Sin timbres, `402 insufficient_balance`. En pruebas sigue sin costo. Ver [Límites](https://fiscalisto.com/docs/api/limites#lo-que-usa-timbres-sin-timbrar).
- **Precio abierto e impuestos locales en productos.** Los productos aceptan `open_price` (sin precio fijo: cada concepto con él manda su `unit_price`, o la factura se rechaza con `items.N.unit_price`) y `local_taxes`, como el ISH de hospedaje. Una factura con esos productos y sin `local_taxes` los agrega sola, calculados sobre los conceptos de cada producto. Ver [Complementos](https://fiscalisto.com/docs/api/complementos#ejemplo-hospedaje-con-ish).
- **Workbench.** En cualquier página de Desarrolladores, la tecla `` ` `` abre un panel con el resumen de la cuenta, las solicitudes, los eventos, los webhooks, un inspector de objetos y un shell que llama a la API en pruebas, sin dejar la página.
- **Inspector de solicitudes.** En **Desarrolladores › Solicitudes**, cada solicitud dice su versión de la API y se ve **Como código** en curl o en cualquiera de los seis SDKs; las repetidas con la misma `Idempotency-Key` dicen **Repetida** y aparecen junto a la original.
- **La API sin internet.** `npx fiscalisto mock` contesta cada ruta en su computadora con la forma de la API, guarda en memoria lo que crea y repite lo mismo con la misma `Idempotency-Key`; en las pruebas de Node, `createMock()` de `fiscalisto/mock`. Ver [CLI](https://fiscalisto.com/docs/api/cli#la-api-sin-internet).
- **Errores en inglés.** Con `Accept-Language: en` (o la opción `language` de los SDKs) los mensajes de error llegan en inglés, con el original en `message_es` cuando el inglés es general. Ver [Errores](https://fiscalisto.com/docs/api/errores#en-inglés).
- **Expandir objetos.** Con `expand[]=issuer` (o `recurring_invoice.last_invoice`, `data.invoice`…) un id llega como el objeto completo en la misma respuesta, en `GET` y en `POST`. En los SDKs de TypeScript, Python y PHP, con la opción `expand`. Ver [Expandir objetos](https://fiscalisto.com/docs/api/expandir).
- **Versiones por fecha.** Cada cuenta queda en la versión de la API del día en que se creó (`api_version` en `GET /v1/account`) y se mueve solo con `POST /v1/account`. Una solicitud puede pedir otra con el encabezado `Fiscalisto-Version`, y cada endpoint de webhooks puede tener la suya. Los seis SDKs mandan la versión para la que se hicieron. Ver [Versiones](https://fiscalisto.com/docs/api/versiones).
- **Relojes de prueba.** `POST /v1/issuers/{id}/test_clock` congela la hora de un emisor de pruebas y `POST /v1/issuers/{id}/test_clock/advance` la adelanta, haciendo día por día lo que habría pasado: facturas recurrentes, cotizaciones que vencen y facturas globales de tickets, con sus webhooks y el evento `test_clock.ready`. Los emisores traen `test_clock`. Ver [Pruebas y producción](https://fiscalisto.com/docs/api/pruebas-y-produccion#adelantar-el-tiempo-con-un-reloj-de-prueba).
- **Idempotency-Key en todo `POST`.** Como en Stripe y Resend: con la misma llave, un reintento de crear un cliente, un webhook, una cotización o una factura recurrente, de mandar un correo o de cualquier otro `POST` contesta lo mismo (`idempotent-replayed: true`) sin hacerlo dos veces, durante 24 horas. Los SDKs, la CLI y los módulos de n8n, Zapier y Make la ponen solos en cada `POST`, así sus reintentos siempre son seguros. Ver [Idempotencia](https://fiscalisto.com/docs/api/idempotencia).
- **Explorador de la API para agentes.** El servidor MCP de la documentación (`https://fiscalisto.com/docs/api/mcp`) agrega `list_operations`, `describe_operation` (con el código del SDK del lenguaje que pida), `describe_object`, `explain_error` y `call_api`, que prueba una solicitud en modo de pruebas con su llave `fk_test_`. Ver [CLI](https://fiscalisto.com/docs/api/cli#la-documentación-en-su-agente).
- **Entornos de prueba.** `POST /v1/sandboxes` le da a cada persona del equipo su propio modo de pruebas: un emisor de pruebas del SAT y una llave `fk_test_` que solo ve sus emisores, facturas, webhooks y eventos, con un reinicio que no toca los de nadie más. Emisores, webhooks y `GET /v1/account` (`key.sandbox`) agregan `sandbox`. También en **Desarrolladores › Llaves**. Ver [Pruebas y producción](https://fiscalisto.com/docs/api/pruebas-y-produccion#un-entorno-de-prueba-para-cada-persona).
- **Contabilidad.** `GET /v1/accounting/journal_entries` da una póliza por cada CFDI del mes, `GET /v1/accounting/trial_balance` la balanza y `GET /v1/accounting/accounts` el catálogo con el código agrupador del SAT. `GET /v1/accounting/electronic_accounting` descarga la contabilidad electrónica (catálogo, balanza y, si el SAT las pide, pólizas) lista para el Buzón Tributario, y `GET /v1/accounting/diot/file` el TXT de la DIOT. Ver [Contabilidad](https://fiscalisto.com/docs/api/contabilidad).
- **Tiendas en línea.** `POST /v1/store_connections` conecta una tienda de Shopify o una cuenta de Mercado Libre: cada pedido pagado se vuelve un ticket de autofactura, la liga va en el pedido de Shopify, en Mercado Libre se factura sola con los datos fiscales del comprador y el CFDI se sube al pedido. Un pedido cancelado o reembolsado cancela su ticket. Para WooCommerce, el plugin **Fiscalisto Autofactura**. Ver [Tiendas en línea](https://fiscalisto.com/docs/api/tiendas).
- **Conciliación bancaria.** `POST /v1/bank_transactions` recibe los depósitos de la cuenta del emisor (de la API de su banco o de un estado de cuenta), sin repetir los que ya mandó, y sugiere la factura que pagó cada uno. `POST /v1/bank_transactions/{id}/match` la concilia y la factura queda pagada; una PPD se paga con `POST /v1/payments` y `bank_transaction`, que timbra el complemento y lo concilia. Ver [Conciliación bancaria](https://fiscalisto.com/docs/api/conciliacion-bancaria).
- **Cuentas por cobrar.** Cada factura trae `payment_status`, `amount_due` y `amount_paid`, que bajan con sus complementos de pago y notas de crédito; `GET /v1/receivables` dice cuánto debe cada cliente y `GET /v1/invoices?payment_status=open` lista lo pendiente. Una PUE con `paid_later` se marca con `POST /v1/invoices/{id}/mark_paid`. Eventos `invoice.paid` e `invoice.partially_paid`. Ver [Cuentas por cobrar](https://fiscalisto.com/docs/api/cuentas-por-cobrar).
- **Cotizaciones.** `POST /v1/quotes` hace una cotización con los conceptos de una factura, para un cliente de su catálogo o alguien que aún no le da sus datos fiscales. Su cliente la ve, la acepta, pide cambios o la rechaza en una liga (eventos `quote.viewed`, `quote.accepted`, `quote.changes_requested` y `quote.rejected`); con `auto_invoice` la factura se timbra sola al aceptarla, o con `POST /v1/quotes/{id}/invoice`. Ver [Cotizaciones](https://fiscalisto.com/docs/api/cotizaciones).
- **Facturas recurrentes.** `POST /v1/recurring_invoices` timbra sola una factura cada mes, semana o día, a la hora que elija, con `{mes}` y `{año}` llenos en cada una y sin repetir nunca un periodo. Cada factura trae `recurring_invoice`; si un periodo no sale llega `recurring_invoice.failed`. Ver [Facturas recurrentes](https://fiscalisto.com/docs/api/facturas-recurrentes).
- **n8n, Zapier y Make.** Conectores para timbrar facturas, registrar tickets, pedir datos fiscales, revisar las listas del SAT y correr flujos con cada evento, sin programar. Ver [n8n, Zapier y Make](https://fiscalisto.com/docs/api/automatizaciones).
- **Autofactura.** `POST /v1/tickets` registra cada venta y su comprador se factura solo con el código y el total, en el portal del emisor o dentro de su página con `fiscalisto.js` o `@fiscalisto/react`; lo que nadie factura entra en la factura global. Eventos `ticket.invoiced` y `ticket.included_in_global`. Ver [Autofactura](https://fiscalisto.com/docs/api/autofactura).
- **Equipo de la cuenta API.** Roles para desarrolladores (**Desarrollador**, **Solo lectura**) y **Desarrolladores › Actividad**: quién creó o cambió llaves, webhooks y emisores, y cuándo.
- **Límite en cada respuesta.** El encabezado `RateLimit-Policy` dice cuántas solicitudes acepta su cuenta cada 10 segundos. En **Desarrolladores › Llaves** cada llave muestra sus solicitudes y errores de los últimos 7 días, y **Solicitudes** se filtra por llave. Ver [Límites](https://fiscalisto.com/docs/api/limites).
- **Reiniciar los datos de prueba.** `POST /v1/test_data/reset` deja el modo de pruebas como nuevo, con 3 clientes y 3 productos de ejemplo si quiere; también en **Desarrolladores › Inicio**. Ver [Pruebas y producción](https://fiscalisto.com/docs/api/pruebas-y-produccion#empezar-de-cero).
- **Descargas del SAT.** `POST /v1/sat_downloads` le pide al SAT las facturas que un emisor recibió o emitió en un periodo, con la e.firma que guarda con `keep_for_downloads`; al terminar llega `sat_download.completed` y las facturas quedan en `GET /v1/sat_invoices`, con su XML. En pruebas trae facturas de ejemplo al instante. Ver [Descargas del SAT](https://fiscalisto.com/docs/api/descargas-del-sat).
- **Proyectos de inicio.** Next.js, Laravel, Django y ASP.NET Core: timbran, descargan el PDF y el XML y verifican los webhooks. Ver [SDKs](https://fiscalisto.com/docs/api/sdk#proyectos-de-inicio).
- **Colección para Postman, Bruno e Insomnia.** Todas las rutas con su ejemplo, en `/docs/api/fiscalisto.postman_collection.json`, o con su llave de pruebas al crearla en **Desarrolladores › Llaves**. Ver [SDKs](https://fiscalisto.com/docs/api/sdk#postman-bruno-e-insomnia).
- **SDKs de Go y Java.** `fiscalisto.com/go` (Go 1.23, sin dependencias) y `com.fiscalisto:fiscalisto` (Java 17, con Jackson), generados del mismo OpenAPI: structs y clases para cada campo, `Idempotency-Key` automática, listas que se recorren solas y webhooks verificados. Cada página de la referencia trae su ejemplo en Go y en Java. Ver [SDKs](https://fiscalisto.com/docs/api/sdk).
- **Avisos de cambios y del estado.** Este registro por correo ([suscribirse](/avisos?tema=cambios)) y por RSS (`/docs/api/cambios.rss`). En [Estado del servicio](/estado), **Incidentes recientes**, avisos por correo cuando algo falla y cuando se resuelve, y `/estado.rss`.
- **Llaves de solo lectura y llaves que vencen.** Al crear una llave elija **Permisos** (**Solo lectura** responde `key_read_only` a lo que cambia algo) y **Vence** (30 días a 1 año, con aviso por correo 7 días y 1 día antes). `GET /v1/account` agrega `key.read_only` y `key.expires_at`. Ver [Autenticación](https://fiscalisto.com/docs/api/autenticacion#llaves-de-solo-lectura).
- **Timbres que no se acaban.** El evento `balance.low` y un correo cuando quedan pocos timbres (usted elige cuántos) y otra vez al acabarse, y **Recarga automática** con su tarjeta en **Desarrolladores › Timbres**. `GET /v1/balance` agrega `low_balance_at` y `auto_recharge`. Ver [Pruebas y producción](https://fiscalisto.com/docs/api/pruebas-y-produccion#qué-cuesta-un-timbre).

## 24 de octubre de 2026

- **Depurar desde Solicitudes.** Cada error trae **Cómo arreglarlo**; cada solicitud, **Copiar como curl**, y en pruebas **Repetir en pruebas** con el cuerpo editable. Los mensajes de validación ahora están en español (`items.0.unit_price: debe ser mayor o igual a 0.`).
- **Códigos de error con nombre.** `ErrorCode` en los cuatro SDKs: `error.code === ErrorCode.InvoiceRejected` en vez del texto, con la descripción de cada código en su editor. Ver [SDKs](https://fiscalisto.com/docs/api/sdk#errores).
- **Estado del servicio.** [fiscalisto.com/estado](https://fiscalisto.com/estado) dice si el timbrado, la API y las listas del SAT funcionan ahora y en los últimos 90 días; `https://fiscalisto.com/estado.json` es lo mismo para sus monitores. Ver [Errores](https://fiscalisto.com/docs/api/errores#si-la-api-no-contesta).
- **SDK de .NET.** `dotnet add package Fiscalisto`: una clase para cada objeto y cada solicitud, `await foreach` en las listas y `FiscalistoClient.Webhooks.Verify`. Cada página de la referencia trae su ejemplo en C#. Ver [SDKs](https://fiscalisto.com/docs/api/sdk).
- **Anticipos.** `customer`, `email_cc` y `metadata` de `POST /v1/advances` se documentan como en las facturas, así que los SDKs ya los revisan.
- **Documentación para agentes.** Servidor MCP en `https://fiscalisto.com/docs/api/mcp` y, en cada página, **Copiar como Markdown**, **Abrir en ChatGPT** y **Abrir en Claude**. Si entró a Fiscalisto con su cuenta API, los ejemplos ya traen su llave de pruebas. Ver [CLI](https://fiscalisto.com/docs/api/cli#la-documentación-en-su-agente).
- **Revisión de su integración.** En **Desarrolladores › Inicio**, lo que dicen sus solicitudes de pruebas antes de pasar a producción: Idempotency-Key, rechazos del SAT y webhooks.
- **Alta de emisores por liga.** `POST /v1/issuers/{id}/onboarding_links` da una página donde su cliente sube su CSD y firma con su e.firma, sin que esos archivos pasen por su plataforma; al terminar llega `issuer.ready`. Ver [Emisores](https://fiscalisto.com/docs/api/emisores#que-su-cliente-suba-sus-archivos).
- **Datos del cliente.** `POST /v1/tax_ids/validate` revisa RFC, nombre, régimen, código postal y uso del CFDI antes de timbrar, y con el idCIF los compara con la constancia en el SAT. `POST /v1/customer_data_requests` crea una liga para que su cliente dé sus datos, con el evento `customer_data_request.completed`. Ver [Datos fiscales del cliente](https://fiscalisto.com/docs/api/datos-del-cliente).
- **CLI.** `npx fiscalisto login` inicia sesión por el navegador, `init` deja el SDK y la llave en su proyecto, `listen` le manda los webhooks a su computadora y `trigger` los provoca. Con `--json`, para agentes. Ver [CLI](https://fiscalisto.com/docs/api/cli).
- **Listas del SAT.** `GET /v1/sat_lists/{tax_id}` y `POST /v1/sat_lists/check` (hasta 1,000 RFC) revisan la 69-B, la 69-B Bis y las del artículo 69. Ver [Listas del SAT](https://fiscalisto.com/docs/api/listas-del-sat).
- **Evento de prueba.** `POST /v1/webhook_endpoints/{id}/test` le manda a un endpoint cualquier evento con un objeto de ejemplo, sin timbrar, y contesta lo que respondió su servidor. Ver [Webhooks](https://fiscalisto.com/docs/api/webhooks#un-evento-de-prueba-sin-timbrar).
- **RFC de prueba.** Cinco RFC que en pruebas provocan cada rechazo común del SAT (nombre, código postal, régimen, uso del CFDI). Ver [Pruebas y producción](https://fiscalisto.com/docs/api/pruebas-y-produccion#provocar-cada-rechazo-del-sat).
- **Probar sin llave.** En la referencia, si entró a Fiscalisto con su cuenta API abierta, **Probar** funciona sin pegar la llave.
- **Panel.** **Desarrolladores** tiene **Facturas** (filtros, PDF, XML y cancelar), **Eventos** (lo que se mandó y cada entrega, con **Reenviar**) y la gráfica de **Uso** de los últimos 30 días.
- **SDKs.** TypeScript, Python y PHP, generados del documento [OpenAPI](https://api.fiscalisto.com/v1/openapi.json). Ver [SDKs](https://fiscalisto.com/docs/api/sdk).
- **Primera versión de la API**: facturas, pagos, notas de crédito, anticipos, nómina, retenciones, lotes, cancelación, emisores, catálogos, webhooks e idempotencia.
