# CLI

Agent-first command-line interface for the BeeL. API — run any endpoint from the terminal, sandbox by default.

The BeeL. CLI lets you operate the API from the terminal: create and issue invoices, manage customers and products, validate NIFs, export data — without writing code. It is **agent-first** by design: compact JSON output for data commands, semantic exit codes, and sandbox by default, so both humans and AI assistants can use it safely.

Commands are derived from the API spec **bundled with the installed CLI version**, so each release exposes the API surface as of that version — new endpoints become new commands when you update the CLI. For an endpoint the installed version doesn't know yet, use the [generic escape hatch](#generic-escape-hatch).

## Installation

<Tabs items={['npm (global)', 'npx (no install)']}>
  <Tab value="npm (global)">
    ```bash
    npm install -g @beel_es/cli
    beel --help
    ```
  </Tab>
  <Tab value="npx (no install)">
    ```bash
    npx @beel_es/cli --help
    ```
    Handy for CI pipelines and AI agents — always runs the latest published version.
  </Tab>
</Tabs>

<Callout type="info">
  Requires **Node.js 20 or higher**. The commands on this page are those of version **0.3.0**; check yours with `beel --version`. Coming from 0.2.x? See [Upgrading from 0.2.x](#upgrading-from-02x).
</Callout>

## Authentication

Two ways to sign in — **OAuth** (a browser sign-in, best for people) or an **API key** (best for CI and autonomous agents).

<Tabs items={['OAuth (browser)', 'API key (CI / agents)']}>
  <Tab value="OAuth (browser)">
    ```bash
    beel login          # opens the browser; sign in on the BeeL. consent screen (sandbox)
    beel login --live   # same, for production
    ```
    Pick the account, scopes and environment on the consent screen — no keys to copy around. Tokens are stored (and auto-refreshed) in `~/.config/beel/config.json` (chmod 600) and are never printed. Revoke anytime with `beel logout` (`--live` for production).
  </Tab>
  <Tab value="API key (CI / agents)">
    ```bash
    # Option A: env var (recommended for CI/agents)
    export BEEL_API_KEY=beel_sk_test_...

    # Option B: store a key in the config file (chmod 600)
    beel login --api-key beel_sk_test_...
    beel login --api-key beel_sk_live_...   # both can coexist
    ```
    Get your keys at [**Settings > API Keys**](https://app.beel.es/ajustes/api-keys) — each environment has its own, separate key, filed by prefix (`beel_sk_test_*` → sandbox, `beel_sk_live_*` → production).
  </Tab>
</Tabs>

When more than one credential is present, precedence is **`BEEL_API_KEY` → OAuth session (refreshed if expired) → stored API key**.

<Callout type="warn">
  **Sandbox is the default.** Every command uses the test environment unless you pass `--live`. A live key in `BEEL_API_KEY` without `--live` is an error, not a silent upgrade — production access is always explicit.
</Callout>

```bash
beel config   # shows config path, base URL and the active session / keys (masked)
beel logout   # remove stored credentials for the environment (--live for production)
```

## Common recipes

Commands follow the `beel <resource> <action>` pattern, for example `beel invoices list` or `beel customers create`. A command acts on one company (NIF), which the CLI works out for you, so you don't pass its ID each time (see [Which company a command acts on](#which-company-a-command-acts-on)). These are everyday examples; the full, always-up-to-date list comes from `beel commands` (see below).

```bash
# Invoices
beel invoices list --status PAID --limit 5        # filter + paginate
beel invoices get <invoice_id>
beel invoices create --data @invoice.json         # create a draft
beel invoices issue <invoice_id> --wait-for-pdf   # emit + wait for the PDF
beel invoices set-status <invoice_id> --status PAID --payment-date 2026-09-01
beel invoices create-corrective <invoice_id> --data @rectificativa.json
beel invoices get-pdf <invoice_id>                # returns the PDF download URL
beel invoices create-export --format SUMMARY --output invoices.xlsx

# Customers & products
beel customers list --search "ACME"
beel customers create --data @customer.json
beel customers patch <customer_id> --data '{"email":null}'   # PATCH: fields you leave out don't change
beel products list --q "consultoría"
beel products delete <product_id>

# Series, VeriFactu & NIF
beel series list
beel series set-default <series_id>
beel verifactu-configuration get                  # VeriFactu status of the NIF
beel nif validate --nif B12345678                 # checks the AEAT census

# Payment connections: events are addressed by the connection's ID
beel payment-connections list                     # each connection's id
beel payment-connections list-events <connection_id> --needs-action
beel payment-connections retry-event <connection_id> <event_id>

# Account level
beel webhooks list
beel me get                                       # who the credential belongs to

# Another company of the same account
beel --company <company_id> invoices list
```

### Which company a command acts on

Most commands work on a company (NIF): `beel invoices list` calls `GET /v1/companies/{company_id}/invoices`. The CLI fills in `{company_id}` in this order:

1. The `--company <company_id>` flag.
2. The `BEEL_COMPANY_ID` environment variable.
3. Your account's only company. The CLI reads your account from `GET /v1/me/identity`, then lists its companies.

If your account has **more than one company**, the CLI does not pick one. It exits with code `2` and lists the candidates (ID, NIF and name) so you can choose. `beel companies list` shows them too.

Step 3 costs one or two extra requests per command, and your API key or OAuth session needs the `companies:list` scope. Without that scope those requests answer `403` (exit code `3`). In scripts, CI and agents, set `BEEL_COMPANY_ID` and skip the lookup:

```bash
export BEEL_COMPANY_ID=<company_id>
beel invoices list
```

Account-level commands (`webhooks`, `members`, `invitations`, `request-logs`, `companies list`…) work the same way with `--account <account_id>` and `BEEL_ACCOUNT_ID`. By default they use the account your credential belongs to, and finding it needs no scope.

## Discovering commands

The CLI is **agent-first**: every command is derived from the API spec, so an assistant can discover the whole surface in one call instead of scraping help text.

```bash
beel commands            # full command index as JSON — { command, signature, description, method, path }
beel commands --markdown # the same grouped by resource as markdown tables
```

`beel commands` reflects the spec bundled with the installed CLI version — not the live API — so update the CLI to pick up newly added endpoints (or use the [escape hatch](#generic-escape-hatch) meanwhile). There's no hand-maintained list to fall out of date. For details of a single command — flags, enums, defaults and body fields, all from the spec — use `--help` at any level:

```bash
beel --help
beel invoices --help
beel invoices create --help
```

For commands with a request body, `--help` also lists the **top-level body fields** (name, type, whether they're required, and any enums), so you know what to send without leaving the terminal:

```text
$ beel invoices create --help
...
Options:
  --type <STANDARD|CORRECTIVE|SIMPLIFIED|PROFORMA>  Invoice type to create. (body field, required)
  --notes <string>                                  (body field)
  --series-id <string>                              Invoicing series ID (if not specified, uses default) (body field)
  ...
  --data <json>                                     JSON body (required): inline, @file.json, or - for stdin; field flags override its keys

Body fields, * = required. Fields with a --flag above can be passed that way; the rest go in --data:
  * lines           object[]
  * recipient       object  Invoice recipient. …
  * type            string (STANDARD|CORRECTIVE|SIMPLIFIED|PROFORMA)  Invoice type to create. …
    notes           string
    …
Full schema (nested fields, formats): beel docs search invoices
```

## Arguments, flags and `--data`

- **IDs in the path are positional arguments**, in the order of the path: `beel invoices get <invoice_id>`, `beel members set-grant <member_id> <company_id>`. The company and the account are not among them: they come from `--company` and `--account` (see [above](#which-company-a-command-acts-on)).
- **Query parameters are flags** named after the API parameter: `--status`, `--sort-by`, `--needs-action`.
- **Top-level body fields that are a string, number or boolean have their own flag**, named after the API field: `--status PAID`, `--default-price 12.5`, `--active false`. Enum values are checked before the request is sent: a value outside the list exits with code `2` and names the allowed ones.
- **`--data` takes the whole body** as inline JSON, `@file.json`, or `-` for stdin. Objects, arrays and `null` only go this way. When you pass both, the flags override the keys of `--data`: `--data @base.json --status PAID`.
- A command whose body is required needs `--data` or at least one field flag.
- Binary responses (PDF, ZIP, Excel) require `--output <path>`.
- `POST` requests get an automatic `Idempotency-Key`.

## Searching the docs

The CLI can search this documentation locally — useful for AI agents that want the relevant section without fetching whole pages. It downloads the machine-readable docs once (cached 15 minutes) and filters on your machine; search terms never leave your computer. No API key needed.

```bash
beel docs list                    # all documentation pages (JSON)
beel docs search idempotency key  # prints only the matching sections
beel docs get glossary            # prints a full page as markdown
```

## Generic escape hatch

Any endpoint, even ones this CLI version doesn't know yet:

```bash
beel request GET /v1/companies/{company_id}/invoices --query status=PAID --query limit=5
beel request POST /v1/companies/{company_id}/customers --data @customer.json
```

`{company_id}` and `{account_id}` in the path are filled in the same way as for regular commands. `beel request` also reaches the deprecated routes until they retire on 9 December 2026.

## Output contract

Built for scripting and AI agents:

- **stdout**: for API/data commands, the response JSON, compact on one line — pipe straight into `jq`. Add `--pretty` to indent it. Two helpers print human-readable markdown instead: `docs` (`list`/`search`/`get`) and `commands --markdown` (plain `commands` is JSON).
- **stderr**: errors as one JSON object on one line: `{"error": {"code", "message", "status", "details", "request_id"}}`

| Exit code | Meaning |
|-----------|---------|
| `0` | Success |
| `1` | Unexpected error |
| `2` | Usage or config error |
| `3` | Auth (401/403) |
| `4` | Not found |
| `5` | Validation (400/409/422) |
| `6` | Rate limit (429) |
| `7` | Server error (5xx) |

`BEEL_COMPANY_ID` and `BEEL_ACCOUNT_ID` choose the company and account (see [above](#which-company-a-command-acts-on)); `BEEL_BASE_URL` overrides the API host; `BEEL_CONFIG_DIR` overrides the config location.

## Upgrading from 0.2.x

0.3.0 builds its commands only from the routes that name the company or the account. The flat routes that 0.2.x called are deprecated and **retire on 9 December 2026**. Scripts written for 0.2.x need new command names:

- **Company commands move to their resource.** `beel companies list-invoices <company_id>` is now `beel invoices list --company <company_id>`, or just `beel invoices list` if the CLI can work out the company.
- **Action names drop what the resource already says.** `companies get-by-id` is `companies get`, `webhooks list-subscriptions` is `webhooks list`, `emails get-delivery` is `emails get`, `me get-my-identity` is `me get`, and `invoices convert-proforma-to-invoice` is `invoices convert-proforma`. Actions that replace a value with `PUT` are called `set`: `owner set`, `members set-grant`.
- **Status changes use one command.** `invoices mark-paid`, `mark-sent` and `revert-to-issued` become `invoices set-status <invoice_id> --status PAID` (or `SENT`, `ISSUED`). `recurring-invoices pause` and `resume` become `recurring-invoices set-status`.
- **`update` becomes `patch`** on invoices, customers, products, recurring invoices and series. Fields you leave out keep their value; to clear a field that can be cleared, send it as `null` (each command's `--help` says which).
- **Payment events take a connection ID** instead of the provider name: `beel payment-connections list-events <connection_id>`.
- **Output is compact JSON.** 0.2.x indented it; pass `--pretty` for the old layout. Body fields can now also be passed as flags (see [Arguments, flags and `--data`](#arguments-flags-and---data)).

If you type a 0.2.x name, the CLI exits with code `2` and its error message gives the new name:

```text
unknown command 'list-invoices'. 'companies list-invoices' was renamed in 0.3.0: use 'beel invoices list --company <company_id>'. All renamed commands: https://docs.beel.es/cli#upgrading-from-02x
```

<Accordions>
  <Accordion title="Every renamed command (0.2.x → 0.3.0)">
    Commands whose name, arguments and body didn't change are not listed.

    | 0.2.x | 0.3.0 | Notes |
    | --- | --- | --- |
    | `accounts cancel-representation <account_id> <company_id>` | `representation cancel --company <company_id>` |  |
    | `accounts change-managed-access-level <account_id>` | `access-level change --account <account_id>` |  |
    | `accounts create-claim-token <account_id>` | `claim-tokens create --account <account_id>` |  |
    | `accounts create-company <account_id>` | `companies create --account <account_id>` |  |
    | `accounts create-invitation <account_id>` | `invitations create --account <account_id>` |  |
    | `accounts create-webhook-subscription <account_id>` | `webhooks create --account <account_id>` |  |
    | `accounts delete-invitation <account_id> <invitation_id>` | `invitations delete <invitation_id> --account <account_id>` |  |
    | `accounts delete-member <account_id> <member_id>` | `members delete <member_id> --account <account_id>` |  |
    | `accounts delete-member-grant <account_id> <member_id> <company_id>` | `members delete-grant <member_id> <company_id> --account <account_id>` |  |
    | `accounts delete-webhook-subscription <account_id> <webhook_id>` | `webhooks delete <webhook_id> --account <account_id>` |  |
    | `accounts download-representation <account_id> <company_id>` | `representation download-document --company <company_id>` |  |
    | `accounts end-management <account_id>` | `management end --account <account_id>` |  |
    | `accounts generate-representation <account_id> <company_id>` | `representation generate --company <company_id>` |  |
    | `accounts get-email-delivery <account_id> <email_id>` | `emails get <email_id> --account <account_id>` |  |
    | `accounts get-email-delivery-indicators <account_id>` | `email-indicators list --account <account_id>` |  |
    | `accounts get-invitation <account_id> <invitation_id>` | `invitations get <invitation_id> --account <account_id>` |  |
    | `accounts get-member <account_id> <member_id>` | `members get <member_id> --account <account_id>` |  |
    | `accounts get-representation-status <account_id> <company_id>` | `representation get --company <company_id>` |  |
    | `accounts get-request-log <account_id> <request_id>` | `request-logs get <request_id> --account <account_id>` |  |
    | `accounts get-usage <account_id>` | `usage get --account <account_id>` |  |
    | `accounts get-webhook-subscription <account_id> <webhook_id>` | `webhooks get <webhook_id> --account <account_id>` |  |
    | `accounts list-companies <account_id>` | `companies list --account <account_id>` |  |
    | `accounts list-company-stats <account_id>` | `companies list-stats --account <account_id>` |  |
    | `accounts list-email-deliveries <account_id>` | `emails list --account <account_id>` |  |
    | `accounts list-invitations <account_id>` | `invitations list --account <account_id>` |  |
    | `accounts list-member-grants <account_id> <member_id>` | `members list-grants <member_id> --account <account_id>` |  |
    | `accounts list-members <account_id>` | `members list --account <account_id>` |  |
    | `accounts list-request-logs <account_id>` | `request-logs list --account <account_id>` |  |
    | `accounts list-webhook-deliveries <account_id> <webhook_id>` | `webhooks list-deliveries <webhook_id> --account <account_id>` |  |
    | `accounts list-webhook-subscriptions <account_id>` | `webhooks list --account <account_id>` |  |
    | `accounts patch-member <account_id> <member_id>` | `members patch <member_id> --account <account_id>` |  |
    | `accounts patch-webhook-subscription <account_id> <webhook_id>` | `webhooks patch <webhook_id> --account <account_id>` |  |
    | `accounts put-member-grant <account_id> <member_id> <company_id>` | `members set-grant <member_id> <company_id> --account <account_id>` |  |
    | `accounts put-owner <account_id>` | `owner set --account <account_id>` |  |
    | `accounts retry-webhook-delivery <account_id> <webhook_id> <delivery_id>` | `webhooks retry-delivery <webhook_id> <delivery_id> --account <account_id>` |  |
    | `accounts rotate-webhook-secret <account_id> <webhook_id>` | `webhooks rotate-secret <webhook_id> --account <account_id>` |  |
    | `accounts submit-representation <account_id> <company_id>` | `representation submit --company <company_id>` |  |
    | `accounts test-webhook-subscription <account_id> <webhook_id>` | `webhooks test <webhook_id> --account <account_id>` |  |
    | `companies activate-by-id <company_id>` | `activations activate --company <company_id>` |  |
    | `companies cancel-representation <company_id>` | `representation cancel --company <company_id>` |  |
    | `companies convert-proforma-to-invoice <company_id> <invoice_id>` | `invoices convert-proforma <invoice_id> --company <company_id>` |  |
    | `companies create-corrective-invoice <company_id> <invoice_id>` | `invoices create-corrective <invoice_id> --company <company_id>` |  |
    | `companies create-customer <company_id>` | `customers create --company <company_id>` |  |
    | `companies create-customer-import <company_id>` | `customers create-import --company <company_id>` |  |
    | `companies create-customers-bulk <company_id>` | `customers create-bulk --company <company_id>` |  |
    | `companies create-invoice <company_id>` | `invoices create --company <company_id>` |  |
    | `companies create-invoice-batch <company_id>` | `invoices create-batch --company <company_id>` |  |
    | `companies create-invoice-delivery <company_id>` | `invoices create-delivery --company <company_id>` |  |
    | `companies create-invoice-derivation <company_id>` | `invoices create-derivation --company <company_id>` |  |
    | `companies create-invoice-export <company_id>` | `invoices create-export --company <company_id>` |  |
    | `companies create-invoice-pdf-archive <company_id>` | `invoices create-pdf-archive --company <company_id>` |  |
    | `companies create-product <company_id>` | `products create --company <company_id>` |  |
    | `companies create-products-bulk <company_id>` | `products create-bulk --company <company_id>` |  |
    | `companies create-recurring-invoice <company_id>` | `recurring-invoices create --company <company_id>` |  |
    | `companies create-recurring-invoice-derivation <company_id>` | `recurring-invoices create-derivation --company <company_id>` |  |
    | `companies create-series <company_id>` | `series create --company <company_id>` |  |
    | `companies deactivate-by-id <company_id>` | `activations deactivate --company <company_id>` |  |
    | `companies delete-by-id <company_id>` | `companies delete <company_id>` |  |
    | `companies delete-customer <company_id> <customer_id>` | `customers delete <customer_id> --company <company_id>` |  |
    | `companies delete-customers-bulk <company_id>` | `customers delete-bulk --company <company_id>` |  |
    | `companies delete-invoice <company_id> <invoice_id>` | `invoices delete <invoice_id> --company <company_id>` |  |
    | `companies delete-invoice-schedule <company_id> <invoice_id>` | `invoices delete-schedule <invoice_id> --company <company_id>` |  |
    | `companies delete-logo-by-id <company_id>` | `logo delete --company <company_id>` |  |
    | `companies delete-product <company_id> <product_id>` | `products delete <product_id> --company <company_id>` |  |
    | `companies delete-products-bulk <company_id>` | `products delete-bulk --company <company_id>` |  |
    | `companies delete-recurring-invoice <company_id> <recurring_invoice_id>` | `recurring-invoices delete <recurring_invoice_id> --company <company_id>` |  |
    | `companies delete-series <company_id> <series_id>` | `series delete <series_id> --company <company_id>` |  |
    | `companies disconnect-payment-connection <company_id> <provider>` | `payment-connections disconnect <connection_id> --company <company_id>` | arguments change: `<provider>` → `<connection_id>` |
    | `companies download-representation-document <company_id>` | `representation download-document --company <company_id>` |  |
    | `companies ensure-default-series <company_id>` | `series ensure-default --company <company_id>` |  |
    | `companies generate-payment-event-draft <company_id> <provider> <event_id>` | `payment-connections generate-event-draft <connection_id> <event_id> --company <company_id>` | arguments change: `<provider> <event_id>` → `<connection_id> <event_id>` |
    | `companies generate-recurring-invoice-now <company_id> <recurring_invoice_id>` | `recurring-invoices generate-now <recurring_invoice_id> --company <company_id>` |  |
    | `companies generate-representation <company_id>` | `representation generate --company <company_id>` |  |
    | `companies get-by-id <company_id>` | `companies get <company_id>` |  |
    | `companies get-customer <company_id> <customer_id>` | `customers get <customer_id> --company <company_id>` |  |
    | `companies get-default-series <company_id>` | `series get-default --company <company_id>` |  |
    | `companies get-fiscal-summary <company_id>` | `fiscal-summary get --company <company_id>` |  |
    | `companies get-invoice <company_id> <invoice_id>` | `invoices get <invoice_id> --company <company_id>` |  |
    | `companies get-invoice-customization <company_id>` | `invoice-customization get --company <company_id>` |  |
    | `companies get-invoice-pdf <company_id> <invoice_id>` | `invoices get-pdf <invoice_id> --company <company_id>` |  |
    | `companies get-invoice-preview <company_id> <invoice_id>` | `invoices get-preview <invoice_id> --company <company_id>` |  |
    | `companies get-invoice-schedule <company_id> <invoice_id>` | `invoices get-schedule <invoice_id> --company <company_id>` |  |
    | `companies get-issuing-readiness <company_id>` | `issuing-readiness get --company <company_id>` |  |
    | `companies get-payment-event <company_id> <provider> <event_id>` | `payment-connections get-event <connection_id> <event_id> --company <company_id>` | arguments change: `<provider> <event_id>` → `<connection_id> <event_id>` |
    | `companies get-product <company_id> <product_id>` | `products get <product_id> --company <company_id>` |  |
    | `companies get-recurring-invoice <company_id> <recurring_invoice_id>` | `recurring-invoices get <recurring_invoice_id> --company <company_id>` |  |
    | `companies get-recurring-invoice-history <company_id> <recurring_invoice_id>` | `recurring-invoices get-history <recurring_invoice_id> --company <company_id>` |  |
    | `companies get-recurring-invoice-next-occurrence <company_id> <recurring_invoice_id>` | `recurring-invoices get-next-occurrence <recurring_invoice_id> --company <company_id>` |  |
    | `companies get-representation <company_id>` | `representation get --company <company_id>` |  |
    | `companies get-series <company_id> <series_id>` | `series get <series_id> --company <company_id>` |  |
    | `companies get-tax-configuration <company_id>` | `tax-configuration get --company <company_id>` |  |
    | `companies get-veri-factu-configuration <company_id>` | `verifactu-configuration get --company <company_id>` |  |
    | `companies initiate-payment-connection <company_id>` | `payment-connections initiate --company <company_id>` |  |
    | `companies issue-invoice <company_id> <invoice_id>` | `invoices issue <invoice_id> --company <company_id>` |  |
    | `companies list-customers <company_id>` | `customers list --company <company_id>` |  |
    | `companies list-invoices <company_id>` | `invoices list --company <company_id>` |  |
    | `companies list-payment-connections <company_id>` | `payment-connections list --company <company_id>` |  |
    | `companies list-payment-events <company_id> <provider>` | `payment-connections list-events <connection_id> --company <company_id>` | arguments change: `<provider>` → `<connection_id>` |
    | `companies list-products <company_id>` | `products list --company <company_id>` |  |
    | `companies list-recurring-invoices <company_id>` | `recurring-invoices list --company <company_id>` |  |
    | `companies list-series <company_id>` | `series list --company <company_id>` |  |
    | `companies patch-by-id <company_id>` | `companies patch <company_id>` |  |
    | `companies patch-customer <company_id> <customer_id>` | `customers patch <customer_id> --company <company_id>` |  |
    | `companies patch-invoice <company_id> <invoice_id>` | `invoices patch <invoice_id> --company <company_id>` |  |
    | `companies patch-product <company_id> <product_id>` | `products patch <product_id> --company <company_id>` |  |
    | `companies patch-recurring-invoice <company_id> <recurring_invoice_id>` | `recurring-invoices patch <recurring_invoice_id> --company <company_id>` |  |
    | `companies patch-series <company_id> <series_id>` | `series patch <series_id> --company <company_id>` |  |
    | `companies preview-customer-import <company_id>` | `customers preview-import --company <company_id>` |  |
    | `companies preview-invoice-pdf <company_id> <invoice_id>` | `invoices preview-pdf <invoice_id> --company <company_id>` |  |
    | `companies retry-payment-event <company_id> <provider> <event_id>` | `payment-connections retry-event <connection_id> <event_id> --company <company_id>` | arguments change: `<provider> <event_id>` → `<connection_id> <event_id>` |
    | `companies send-invoice <company_id> <invoice_id>` | `invoices send <invoice_id> --company <company_id>` |  |
    | `companies set-default-series <company_id> <series_id>` | `series set-default <series_id> --company <company_id>` |  |
    | `companies set-invoice-schedule <company_id> <invoice_id>` | `invoices set-schedule <invoice_id> --company <company_id>` |  |
    | `companies set-invoice-status <company_id> <invoice_id>` | `invoices set-status <invoice_id> --company <company_id>` |  |
    | `companies set-recurring-invoice-status <company_id> <recurring_invoice_id>` | `recurring-invoices set-status <recurring_invoice_id> --company <company_id>` |  |
    | `companies skip-recurring-invoice <company_id> <recurring_invoice_id>` | `recurring-invoices skip <recurring_invoice_id> --company <company_id>` |  |
    | `companies submit-representation <company_id>` | `representation submit --company <company_id>` |  |
    | `companies update-invoice-customization <company_id>` | `invoice-customization update --company <company_id>` |  |
    | `companies update-tax-configuration <company_id>` | `tax-configuration update --company <company_id>` |  |
    | `companies update-veri-factu-configuration <company_id>` | `verifactu-configuration update --company <company_id>` |  |
    | `companies upload-logo-by-id <company_id>` | `logo upload --company <company_id>` |  |
    | `companies void-invoice <company_id> <invoice_id>` | `invoices void <invoice_id> --company <company_id>` | now requires a body (`--data` or field flags) |
    | `configuration create-default-series` | `series ensure-default` | `POST` → `PUT` |
    | `configuration create-series` | `series create` |  |
    | `configuration delete-series <series_id>` | `series delete <series_id>` |  |
    | `configuration get-default-series-status` | `series get-default` |  |
    | `configuration get-invoice-customization-options` | `invoice-customization-options list` |  |
    | `configuration get-tax` | `tax-configuration get` |  |
    | `configuration get-tax-types` | `tax-types list` |  |
    | `configuration get-veri-factu` | `verifactu-configuration get` |  |
    | `configuration list-series` | `series list` |  |
    | `configuration patch-series <series_id>` | `series patch <series_id>` |  |
    | `configuration set-default-series <series_id>` | `series set-default <series_id>` | `POST` → `PUT` |
    | `configuration update-language` | `me update` | `PUT` → `PATCH` |
    | `configuration update-series <series_id>` | `series patch <series_id>` | `PUT` → `PATCH` |
    | `configuration update-tax` | `tax-configuration update` |  |
    | `configuration update-veri-factu` | `verifactu-configuration update` |  |
    | `customers deactivate-bulk` | `customers delete-bulk` |  |
    | `customers download-template-csv` | `templates download-customer-import` | `POST` → `GET` |
    | `customers import-csv-preview` | `customers preview-import` |  |
    | `customers import-holded-contacts` | `customers create-import` |  |
    | `customers update <customer_id>` | `customers patch <customer_id>` | `PUT` → `PATCH`; PATCH leaves absent fields untouched instead of clearing them — send every field |
    | `developers get-request-log <request_id>` | `request-logs get <request_id>` |  |
    | `developers list-request-logs` | `request-logs list` |  |
    | `emails get-delivery <email_id>` | `emails get <email_id>` |  |
    | `emails get-delivery-indicators` | `email-indicators list` |  |
    | `emails list-deliveries` | `emails list` |  |
    | `invoices change-status-bulk` | `invoices create-batch` |  |
    | `invoices convert-proforma-to <invoice_id>` | `invoices convert-proforma <invoice_id>` |  |
    | `invoices create-recurring-from <invoice_id>` | `recurring-invoices create-derivation` | arguments change: `<invoice_id>` → (none) |
    | `invoices download-pdf-bulk` | `invoices create-pdf-archive` |  |
    | `invoices duplicate <invoice_id>` | `invoices create-derivation` | arguments change: `<invoice_id>` → (none); now requires a body (`--data` or field flags) |
    | `invoices export-excel` | `invoices create-export` |  |
    | `invoices generate-pdf <invoice_id>` | `invoices get-pdf <invoice_id>` |  |
    | `invoices issue-bulk` | `invoices create-batch` |  |
    | `invoices mark-paid <invoice_id>` | `invoices set-status <invoice_id>` | `POST` → `PUT`; now requires a body (`--data` or field flags) |
    | `invoices mark-sent <invoice_id>` | `invoices set-status <invoice_id>` | `POST` → `PUT`; now requires a body (`--data` or field flags) |
    | `invoices preview-draft-pdf <invoice_id>` | `invoices preview-pdf <invoice_id>` |  |
    | `invoices reschedule <invoice_id>` | `invoices set-schedule <invoice_id>` | `PATCH` → `PUT` |
    | `invoices revert-to-issued <invoice_id>` | `invoices set-status <invoice_id>` | `POST` → `PUT`; now requires a body (`--data` or field flags) |
    | `invoices schedule <invoice_id>` | `invoices set-schedule <invoice_id>` | `POST` → `PUT` |
    | `invoices send-bulk-email` | `invoices create-delivery` |  |
    | `invoices send-email <invoice_id>` | `invoices send <invoice_id>` |  |
    | `invoices unschedule <invoice_id>` | `invoices delete-schedule <invoice_id>` | `POST` → `DELETE` |
    | `invoices update <invoice_id>` | `invoices patch <invoice_id>` | `PUT` → `PATCH` |
    | `me get-my-identity` | `me get` |  |
    | `products search` | `products list` |  |
    | `products update <product_id>` | `products patch <product_id>` | `PUT` → `PATCH`; PATCH leaves absent fields untouched instead of resetting them to the creation defaults — send every field |
    | `recurring-invoices pause <recurring_invoice_id>` | `recurring-invoices set-status <recurring_invoice_id>` | `POST` → `PUT`; now requires a body (`--data` or field flags) |
    | `recurring-invoices preview <recurring_invoice_id>` | `recurring-invoices get-next-occurrence <recurring_invoice_id>` |  |
    | `recurring-invoices resume <recurring_invoice_id>` | `recurring-invoices set-status <recurring_invoice_id>` | `POST` → `PUT`; now requires a body (`--data` or field flags) |
    | `recurring-invoices skip-next-generation <recurring_invoice_id>` | `recurring-invoices skip <recurring_invoice_id>` |  |
    | `recurring-invoices update <recurring_invoice_id>` | `recurring-invoices patch <recurring_invoice_id>` | `PUT` → `PATCH`; PATCH leaves absent fields untouched instead of clearing them — send every field |
    | `webhooks create-subscription` | `webhooks create` |  |
    | `webhooks delete-subscription <webhook_id>` | `webhooks delete <webhook_id>` |  |
    | `webhooks get-subscription <webhook_id>` | `webhooks get <webhook_id>` |  |
    | `webhooks list-subscriptions` | `webhooks list` |  |
    | `webhooks test-subscription <webhook_id>` | `webhooks test <webhook_id>` |  |
    | `webhooks update-subscription <webhook_id>` | `webhooks patch <webhook_id>` |  |
  </Accordion>
</Accordions>

## Related

<Related>

- [Claude Code](/claude-code) — the plugin whose skills run the CLI to verify a flow
- [Authentication](/auth) — the API key the CLI reads from `BEEL_API_KEY`
- [MCP server](/mcp) — the same operations for an assistant, without a terminal

</Related>

---

Full OpenAPI spec: https://docs.beel.es/api/openapi