# CLI: facturar desde su terminal

> Inicie sesión por el navegador, deje el SDK listo en su proyecto, timbre, cancele y reciba los webhooks en su computadora con un solo comando. Con --json, para agentes y scripts.

El CLI de Fiscalisto viene en el paquete `fiscalisto` de npm. No hay que instalar nada: corra `npx fiscalisto` en cualquier computadora con Node 20 o más reciente.

```bash
npx fiscalisto login     # se abre el navegador; autorice y vuelva
npx fiscalisto init      # SDK, llave en .env y un ejemplo que timbra
node --env-file=.env fiscalisto-ejemplo.mjs
```

En esos tres pasos su proyecto ya timbra en pruebas: sin copiar llaves y sin leer la referencia antes.

## Iniciar sesión

`fiscalisto login` le muestra un código y abre `fiscalisto.com/cli`. Ahí elija su cuenta API (o cree una), revise que el código sea el mismo que en su terminal y pulse **Autorizar**. El CLI recibe una llave de pruebas nueva, con el nombre de su computadora («CLI · mi-mac»), y la guarda en `~/.config/fiscalisto/config.json`, que solo usted puede leer.

| Comando | Qué hace |
| --- | --- |
| `fiscalisto login` | Llave de pruebas por el navegador |
| `fiscalisto login --live` | Pide también una de producción; necesita la verificación en dos pasos |
| `fiscalisto login --key fk_test_…` | Guarda una llave que ya tiene, sin navegador (servidores, CI) |
| `fiscalisto whoami` | Cuenta, modo, timbres y emisores |
| `fiscalisto logout` | Olvida las llaves en esta computadora |

Las llaves del CLI aparecen en **Desarrolladores › Llaves** como cualquier otra: revóquelas ahí cuando quiera. El código del navegador vence en 10 minutos y sirve una sola vez.

El CLI usa, en este orden: `--api-key`, la variable `FISCALISTO_API_KEY` y la llave guardada. Con `--live` usa la de producción guardada y le pregunta antes de timbrar (`--yes` no pregunta).

## Dejar su proyecto listo

`fiscalisto init` reconoce su proyecto (`package.json`, `pyproject.toml` o `requirements.txt`, `composer.json`, `go.mod`, `pom.xml` o `build.gradle`, un `.csproj`) y:

1. Pone `FISCALISTO_API_KEY` en `.env` y agrega `.env` a `.gitignore`.
2. Instala el [SDK](https://fiscalisto.com/docs/api/sdk) con su gestor (npm, pnpm, yarn, bun, pip, uv, poetry, composer, `go get` o `dotnet add package`) y lo anota en sus dependencias (con pip, en `requirements.txt`). En Java le dice qué dependencia agregar a su `pom.xml` o `build.gradle`.
3. Escribe un ejemplo que timbra una factura de prueba y le dice cómo correrlo.

Con `--lang node|python|php|go|dotnet|java` elige el lenguaje, con `--no-install` no instala nada y con `--agents` agrega a su `AGENTS.md` (o `CLAUDE.md`) una sección de cómo facturar y deja la guía completa en `.claude/skills/fiscalisto/SKILL.md`, para que su agente de código use el SDK, la idempotencia y los [RFC de prueba](https://fiscalisto.com/docs/api/pruebas-y-produccion#provocar-cada-rechazo-del-sat) sin que se lo explique. Vea [Fiscalisto para agentes de IA](https://fiscalisto.com/docs/api/agentes).

## Facturas

```bash
fiscalisto invoices create --example                      # una factura de prueba
fiscalisto invoices create --customer ICV060329BY0 --name "INMOBILIARIA CVA" \
  --regime 601 --zip 33826 --item "Consultoría|80101500|1000"
fiscalisto invoices create --data @factura.json           # el mismo cuerpo que POST /v1/invoices
fiscalisto invoices list --status valid --customer ICV060329BY0
fiscalisto invoices get inv_…
fiscalisto invoices pdf inv_… -o factura.pdf              # también xml; sin -o, inv_….pdf
fiscalisto invoices send inv_… --to cliente@empresa.mx
fiscalisto invoices cancel inv_… --motive 02
```

Cada `create` lleva una [Idempotency-Key](https://fiscalisto.com/docs/api/idempotencia): si se corta la conexión y lo repite con `--idempotency-key`, no se timbra dos veces. Un rechazo del SAT se ve con su código y su explicación, como en la API.

`fiscalisto sat-lists check RFC [RFC…]` revisa uno o varios RFC en las [listas del SAT](https://fiscalisto.com/docs/api/listas-del-sat).

## Webhooks en su computadora

```bash
fiscalisto listen --forward-to http://localhost:3000/webhooks
```

`listen` sigue los eventos de su cuenta y se los manda a su servidor local, firmados igual que los [webhooks](https://fiscalisto.com/docs/api/webhooks) de verdad (`webhook-id`, `webhook-timestamp`, `webhook-signature`). La firma usa un secreto de esta computadora, que el CLI le muestra al empezar y es siempre el mismo: póngalo en `FISCALISTO_WEBHOOK_SECRET` de su app y su verificación funciona sin cambios. Con `--events invoice.stamped,invoice.failed` solo reenvía esos. Si su servidor no contesta (lo está reiniciando), `listen` reintenta cada 3 segundos hasta un minuto, en orden, y no se salta eventos. Lo que `listen` lee cada 2 segundos no llena **Solicitudes** ni la gráfica de **Uso**.

En otra terminal, provoque el evento que quiere probar:

| Comando | Lo que pasa en pruebas |
| --- | --- |
| `fiscalisto trigger invoice.stamped` | Timbra una factura de prueba |
| `fiscalisto trigger invoice.failed` | El SAT la rechaza (con el RFC de prueba `NOM010101FK9`) |
| `fiscalisto trigger invoice.canceled` | Timbra una y la cancela |
| `fiscalisto trigger invoice_batch.completed` | Un lote de dos facturas |

`trigger` solo funciona con llaves de pruebas. Para mandar a un endpoint cualquier otro evento, sin timbrar, use `fiscalisto webhooks test whe_… --type invoice.paid` (es [**Mandar evento de prueba**](https://fiscalisto.com/docs/api/webhooks#un-evento-de-prueba-sin-timbrar)). `fiscalisto webhooks list|create|delete` y `fiscalisto events list|get` hacen lo mismo que el panel.

## Cualquier ruta de la API

```bash
fiscalisto api /v1/account
fiscalisto api POST /v1/customers --data '{"tax_id":"ICV060329BY0","legal_name":"INMOBILIARIA CVA","tax_system":"601","zip":"33826"}'
fiscalisto api /v1/invoices/inv_…/pdf > factura.pdf
```

`fiscalisto issuers list` muestra sus emisores y `fiscalisto issuers get iss_…` uno con su estado. `api` llama cualquier ruta de la [referencia](https://fiscalisto.com/docs/api/referencia/facturas/create-invoice) con su llave. `--data` acepta JSON, `@archivo.json` o `-` (lo lee de la entrada).

## La API sin internet

`fiscalisto mock` levanta en su computadora un servidor que contesta cada ruta como la API, con la misma forma de cada objeto y de cada error, sin internet ni llave real. Sirve para desarrollar en un avión y para las pruebas de su proyecto (en CI, sin red).

```bash
npx fiscalisto mock --port 12111
```

- Acepta cualquier llave `fk_test_` (`fk_test_mock`).
- Lo que crea queda en memoria mientras corre: un cliente creado se lee, se lista, se cambia y se borra. Una factura se crea `valid`, con su PDF y su XML de ejemplo.
- Repetir un `POST` con la misma `Idempotency-Key` contesta lo mismo, como la API.
- No revisa las reglas del SAT ni timbra. Antes de producción, pruebe contra la API con su llave `fk_test_` (el modo de pruebas es gratis).

Apunte su SDK a él con la dirección de la API: `baseUrl` en TypeScript, `base_url` en Python y PHP, `WithBaseURL` en Go, `.baseUrl` en Java y `BaseUrl` en .NET. En las pruebas de Node, sin abrir un puerto:

```ts
import { Fiscalisto } from "fiscalisto";
import { createMock } from "fiscalisto/mock";

const mock = createMock();
const fiscalisto = new Fiscalisto("fk_test_mock", {
  baseUrl: "http://mock",
  fetch: (url, init) => mock.fetch(new Request(url, init)),
});
```

## Para agentes y scripts

Con `--json` cada comando contesta un solo JSON (y `listen` una línea por evento), los errores incluidos: `{"error": {"type", "code", "message", "param"}}`, iguales a los de la API. El CLI sale con código 0 si todo salió bien, 2 si el comando está mal escrito y 1 en cualquier otro error.

```bash
fiscalisto invoices create --example --json | jq -r .uuid
```

### La documentación en su agente

Agregue la documentación como servidor MCP y su agente de código la consulta mientras programa (`get_started`, `search_docs`, `get_page`, `list_pages`), sin llave:

```bash
claude mcp add --transport http fiscalisto-docs https://fiscalisto.com/docs/api/mcp
```

Además de buscar y leer las guías (`search_docs`, `get_page`, `list_pages`), el servidor explora la referencia de la API:

| Herramienta | Qué hace |
| --- | --- |
| `get_started` | La guía de integración completa en una página ([SKILL.md](https://fiscalisto.com/docs/api/SKILL.md)). |
| `list_operations` | Cada operación con su `operationId`, método y ruta, por sección (`tag`). |
| `describe_operation` | Una operación por su `operationId`, su método del SDK (`invoices.create`), «POST /v1/invoices» o en palabras («create invoice»): parámetros, cada campo del cuerpo y de la respuesta, ejemplos y el código con el SDK del `language` que elija (`ts`, `python`, `php`, `csharp`, `go`, `java`). |
| `describe_object` | Los campos de un objeto (`Invoice`, `Event`…) con un ejemplo. |
| `explain_error` | Qué significa un `error.code` y cómo resolverlo. |
| `call_api` | Prueba una solicitud de verdad en modo de pruebas con su llave `fk_test_` (`api_key`) y devuelve el código, el `Request-Id` y el JSON. Nunca acepta una `fk_live_`. |

Así su agente puede leer la ruta, armar el cuerpo, probarlo contra su modo de pruebas y corregirlo con el error antes de escribir el código. La solicitud queda en **Desarrolladores › Solicitudes** con la llave que usó.

En Cursor, Codex, VS Code u otro cliente, use la misma dirección como servidor MCP de tipo HTTP ([cómo, en cada uno](https://fiscalisto.com/docs/api/agentes#conectar-la-documentación-mcp)). Cada página tiene además **Copiar como Markdown**, **Abrir en ChatGPT** y **Abrir en Claude** arriba del título.

`fiscalisto docs` imprime la guía completa para agentes ([llms.txt](https://fiscalisto.com/docs/api/llms.txt)) y `fiscalisto open llaves` (o `panel`, `facturas`, `webhooks`, `eventos`, `docs`) abre esa página del panel.
