Skip to content

CLI

Validate, scaffold, and convert offline — or send to Peppol with one command.

Installation

Install @getpeppr/cli globally or run it directly with npx.

Install globally

Terminal
npm install -g @getpeppr/cli

Or use npx (no install)

Terminal
npx @getpeppr/cli validate invoice.json

Scaffold an Invoice

Generate a starter JSON file with all required fields pre-filled — a Belgian seller, the Belgian sandbox test receiver as buyer, two invoice lines. Ready to edit, validate, and send.

Terminal
# Default — creates invoice.json
getpeppr init

# Custom filename
getpeppr init my-invoice.json

# Credit note template
getpeppr init --credit-note

# Overwrite an existing file
getpeppr init --force
FlagDescription
[filename]Output filename (default invoice.json)
--credit-noteGenerate a credit note template instead of an invoice
--forceOverwrite an existing file

Validate an Invoice

Pass a JSON file to getpeppr validate to check it against three validation engines:

  • Structure — required fields, types, and format checks
  • Offline Checks — 40 registered partial pre-flight checks: exact network-rule equivalents plus explicit GETPEPPR-* diagnostics; the legacy provider-capability diagnostic unsupported_vat_category can also appear outside that count
  • Country Rules — Belgium, France, Italy, Netherlands, Germany
Terminal
getpeppr validate invoice.json

Example output

Output
Validating: invoice.json

── Structure ──────────────────────────────
 No errors
 to.vatNumber Buyer VAT number not provided. May be required for B2B.

── Offline Checks (partial) ───────────────────
 No findings

── Country Rules ────────────────────────────
 No structured communication reference (BE-02)

── Summary ──────────────────────────────────
 Pre-flight checks passed (2 warnings)
Validation runs offline — no API key, no network connection, no account required. The CLI uses the same validation engine as the SDK (validateInvoice, validateSchematron, validateCountryRules). This offline pass catches common issues; it is not a Peppol conformance verdict. Sending invoices to Peppol does require an API key — see Send to Peppol below.

Validate Flags

FlagDescription
--jsonMachine-readable JSON output
--quietExit code only, no output
--versionShow version number
--helpShow help

Convert to UBL XML

Convert a getpeppr JSON invoice to Peppol BIS 3.0 UBL 2.1 XML. Credit notes ("isCreditNote": true) are detected automatically and produce the correct UBL CreditNote document.

Terminal
# Print UBL XML to stdout
getpeppr convert invoice.json

# Write to file
getpeppr convert invoice.json -o invoice.xml

# Validate before converting (errors block conversion)
getpeppr convert invoice.json --validate -o invoice.xml
FlagDescription
-o, --output <file>Write XML to file instead of stdout
--validateValidate before converting — errors block conversion

Lookup the Peppol Directory

Search the public Peppol Directory to verify any participant on the network — by Peppol ID or company name.

Terminal
# Direct lookup by Peppol ID
getpeppr lookup 0208:0685660237

# Search by company name
getpeppr lookup --name "Dupont"

# Filter by country
getpeppr lookup --name "GmbH" --country DE

# JSON output for tooling
getpeppr lookup 0208:0685660237 --json
FlagDescription
--name <name>Search by company name (min 3 characters)
--country <code>Filter by ISO 2-letter country code
--jsonOutput results as JSON
--limit <n>Max results for search (default 10)

Exit Codes

CodeMeaning
0Pre-flight completed without blocking findings (may have warnings)
1Pre-flight found blocking errors
2File not found or invalid JSON

JSON Output

Use --json for machine-readable output, ideal for CI pipelines and tooling.

Terminal
getpeppr validate invoice.json --json
Result
{
  "structure": { "errors": [], "warnings": [...] },
  "schematron": { "errors": [], "warnings": [] },
  "countryRules": { "errors": [], "warnings": [...] },
  "totalErrors": 0,
  "totalWarnings": 2,
  "valid": true
}

CI/CD Integration

Use --quiet in CI pipelines to gate deployments on invoice compliance.

ci.yml
# Fail the pipeline if the invoice is invalid
getpeppr validate invoice.json --quiet || exit 1

# Or validate multiple files
for file in invoices/*.json; do
  getpeppr validate "$file" --quiet || exit 1
done

# Send via API key in env (no login state needed)
GETPEPPR_API_KEY=$SANDBOX_KEY getpeppr send invoice.json --json
The --quiet flag suppresses all output and relies only on exit codes. It takes precedence over --json, so use one or the other: --json alone in CI to capture structured results, --quiet alone when only the exit code matters.

Invoice Format

The input file must be a JSON object matching the InvoiceInput type. See the Type Definitions for all available fields.

invoice.json
{
  "number": "INV-2026-001",
  "date": "2026-04-07",
  "dueDate": "2026-05-07",
  "currency": "EUR",
  "buyerReference": "PO-12345",
  "to": {
    "name": "SPF Economie (test receiver)",
    "peppolId": "9925:BE0314595348",
    "street": "Rue du Progrès 50",
    "city": "Brussels",
    "postalCode": "1210",
    "country": "BE"
  },
  "lines": [
    {
      "description": "Consulting services",
      "quantity": 10,
      "unitPrice": 150,
      "vatRate": 0,
      "vatCategory": "O",
      "taxExemptReason": "Integration test"
    }
  ]
}

Send to Peppol

When your invoice JSON is ready, send it through the getpeppr API to the Peppol network — straight from the terminal. Sandbox is the default; pass --prod for production.

getpeppr login — Save your API key

Stores a getpeppr API key in $XDG_CONFIG_HOME/getpeppr/credentials.json~/.config/getpeppr/credentials.json by default, %APPDATA%\getpeppr\credentials.json on Windows. On Unix-like systems the file is created and checked with mode 0600; Windows has no POSIX mode, so there the file relies on your account's own permissions. Sandbox and live keys can coexist — the CLI picks the right one based on the target environment.

Terminal
# Interactive (recommended) — masked input
getpeppr login

# Explicit (required in CI / non-TTY)
getpeppr login --key sk_sandbox_... --sandbox
getpeppr login --key sk_live_...    --live
FlagDescription
--key <key>API key. CI use only — visible in ps/shell history. Prefer the prompt or GETPEPPR_API_KEY.
--sandboxStore as sandbox key (default)
--liveStore as live (production) key
Resolution order: --key flag → GETPEPPR_API_KEY env var → stored credentials. In CI, prefer the env var pattern over login --key to avoid leaking the key into shell history.

getpeppr send — Send an invoice

Sends an invoice through the getpeppr API to the Peppol network. Pass either a JSON file or the synth flags (--to, --amount, --desc) — they're mutually exclusive.

getpeppr send runs a JSON preflight aligned with POST /v1/invoices. That endpoint currently ignores invoiceTypeCode and lets the provider generate the UBL, so the send preflight does not apply P0100, P0101, or P0112 to that inert field. Structure checks including BR-CL-01, plus every other applicable offline and country check, remain active. Use getpeppr validate or convert --validate for full local-UBL semantics; both retain those profile checks because they validate or build the UBL locally.
Terminal
# Send a JSON file (sandbox by default)
getpeppr send invoice.json

# Watch delivery status until terminal (60s timeout)
getpeppr send invoice.json --watch

# Production send — confirmation prompt (skip with -y)
getpeppr send invoice.json --prod

# Quick test — synthesize from flags using the SPF Economie recipient test ID
getpeppr send --to 9925:BE0314595348 --amount 100 --desc "Test invoice"
FlagDescription
[file]Path to invoice JSON (mutex with --to/--amount/...)
--prodTarget production (uses live key + confirmation prompt)
--localTarget http://localhost:3001 (dev server)
--key <key>Override stored API key
--to <peppol-id>Recipient Peppol ID (when no file)
--country <iso>Recipient ISO 3166-1 alpha-2 country override (e.g. BE)
--amount <number>Line amount in major currency units
--currency <iso>ISO 4217 code (default EUR)
--desc <text>Line description
--attachmentAttach the bundled test PDF
--watchPoll status until terminal (60s timeout, measured to the start of the last poll). Exits 1 on rejected, failed, no_action (not deliverable), and — since CLI 0.7.0 — whenever the polling itself fails, whether the API answered something unreadable or the request never landed at all. A plain timeout still exits 0
-y, --yesSkip the --prod confirmation prompt
--no-validateSkip the JSON send preflight
--jsonMachine-readable JSON output
--quietExit code only, no output

getpeppr whoami — Show your Peppol identity

Shows the Peppol identity of the account behind your API key — the quick sanity check that you are pointing at the right account and environment before sending.

Terminal
# Which account and environment am I pointing at?
getpeppr whoami

# Machine-readable output (carries the full identity — see the note below)
getpeppr whoami --json
FlagDescription
--prodUse the live API key (default: sandbox)
--localTarget http://localhost:3001 (dev server)
--key <key>Override stored API key — for CI/scripted use only; visible in ps and shell history, prefer GETPEPPR_API_KEY
--jsonOutput the identity as JSON

--json prints the full identity, including the legal entity name and address — keep it out of shared CI logs and support tickets.

getpeppr logout — Remove credentials

Removes the credentials file described under login. No-op if it doesn't exist.

Terminal
getpeppr logout

Next Steps

Need a programmatic API instead of the terminal? Use the SDK. Sign up at getpeppr.dev to get your API key.