Factuarea APIDevelopers

Agents & scripting

The factuarea CLI agent-first contract — stable JSON on stdout, structured errors on stderr, semantic exit codes, the commands --json manifest, local scope-check and typed confirmation for irreversible operations.

The CLI is agent-first: an AI assistant or a script can discover the whole surface in one call, get stable machine-readable output, and branch on semantic exit codes instead of parsing prose.

Discover the surface in one call

factuarea commands --json

This dumps the full command manifest. Each entry carries:

FieldMeaning
pathThe command path, e.g. invoices create.
argsPositional arguments (path params).
optional_argsThe positional arguments you can leave out, each mapped to the flag that fills it: {"company": "--company"} or {"account": "--account"}. Absent when no flag fills one. The managed-accounts commands never publish the managed account, and neither do the irreversible ones whose last path parameter is the account. See Company and account axes.
flagsAvailable flags.
mutatingWhether the command writes (needs --live in production).
binaryWhether it returns a binary (PDF/ZIP/XML) instead of JSON.
paginatedWhether the command supports cursor pagination.
required_scopeThe scope the API key must hold, e.g. invoices:read.
irreversibleWhether the operation cannot be undone.
exampleA ready-to-adapt example invocation.

required_scope and irreversible come straight from the OpenAPI spec's x-required-scope and x-irreversible extensions, so the CLI and the API reference agree by construction.

Output contract

  • --json emits the raw API body on stdout.
  • Errors go to stderr as structured JSON — the same error envelope as the API: error.{type,code,message,request_id,doc_url}. When the error answer carried a Retry-After header (a 429 or a 503, for example), the JSON adds error.retry_after with its value.
  • Keep stdout for data and stderr for diagnostics: pipe stdout to jq, log stderr.
  • --show-etag writes etag: <value> to stderr, so stdout keeps the raw body; capture the ETag from stderr to send it back with --if-match or --if-none-match. See Conditional writes.
  • A binary download can end with exit 0 and no file: a 202 prints the status JSON on stdout and retry-after: <seconds> on stderr, and a 304 (with --if-none-match) prints nothing on stdout. See download statuses.

Exit codes

Branch on the exit code, never on the message:

CodeMeaning
0OK
2Local usage / guard error
3Authentication failed
4Permission / missing scope
5Validation error
6Not found
7Rate limit
8Conflict / idempotency
9Server error
10Network / timeout

Local scope-check

Before a call, the CLI checks that your key holds the operation's required_scope. If it doesn't, the command fails locally with exit 4 and a clear message — no wasted round trip that the API would reject with 403 anyway.

  • The check only runs when the operation declares a scope and resolves the key's scopes lazily (one GET /v1/me per invocation at most, memoized).
  • A * scope on the key covers any operation.
  • --skip-scope-check downgrades the block to a warning and continues — useful if your cached scopes are stale. The API's real 403 is still the last line of defense.

Irreversible operations

Operations the spec marks x-irreversible (deletes, void, terminal conversions, fiscal emission, certificate rotation, GDPR forget…) ask for a typed confirmation before the call:

factuarea invoices delete <uuid> --confirm <uuid>
  • Pass --confirm <id> with the resource id to proceed.
  • In a non-interactive context (--no-input or no TTY) without --confirm, the command refuses with exit 2 rather than guessing.

See the scopes & irreversibility guide for the full list of which operations carry each scope and which are irreversible.

Want the agent to operate Factuarea through tools instead of CLI commands? Connect it to the MCP server — the same surface exposed as tools, with OAuth and API-key auth.

REST fallback

The CLI’s command catalog comes from its bundled spec. In the September 2026 baseline, release v0.2.0 is available and the main-branch spec contains 414 entries, with 38 REST endpoints absent from generated commands. Inspect factuarea commands --json for your installed version. Use the raw HTTP command for a supported REST endpoint missing from that catalog:

factuarea api get /v1/companies/acme_co/stores

On this page

Need a hand?Contact support