> ## Documentation Index
> Fetch the complete documentation index at: https://docs.horizonpay.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Scripting & CI

> Run the CLI in scripts and CI with an API key, JSON output and exit codes.

## Authenticate

In CI, skip `invoice-ai login` and set `INVOICE_AI_API_KEY`:

```bash theme={null}
export INVOICE_AI_API_KEY=inv_live_...
invoice-ai whoami
```

The CLI uses the first key it finds: `--api-key`, then `INVOICE_AI_API_KEY`, then the saved profile. Give a CI key only the scopes the job needs.

## JSON output

Output is a table in a terminal and JSON when piped. Pass `--json` to force JSON, or `--format csv`.

```bash theme={null}
invoice-ai invoices list --status overdue --all --json | jq -r '.data[].number'
```

A single object prints as the object. A list prints as `{ "data": [...], "next_cursor": ... }`. Messages and errors go to stderr, so stdout stays valid JSON.

## No prompts

* `send`, `void`, `delete` and `archive` ask for confirmation. Pass `--yes` to skip it.
* `invoices create` starts a wizard in a terminal. Pass `--no-interactive` with flags such as `--customer` and `--price`.
* When `CI` is set or there's no terminal, the CLI never prompts. A command that needs a prompt exits with code `2`.

## Exit codes

| Code | Meaning |
| - | - |
| `0` | Success |
| `1` | API or runtime error, such as `invalid_state` or a network failure |
| `2` | Usage error, or a prompt was needed without a terminal |
| `3` | Auth error: missing or invalid key (`401`), or a missing scope (`403`) |
| `4` | Rate limited (`429`) after retries |

## GitHub Actions example

Send every draft invoice each Monday:

```yaml .github/workflows/send-invoices.yml theme={null}
name: Send draft invoices
on:
  schedule:
    - cron: "0 9 * * 1"
jobs:
  send:
    runs-on: ubuntu-latest
    env:
      INVOICE_AI_API_KEY: ${{ secrets.INVOICE_AI_API_KEY }}
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm install -g @horizonpay/invoice-ai-cli
      - run: |
          for id in $(invoice-ai invoices list --status draft --all --json | jq -r '.data[].id'); do
            invoice-ai invoices send "$id" --yes
          done
```

The key needs `invoices:read` and `invoices:send`. Sending is capped at 10 emails per hour per key and 50 per account, so a large batch stops with exit code `4`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.