compense is a command-line tool for the tasks you do by hand while you integrate: validating a key, browsing the event catalog, registering an endpoint, triggering a test event, reviewing and retrying deliveries, moving a test clock, advancing a simulator and forwarding webhooks to your machine. Each command is a thin wrapper over the SDK and prints the gateway’s response as JSON, so you can pipe it into jq.

Installation #

The CLI is bundled with two SDKs, with the same commands and options. Use it even if your integration is in PHP, .NET or Go: those SDKs don’t ship a CLI.

SDKHow to installHow to run
Python (3.9+)pip install compense-sdk-pythoncompense … (it lands on the environment’s PATH)
JavaScript (Node 18+)npm install @compense/sdknpx compense …
Shell
compense --help              # Python and JavaScript
npx compense --version       # JavaScript only: prints the SDK version

Key, environment and URL #

Every command that calls the API accepts three options:

OptionValueDefault
--key KEYYour cmp_... keyThe COMPENSE_API_KEY environment variable
--environment ENVproduction, sandbox or devsandbox
--base-url URLAny other gateway URL (e.g. the one you got during onboarding); takes precedence over --environment—
Shell
export COMPENSE_API_KEY="cmp_..."                 # PowerShell: $env:COMPENSE_API_KEY = "cmp_..."
compense health                                   # sandbox by default
compense health --environment dev
compense health --base-url https://sandbox.dev.compense.co/gw

Remember that the key decides the behavior: with a sandbox key you get sandbox responses in any environment. Put the options after the command (and after its action, for clock and simulate): that’s the form both implementations accept.

Output and exit codes #

  • The response goes to stdout as indented JSON. SDK models are printed with the body exactly as the gateway returned it.
  • Messages (errors, the trigger notice) go to stderr.
CodeMeaning
0Success.
1The gateway rejected the request (error: gateway rejected the request — …), or you ran compense without a command (it prints the help). In JavaScript, also a connection error or timeout, and an unknown or incomplete command.
2No key (error: no API key. Pass --key or set $COMPENSE_API_KEY.), a configuration error (e.g. trigger with no active endpoints) or invalid options. In Python, also an unknown or incomplete command (an argparse error).

Commands #

CommandWhat it doesOperation
healthValidates the key: tenant and scopesGET/v1/gateway/health/
events [--category C]Webhook event catalogGET/v1/gateway/webhooks/event-catalog/
endpointsYour endpoints (without the secret)GET/v1/gateway/webhooks/endpoints/
endpoint-create --url U --event E [--event E …] [--label L]Registers an endpoint and prints the secret oncePOST/v1/gateway/webhooks/endpoints/
trigger <event> [--endpoint ID]Sends a signed test deliveryPOST/v1/gateway/webhooks/endpoints/{endpoint_id}/test/
deliveries [--status S] [--event-type T] [--endpoint ID]Delivery history (first page)GET/v1/gateway/webhooks/deliveries/
replay <delivery_id>Retries a failed or abandoned deliveryPOST/v1/gateway/webhooks/deliveries/{delivery_id}/replay/
clock create <frozen_time>Creates a test clockPOST/v1/gateway/sandbox/test-clocks/
clock get <clock_id>Retrieves a clockGET/v1/gateway/sandbox/test-clocks/{clock_id}/
clock advance <clock_id> <seconds>Moves a clock forward (prints the new id)POST/v1/gateway/sandbox/test-clocks/{clock_id}/advance/
simulate transfer [--status S] [--amount A] [--transaction-id T]One step of a wallet transferPOST/v1/gateway/sandbox/wallet/simulate/
simulate credit <app_id> [--status S] [--amount A]One step of a credit disbursementPOST/v1/gateway/sandbox/credits/{app_id}/advance/
listen --forward-to URL [--port N]Forwards received webhooks to a local URL— (doesn’t call the API)

The CLI has no commands to edit, pause, delete or rotate endpoints, or to get a single delivery’s details: use the SDK or cURL (Subscribing an endpoint, Retries and deliveries).

health #

Shell
compense health
JSON
{
  "status": "ok",
  "tenant": "horizonte",
  "scopes": ["affiliates:read", "credits:submit", "webhooks:read", "webhooks:manage"]
}

Webhooks #

Shell
# Catalog (everything or one category: credits, subsidies, monetary_allowance, affiliates,
# wallets, loans, health, admin, pqrs, general)
compense events --category loans

# Register an endpoint: repeat --event for each event. Save the "secret" it prints.
compense endpoint-create \
  --url https://erp.horizonte.example/compense/webhooks \
  --event payment.received \
  --event installment.overdue \
  --label "ERP Caja Horizonte"

compense endpoints

# Signed test. Without --endpoint it picks an active endpoint subscribed to the event
# (or, if there isn't one, the first active one).
compense trigger payment.received
compense trigger test.ping --endpoint 3f1a2b3c-0000-4a1b-9c2d-000000000001

# Failed deliveries for one event and a retry of one of them
compense deliveries --status failed --event-type payment.received
compense replay 8b7c6d5e-0000-4a1b-9c2d-000000000301

deliveries shows the first page (25 deliveries) and has no date or page filter; to walk the whole history, use the SDK, as in Reprocessing every failed delivery. With jq you can retry what you see:

Shell
compense deliveries --status failed | jq -r '.results[].id' | while read -r ID; do
  compense replay "$ID"
done

Clocks #

Shell
compense clock create 2026-10-01T00:00:00Z           # or Unix seconds: 1790812800
compense clock advance tcl-… 2592000                 # 30 days; prints the clock with a NEW id
compense clock get tcl-…

# Chain advances with jq
ID=$(compense clock create 2026-07-15T00:00:00Z | jq -r .id)
ID=$(compense clock advance "$ID" 5443200 | jq -r .id)   # 63 days (maximum per call)
compense clock get "$ID" | jq -r .current_time

Clocks only respond to sandbox keys. Details in Test clocks.

Simulators #

Shell
# Transfer: without --status it starts at PENDING. 22.22 → FAILED, 33.33 → RETURNED.
compense simulate transfer --amount 33.33
compense simulate transfer --status PROCESSING --amount 33.33
compense simulate transfer --status SETTLED --amount 33.33 --transaction-id NOVA-P2P-2026-000123

# Disbursement of a sandbox credit application
compense simulate credit sbx-E-… --status PENDING
JSON
{
  "object": "wallet_transfer",
  "previous_status": "SETTLED",
  "status": "RETURNED",
  "terminal": true,
  "amount": 33.33,
  "reference": "NOVA-P2P-2026-000123",
  "reason_code": "TRANSFER_RETURNED",
  "environment": "sandbox"
}

Details in Lifecycle simulators.

listen #

listen starts a server on 127.0.0.1 (port 8787 by default) that receives webhook deliveries and forwards them as is (raw body and headers, except hop-by-hop ones such as Host or Content-Length) to the URL you give it. It prints each delivery’s signature headers and returns to Compense the same code your receiver answered with (or 502 if it can’t reach it), so retries reflect what actually happened. Stop it with Ctrl-C.

Shell
compense listen --forward-to http://localhost:8000/compense/webhooks --port 8787

listen doesn’t use the key and doesn’t accept --key, --environment or --base-url: it only forwards. Since the sandbox doesn’t send webhooks and an endpoint must be public HTTPS, you need a tunnel and a production key in the dev environment; the step-by-step guide is in Testing your webhooks.

Differences between the Python and JavaScript CLIs #

The commands, options and exit codes are the same. The differences are minor:

PythonJavaScript
Executablecompensenpx compense (or compense if you install the package globally)
--versionDoesn’t existPrints the SDK version
Per-command helpcompense <command> --helpA single general help (--help or -h)
Option positionAfter the command (and after the action for clock / simulate)Anywhere
Connection error or timeoutShown by the interpreter (traceback)error: … and code 1