A headless stash for incoming requests.
Receive webhooks, stash raw HTTP requests, and stream events to your terminal, scripts, or AI agents.
External service → Barestash endpoint → Raw request stashed → CLI / JSONL stream
npm install -g @barestash/cliRequires Node.js 22.13 or later.
Create a temporary endpoint (no authentication required), watch for events, and send a test webhook:
# Create a temporary endpoint and store it as the CLI default
barestash endpoints create --temporary --set-default
# Watch incoming events using the stored default
barestash events tail
# In another terminal, send a test request to the webhook URL
curl -X POST https://ingest.example.com/ep_abc123/test \
-H 'content-type: application/json' \
-d '{"hello":"world"}'For private endpoints and long-lived workflows, authenticate with a scoped Personal Access Token (PAT) first. See Setting up authentication.
Commands follow a resource/action model:
barestash {resource} {action}
Resources: auth, endpoints, events, tokens
barestash --help
barestash events --helpbarestash events tail --endpoint ep_abc123
barestash events tail --endpoint ep_abc123 --last 10 --headers --bodyPress Ctrl+C to stop watching. The command exits successfully without an
additional message.
barestash events stream writes one JSON object per line to stdout. Pipe it into your tools:
barestash events stream --endpoint ep_abc123 | jq .Live streaming requires an authenticated private endpoint. For temporary
endpoints, use barestash events tail --endpoint ep_abc123.
Private live streams are subject to service concurrency and daily quotas. If
the concurrency limit is reached, close another live stream before retrying.
If the daily quota is reached, the CLI prints the API's UTC reset guidance and
Retry-After delay to stderr. An admission rejection leaves JSONL stdout empty
and exits non-zero without reconnecting. If an established stream closes at
the daily limit, the CLI makes its normal reconnect attempt and exits without
another reconnect when that attempt receives the quota rejection.
Press Ctrl+C to stop streaming. The command exits successfully without
adding a non-JSONL line to stdout or a diagnostic to stderr.
barestash events latest --endpoint ep_abc123
barestash events show evt_01JDEFbarestash endpoints create --name github-dev
barestash endpoints list
barestash endpoints show ep_abc123
barestash endpoints secrets create --endpoint ep_abc123| Command | Description |
|---|---|
barestash auth login |
Sign in through Barestash Device Authorization |
barestash auth login --with-token |
Validate and store a PAT from stdin |
barestash auth logout |
Remove locally stored credentials |
barestash auth logout --revoke |
Log out and revoke the current token |
barestash auth status |
Show authentication status (--json for machine output) |
Interactive login prints a one-time code, opens the approval page when possible, and polls at the interval selected by the API. The resulting one-hour access token is refreshed automatically from the rotating CLI session.
barestash auth login
echo "$BARESTASH_TOKEN" | barestash auth login --with-tokenCredentials use the OS credential store by default (Keychain, Credential
Manager, or Secret Service). If it is unavailable, the CLI warns and falls back
to a plaintext credential file protected with restrictive user-only
permissions. Pass --insecure-storage to select that plaintext file explicitly.
| Command | Description |
|---|---|
barestash tokens create |
Issue a scoped PAT (--name, --scope, --preset, --expires-in, --no-expiration, --json) |
barestash tokens list |
List token metadata (--all, --json) |
barestash tokens revoke <token-id> |
Revoke a token (--yes) |
PAT secrets are shown once at creation time. Save them immediately. The default
scope preset is full access and the default expiration is 90 days. Use
--preset read-only, repeat --scope, or explicitly opt into
--no-expiration as needed.
| Command | Description |
|---|---|
barestash endpoints create |
Create an endpoint (--private, --temporary, --name, --set-default, --json) |
barestash endpoints list |
List your endpoints (--json) |
barestash endpoints show <endpoint-id> |
Show endpoint details (--json) |
barestash endpoints delete <endpoint-id> |
Delete a private endpoint (--yes) |
barestash endpoints secrets create |
Create an ingest secret (--endpoint, --json) |
barestash endpoints secrets list |
List ingest secrets (--endpoint, --json) |
barestash endpoints secrets revoke <secret-id> |
Revoke an ingest secret (--endpoint, --yes) |
| Mode | TTL | Max events | Auth to create | Auth to read |
|---|---|---|---|---|
| Private (default) | 7 days | 1000 | Required | Required |
Temporary (--temporary) |
24 hours | 100 | Not required | REST/polling reads do not require auth; live SSE is unsupported |
Temporary endpoints are for short-term, non-sensitive debugging. Private endpoints support ingest secret verification via the x-barestash-secret header.
| Command | Description |
|---|---|
barestash events list |
List recent events (--endpoint, --limit, --json) |
barestash events latest |
Show the most recent event (--endpoint, --json) |
barestash events show <event-id> |
Show event details (--json) |
barestash events tail |
Follow new events (--endpoint, --last, --headers, --body, --view, --poll-interval) |
barestash events stream |
Stream events as JSON Lines (--endpoint) |
Sensitive headers such as Authorization and stripe-signature are shown as [REDACTED] in CLI output.
BARESTASH_TOKENenvironment variable- Credentials stored by
barestash auth loginorbarestash auth login --with-token
# Interactive CLI session
barestash auth login
# Store the token locally
export BARESTASH_TOKEN=bst_pat_...
echo "$BARESTASH_TOKEN" | barestash auth login --with-token
# Issue additional tokens for CI or agents
barestash tokens create \
--name ci-github \
--scope endpoints:read \
--scope events:read \
--expires-in 90dTemporary endpoints do not require authentication for supported REST and
polling reads when selected by --endpoint, BARESTASH_ENDPOINT, or the
stored local default. events stream requires a private endpoint.
| Variable | Description |
|---|---|
BARESTASH_API_URL |
Barestash API base URL (default: http://localhost:8787). Must use http: or https: without embedded credentials. Private and link-local addresses are rejected unless you pass --allow-insecure-api-url or set BARESTASH_ALLOW_INSECURE_API_URL=1. |
BARESTASH_ALLOW_INSECURE_API_URL |
Allow private or link-local BARESTASH_API_URL values. Equivalent to the global --allow-insecure-api-url flag. |
BARESTASH_TOKEN |
Scoped PAT or CLI access token for authenticated commands |
BARESTASH_ENDPOINT |
Default endpoint ID for commands that accept --endpoint |
BARESTASH_CONFIG_FILE |
Override path to the local config file |
Event and endpoint-secret commands that accept --endpoint resolve the target
endpoint in this order:
--endpoint <endpoint-id>flagBARESTASH_ENDPOINTenvironment variable- The local default set by
barestash endpoints create --set-default
If no endpoint is selected, the CLI prints an actionable error.
Non-secret configuration is stored in an OS-appropriate config directory:
| Platform | Path |
|---|---|
| macOS | ~/Library/Application Support/barestash/config.json |
| Linux | ~/.config/barestash/config.json |
| Windows | %APPDATA%\barestash\config.json |
Override with BARESTASH_CONFIG_FILE or XDG_CONFIG_HOME.
Secret credentials are stored in the OS credential store. Plaintext fallback
uses credentials.json beside the config file with mode 0600 on Unix-like
systems and a user-only ACL on Windows. Credential refresh and replacement use
a sibling lock file so multiple CLI processes cannot rotate the same refresh
token concurrently.
BARESTASH_API_URL controls where the CLI sends authenticated API requests.
Treat it like a secret-handling surface:
- Invalid schemes, embedded credentials, and private/link-local addresses are rejected before any authenticated request.
- Redirects are capped and re-validated so a compromised API cannot bounce the CLI toward metadata or internal-network hosts.
- The resolved API host is logged to stderr on first use, before API-backed result output or monitoring layouts are printed.
- Use
--allow-insecure-api-urlonly when you intentionally target a private API host on your network.
- Human-readable output is the default. Interactive terminals use color,
Unicode symbols, and tables sized to the terminal width. Redirected and
piped output, and terminals with
TERM=dumb, remain plain text. - Pass
--jsonfor structured output suitable for scripts. barestash events streamalways writes JSON Lines (NDJSON) to stdout for machine consumers.- Set
NO_COLORto disable ANSI color without disabling the interactive layout.
Keep stdout reserved for structured data. Diagnostic messages go to stderr.
Use the optional live dashboard when following events in an interactive terminal:
barestash events tail --viewThe dashboard redraws the terminal with the endpoint status, received count,
latest event time, and recent events. It uses a compact table on narrow
terminals, tracks terminal resizes, and limits visible events to the detected
terminal height. Stop it with Ctrl+C. Because the dashboard requires
terminal control, --view is unavailable when stdout is redirected or piped,
or when TERM=dumb, and cannot be combined with --headers or --body.
- Repository: github.com/barestashhq/cli
- CLI design specification: docs/cli-design.md
- Security policy: SECURITY.md
The repository uses pnpm workspaces and provides a Nix/direnv development
environment. Use just as the command entrypoint:
just install
just check
just packagepackages/protocol is a private build-time workspace package containing
only the API contracts and portable helpers needed by the CLI. It is bundled
into dist/barestash.js and is not a runtime dependency of the published npm
package.