CLI reference
Every hookchat command with its usage, flags and examples, generated from docs/cli/reference.md (itself written by hookchat docs generate). Install the binary from the downloads page.
Global flags#
These flags are accepted by every command.
| Flag | Type | Default | Description |
|---|---|---|---|
--api-key | string | API key (hookchat_live_... or hookchat_test_...); overrides HOOKCHAT_API_KEY and the profile | |
--base-url | string | API origin; overrides HOOKCHAT_BASE_URL and the profile (default https://hookchat.dev) | |
--no-color | bool | disable colour even when stdout is a terminal | |
-o, --output | string | table | output format: table, json or yaml |
--profile | string | config profile to use; overrides HOOKCHAT_PROFILE (default "default") | |
-q, --quiet | bool | print only ids or values, nothing else on success | |
--tenant | string | tenant slug, required for an operator key; overrides HOOKCHAT_TENANT and the profile | |
--timeout | duration | 30s | per-request timeout |
Commands#
hookchat#
The HookChat command line: Instagram and Messenger DMs as webhooks
hookchat [command]hookchat is the command line for the HookChat API. Every /v1 resource has a command: keys, webhooks and their deliveries, conversations, messages, accounts, the audit trail, stats and realtime tickets. It also verifies captured webhook deliveries offline and manages login profiles.
Authentication resolves in this order: the --api-key, --base-url and --tenant flags, then the HOOKCHAT_API_KEY, HOOKCHAT_BASE_URL and HOOKCHAT_TENANT environment variables, then the profile selected by --profile or HOOKCHAT_PROFILE (or the default profile) in the config file written by "hookchat auth login". The config file lives at $HOOKCHAT_CONFIG_DIR/config.json or <user config dir>/hookchat/config.json and is created with mode 0600.
Output is a table by default. --output json prints the API resource (a list is a JSON array, or {"items": [...], "next_cursor": "..."} when a page follows) and --output yaml prints the same shape as YAML. --quiet prints only ids, or the secret for keys create, webhooks create and webhooks rotate. Colour is used only when stdout is a terminal, NO_COLOR is unset and --no-color is not given.
0 success
1 unexpected error
2 usage error: unknown command, flag or argument
3 authentication: unauthorized, forbidden, tenant_required, or no API key configured
4 not found: conversation, message, endpoint, key or delivery
5 invalid_request: a malformed body or parameter
6 send policy: window_closed, human_agent_unavailable or missing_actor
7 rate_limited: the send budget is exhausted or the gateway returned 429
8 send_failed or replay_conflict
9 webhook signature verification failed (verify)
10 network error, timeout or a 5xx without an error envelope# Check the gateway and your credentials
hookchat auth login --api-key hookchat_test_... --tenant acme
hookchat ping
# Register a webhook and capture its secret
hookchat webhooks create --url https://example.com/hookchat --output json
# Reply inside the 24 hour window
hookchat messages reply --conversation "CONV#acme#instagram#1#2" --text "On it"Subcommands
- hookchat accounts: List the tenant's linked channel accounts
- hookchat audit: Read the tenant's audit trail
- hookchat auth: Log in, inspect and remove credential profiles
- hookchat completion: Print a shell completion script
- hookchat conversations: Read the unified inbox
- hookchat docs: Generate and check the command reference
- hookchat keys: Create, list and revoke API keys
- hookchat messages: Read the message feed and send replies
- hookchat ping: Check that the gateway is reachable
- hookchat realtime: Mint websocket connect tickets
- hookchat stats: Show the tenant's overview counts
- hookchat verify: Verify a captured webhook delivery offline
- hookchat version: Print the CLI version
- hookchat webhooks: Manage webhook endpoints and their deliveries
hookchat accounts#
List the tenant's linked channel accounts
hookchat accounts [command]The Instagram and Messenger accounts linked to the tenant, with their credential health. An account with a refresh_error needs relinking in the console.
# Linked accounts
hookchat accounts list
# Only the account keys
hookchat accounts list --quietSubcommands
- hookchat accounts list: List linked accounts and their credential health
hookchat accounts list#
List linked accounts and their credential health
hookchat accounts listCalls GET /v1/accounts. The list is not paginated. Each row carries the platform, the external id, the handle, the status (active, disabled or error) and the last refresh error, if any.
# Linked accounts as a table
hookchat accounts list
# Find accounts that need relinking
hookchat accounts list --output json | jq '.[] | select(.refresh_error)'hookchat audit#
Read the tenant's audit trail
hookchat audit [command]The audit trail records every administrative action on the tenant: key creation and revocation, webhook changes, replays and sends. Entries never carry message content, tokens or secrets.
# The most recent 50 entries
hookchat audit list
# Everything, as JSON
hookchat audit list --all --output jsonSubcommands
- hookchat audit list: List audit entries, most recent first
hookchat audit list#
List audit entries, most recent first
hookchat audit list [flags]Calls GET /v1/audit. One page is printed by default; the next_cursor goes to stderr in table mode and into the JSON or YAML envelope otherwise. --all walks every page.
# One page of 20
hookchat audit list --limit 20
# Continue from a cursor
hookchat audit list --cursor eyJ...
# Every entry
hookchat audit list --allFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--all | bool | walk every page instead of printing one page and its next_cursor | |
--cursor | string | resume from a previous next_cursor | |
--limit | int | 50 | page size, 1 to 100 (with --all, the page size used while walking) |
hookchat auth#
Log in, inspect and remove credential profiles
hookchat auth [command]Profiles store an API key, a base URL and a tenant in the config file so the other commands need no flags. The file is $HOOKCHAT_CONFIG_DIR/config.json or <user config dir>/hookchat/config.json, created with mode 0600. A profile is selected with --profile or HOOKCHAT_PROFILE; "default" is used otherwise. Flags and environment variables always override a profile.
# Store a key as the default profile
hookchat auth login --api-key hookchat_test_... --tenant acme
# Keep a second workspace in its own profile
hookchat auth login --profile acme --tenant acme --api-key hookchat_live_...
hookchat --profile acme pingSubcommands
- hookchat auth login: Validate an API key and store it as a profile
- hookchat auth logout: Remove a profile from the config file
- hookchat auth status: Show the active profile and ping the gateway
hookchat auth login#
Validate an API key and store it as a profile
hookchat auth login [flags]Reads the key from --api-key, or from standard input when the flag is absent (a prompt is shown when stdin is a terminal, so the key never lands in shell history). The key and base URL are validated with a ping, then written to the profile named by --profile (default "default") together with --base-url and --tenant. The first profile written becomes the default profile; pass --set-default to make any later profile the default.
The full key is never printed; status shows a masked prefix only.
# Store the key with a tenant
hookchat auth login --api-key hookchat_live_... --tenant acme
# Read the key from a secret manager without echoing it
op read op://vault/hookchat/key | hookchat auth login --tenant acme
# A second workspace profile, made the default
hookchat auth login --profile acme --tenant acme --set-defaultFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--set-default | bool | make this profile the default profile |
hookchat auth logout#
Remove a profile from the config file
hookchat auth logoutDeletes the profile named by --profile (or HOOKCHAT_PROFILE, or the default profile) from the config file. The key itself is not revoked; use "hookchat keys revoke" for that. Removing the default profile makes the next remaining profile the default.
# Remove the default profile
hookchat auth logout
# Remove a named profile
hookchat auth logout --profile acmehookchat auth status#
Show the active profile and ping the gateway
hookchat auth statusShows which profile is active, where the key came from (flags, environment or the profile), the masked key prefix, the base URL and the tenant, then pings the gateway. The exit code follows the ping, so status doubles as a health check in scripts.
# Human readable status
hookchat auth status
# Machine readable, including the ping result
hookchat auth status --output jsonhookchat completion#
Print a shell completion script
hookchat completion bash|zsh|fish|powershellPrints a completion script for the named shell. Load it in your shell's startup file to complete commands and flags:
bash source <(hookchat completion bash)
zsh hookchat completion zsh > "${fpath[1]}/_hookchat"
fish hookchat completion fish > ~/.config/fish/completions/hookchat.fish
powershell hookchat completion powershell | Out-String | Invoke-Expression# Bash, for the current session
source <(hookchat completion bash)
# Zsh, installed permanently
hookchat completion zsh > "${fpath[1]}/_hookchat"hookchat conversations#
Read the unified inbox
hookchat conversations [command]A conversation is one thread between a linked account and a participant. The gateway computes each thread's messaging window (open_24h, human_agent_only or closed) and the can_reply and can_send_as_human_agent flags; consumers never recompute them. Conversation ids contain "#" separators, so quote them in the shell.
# Threads waiting for an answer
hookchat conversations list --output json | jq '.[] | select(.unanswered)'
# One thread with its recent messages
hookchat conversations get "CONV#acme#instagram#1#2"Subcommands
- hookchat conversations get: Show one conversation and its recent messages
- hookchat conversations list: List conversations, most recently active first
hookchat conversations get#
Show one conversation and its recent messages
hookchat conversations get <id> [flags]Calls GET /v1/conversations/:id. The id is URL-encoded for you. The table shows the conversation's window and flags followed by its bounded thread history; json and yaml print {"conversation": ..., "messages": [...]}. --include-test adds rows written by test-scope keys.
# A thread, including test-key rows
hookchat conversations get "CONV#acme#instagram#1#2" --include-test
# Just the window state
hookchat conversations get "CONV#acme#instagram#1#2" --output json | jq -r .conversation.window.stateFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--include-test | bool | include rows written by test-scope keys |
hookchat conversations list#
List conversations, most recently active first
hookchat conversations list [flags]Calls GET /v1/conversations. One page is printed by default with the next_cursor on stderr (table) or in the envelope (json, yaml); --all walks every page. The list is the inbox feed: live rows only.
# The first page of 50
hookchat conversations list
# Every conversation, ids only
hookchat conversations list --all --quiet
# Threads that can still be replied to
hookchat conversations list --output json | jq '.[] | select(.can_reply) | .id'Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--all | bool | walk every page instead of printing one page and its next_cursor | |
--cursor | string | resume from a previous next_cursor | |
--limit | int | 50 | page size, 1 to 100 (with --all, the page size used while walking) |
hookchat docs#
Generate and check the command reference
hookchat docs [command]The command reference is a single Markdown file generated from the command tree: every command's synopsis, description, examples and flags. It is committed at docs/cli/reference.md and a test fails when it is stale.
# Regenerate the reference after changing a command
hookchat docs generate --out docs/cli/reference.md
# Fail CI when the committed reference is stale
hookchat docs checkSubcommands
- hookchat docs check: Exit 1 when the committed reference is stale
- hookchat docs generate: Write the Markdown command reference
hookchat docs check#
Exit 1 when the committed reference is stale
hookchat docs check [flags]Generates the reference in memory and compares it with the file. A difference exits 1 with a message telling you to run "hookchat docs generate".
# Check the committed file
hookchat docs check
# Check another path
hookchat docs check --file build/reference.mdFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--file | string | docs/cli/reference.md | the reference file to compare |
hookchat docs generate#
Write the Markdown command reference
hookchat docs generate [flags]Walks the command tree and writes one Markdown file with the global flags, then a section per command with its synopsis, description, examples and flags. With --out - the reference is written to stdout.
# Write the committed reference
hookchat docs generate --out docs/cli/reference.md
# Preview on stdout
hookchat docs generate --out -Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--out | string | docs/cli/reference.md | output path, or - for stdout |
hookchat keys#
Create, list and revoke API keys
hookchat keys [command]API keys are bound to a tenant and carry a scope: live keys send real messages, test keys route sends through the mock connection and write rows that reads only see with --include-test. A key inherits the caller's scope unless --scope is given, and a test key cannot mint a live key.
# Mint a test key for CI
hookchat keys create --label ci --scope test
# Revoke it later
hookchat keys revoke 01ARZ3NDEKTSV4RRFFQ69G5FAVSubcommands
- hookchat keys create: Mint a new API key
- hookchat keys list: List the tenant's API keys
- hookchat keys revoke: Revoke an API key
hookchat keys create#
Mint a new API key
hookchat keys create [flags]Calls POST /v1/keys. The plaintext secret is returned exactly once; store it now, no read path returns it again. --quiet prints only the secret, which suits shell capture.
# A labelled live key
hookchat keys create --label "billing worker" --scope live
# Capture a test key in a script
KEY=$(hookchat keys create --label ci --scope test --quiet)Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--label | string | display label (default "key for <tenant>") | |
--scope | string | key scope: live or test (default: the caller's scope) |
hookchat keys list#
List the tenant's API keys
hookchat keys listCalls GET /v1/keys. Only the display prefix of each key is returned, never a secret. Revoked keys stay in the list with status revoked.
# All keys as a table
hookchat keys list
# Only active key ids
hookchat keys list --output json | jq -r '.[] | select(.status == "active") | .id'hookchat keys revoke#
Revoke an API key
hookchat keys revoke <id>Calls DELETE /v1/keys/:id. Revoking an already revoked key succeeds; an unknown or cross-tenant id is key_not_found (exit 4).
# Revoke by id
hookchat keys revoke 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Revoke every key with a label, quietly
hookchat keys list --output json | jq -r '.[] | select(.label == "ci") | .id' | xargs -n1 hookchat keys revoke --quiethookchat messages#
Read the message feed and send replies
hookchat messages [command]There are exactly two send paths and no generic send. "reply" works inside the 24 hour window after the participant's last message. "human-agent" works from 24 hours to 7 days and must name the human who wrote the message with --actor. Past 7 days nothing can be sent. The gateway enforces the policy and answers window_closed, human_agent_unavailable or missing_actor (exit 6).
# Reply inside the window
hookchat messages reply --conversation "CONV#acme#instagram#1#2" --text "Thanks, on it"
# Follow up as a named human after 24 hours
hookchat messages human-agent --conversation "CONV#acme#instagram#1#2" --text "Any update?" --actor user_42Subcommands
- hookchat messages get: Show one message by its platform id
- hookchat messages human-agent: Send a human-typed message in the 24 hour to 7 day window
- hookchat messages list: List messages, newest first
- hookchat messages reply: Send a reply inside the 24 hour window
hookchat messages get#
Show one message by its platform id
hookchat messages get <id> [flags]Calls GET /v1/messages/:id. The id is the platform's own message id (mid). A message written by a test-scope key is found only with --include-test.
# One message
hookchat messages get mid_abc123
# A message sent under a test key
hookchat messages get mid_abc123 --include-test --output jsonFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--include-test | bool | include rows written by test-scope keys |
hookchat messages human-agent#
Send a human-typed message in the 24 hour to 7 day window
hookchat messages human-agent [flags]Calls POST /v1/messages/human-agent. --actor names the human who wrote the message and is required: the gateway refuses a send without it with missing_actor (exit 6). Past 7 days the gateway answers human_agent_unavailable (exit 6) and nothing can be sent.
# A follow up from a named agent
hookchat messages human-agent --conversation "CONV#acme#instagram#1#2" --text "Any update?" --actor user_42
# With an attachment
hookchat messages human-agent --conversation "CONV#acme#instagram#1#2" --attachment file=https://example.com/quote.pdf --actor user_42Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--actor | string | id of the human who wrote the message (required) | |
--attachment | strings | attachment as <type>=<url>; repeatable | |
--conversation | string | conversation id (required) | |
--reply-to | string | platform message id to reply to | |
--text | string | message text |
hookchat messages list#
List messages, newest first
hookchat messages list [flags]Calls GET /v1/messages, the tenant-wide feed. --conversation narrows it to one thread and --direction to inbound or outbound. Rows written by test-scope keys appear only with --include-test. A filtered page may be short and still carry a next_cursor.
# The last 50 messages across the tenant
hookchat messages list
# One thread, inbound only, including test rows
hookchat messages list --conversation "CONV#acme#instagram#1#2" --direction inbound --include-test
# Every message in a thread as JSON
hookchat messages list --conversation "CONV#acme#instagram#1#2" --all --output jsonFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--all | bool | walk every page instead of printing one page and its next_cursor | |
--conversation | string | restrict to one conversation id | |
--cursor | string | resume from a previous next_cursor | |
--direction | string | restrict to one direction: inbound or outbound | |
--include-test | bool | include rows written by test-scope keys | |
--limit | int | 50 | page size, 1 to 100 (with --all, the page size used while walking) |
hookchat messages reply#
Send a reply inside the 24 hour window
hookchat messages reply [flags]Calls POST /v1/messages/reply. Text, attachments or both may be sent; an attachment is <type>=<url> where type is image, video, audio or file and Meta fetches the URL. Outside the 24 hour window the gateway refuses with window_closed (exit 6); check the conversation's can_send_as_human_agent flag and use "messages human-agent" when it is true.
# A text reply
hookchat messages reply --conversation "CONV#acme#instagram#1#2" --text "Thanks, on it"
# An image with a caption, replying to a specific message
hookchat messages reply --conversation "CONV#acme#instagram#1#2" --text "Here you go" --attachment image=https://example.com/a.png --reply-to mid_123
# Only the platform message id
hookchat messages reply --conversation "CONV#acme#instagram#1#2" --text "Hi" --quietFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--attachment | strings | attachment as <type>=<url>; repeatable | |
--conversation | string | conversation id (required) | |
--reply-to | string | platform message id to reply to | |
--text | string | message text |
hookchat ping#
Check that the gateway is reachable
hookchat pingCalls GET /v1/ping and prints the gateway's name, version and clock. The route is unauthenticated, so ping works before any key is configured; when a key is configured it is sent anyway, which makes ping a quick check of the base URL a profile points at.
# Ping the production gateway
hookchat ping
# Ping a local gateway as JSON
hookchat ping --base-url http://localhost:3000 --output jsonhookchat realtime#
Mint websocket connect tickets
hookchat realtime [command]A browser cannot set an Authorization header on a websocket upgrade, so the realtime socket is opened with a short-lived, single-use ticket minted here and passed in the socket URL.
# Mint a ticket
hookchat realtime ticket
# Just the ticket value, for a script
hookchat realtime ticket --quietSubcommands
- hookchat realtime ticket: Mint a short-lived websocket connect ticket
hookchat realtime ticket#
Mint a short-lived websocket connect ticket
hookchat realtime ticketCalls POST /v1/realtime/ticket. The ticket is single use, bound to the tenant, and expires within about a minute; open the socket before expires_at.
# Mint a ticket and show its expiry
hookchat realtime ticket
# Feed the ticket to another tool
TICKET=$(hookchat realtime ticket --quiet)hookchat stats#
Show the tenant's overview counts
hookchat statsCalls GET /v1/stats: messages in the last 24 hours, the DLQ total and the per-endpoint delivered, failed and dlq counts over the reported window.
# Overview as a table
hookchat stats
# Overview as JSON, for a dashboard
hookchat stats --output jsonhookchat verify#
Verify a captured webhook delivery offline
hookchat verify --secret <whs_...> [--file <path>] [flags]Checks a delivery's HookChat-Signature header against the signing secret and prints the event it carries. The input is a JSON document of the form {"headers": {...}, "body": "<raw body>"} with lowercased header names, which is what a capture receiver stores, read from --file or standard input. With --raw the input is the raw body itself and the headers are passed with --header "HookChat-Signature: t=...,v1=...".
The signature is HMAC-SHA256 over "<t>.<body>" with the exact body bytes; during a secret rotation the header carries two v1 values and either secret verifies. A timestamp further than --tolerance from now is rejected. A signature failure exits 9; a body that verifies but is not a HookChat event exits 1.
# A delivery captured as JSON
hookchat verify --secret whs_... --file delivery.json
# Piped from a capture receiver
curl -s http://localhost:4100/deliveries | jq '.[0]' | hookchat verify --secret whs_...
# A raw body with its signature header
hookchat verify --secret whs_... --raw --header "HookChat-Signature: t=1756900000,v1=ab12..." --file body.json
# An old fixture, ignoring the timestamp check
hookchat verify --secret whs_... --file delivery.json --tolerance 87600hFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--file | string | read the input from this file instead of stdin | |
--header | strings | a header as "Name: value", repeatable; only with --raw | |
--raw | bool | the input is the raw body; pass headers with --header | |
--secret | string | the endpoint's whs_ signing secret (required) | |
--tolerance | duration | 5m0s | maximum age of the delivery timestamp |
hookchat version#
Print the CLI version
hookchat versionPrints the hookchat CLI version. With --output json or yaml it also reports the Go toolchain, operating system and CPU architecture the binary was built for, which is useful in a bug report.
# Just the version
hookchat version
# Version plus build details
hookchat version --output jsonhookchat webhooks#
Manage webhook endpoints and their deliveries
hookchat webhooks [command]A webhook endpoint is an HTTPS URL the gateway POSTs signed events to. Create returns the whs_ signing secret exactly once; rotate mints a new one while the old one keeps signing for a 24 hour overlap. Test sends a test.event through the real delivery path, and the deliveries subcommands inspect and replay the delivery log.
# Register an endpoint for two event types
hookchat webhooks create --url https://example.com/hookchat --events message.received,message.failed
# Prove the receiver verifies signatures
hookchat webhooks test 01ARZ3NDEKTSV4RRFFQ69G5FAV
hookchat webhooks deliveries list 01ARZ3NDEKTSV4RRFFQ69G5FAVSubcommands
- hookchat webhooks create: Register an endpoint and mint its signing secret
- hookchat webhooks delete: Delete an endpoint
- hookchat webhooks deliveries: Inspect and replay an endpoint's deliveries
- hookchat webhooks get: Show one endpoint
- hookchat webhooks list: List the tenant's live endpoints
- hookchat webhooks rotate: Mint a new signing secret with a 24 hour overlap
- hookchat webhooks test: Send a test.event through the real delivery path
- hookchat webhooks update: Change an endpoint's URL or events, or pause and resume it
hookchat webhooks create#
Register an endpoint and mint its signing secret
hookchat webhooks create [flags]Calls POST /v1/webhooks. The URL must be HTTPS on a public host (the gateway rejects private and loopback addresses with invalid_request and the reason in detail). --events restricts the subscription; omit it for every event type. The whs_ signing secret is shown exactly once; --quiet prints only the secret.
# Every event type
hookchat webhooks create --url https://example.com/hookchat
# Only inbound messages and failures, as JSON to capture id and secret
hookchat webhooks create --url https://example.com/hookchat --events message.received,message.failed --output json
# Capture the secret directly
SECRET=$(hookchat webhooks create --url https://example.com/hookchat --quiet)Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--events | strings | event types to subscribe to, comma separated (default: all) | |
--url | string | HTTPS endpoint the gateway POSTs deliveries to (required) |
hookchat webhooks delete#
Delete an endpoint
hookchat webhooks delete <id>Calls DELETE /v1/webhooks/:id. The endpoint is tombstoned: its signing material is erased while its id and delivery history are kept. A second delete of the same endpoint is a no-op success.
# Delete by id
hookchat webhooks delete 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Delete every endpoint pointing at a host
hookchat webhooks list --output json | jq -r '.[] | select(.url | contains("old.example.com")) | .id' | xargs -n1 hookchat webhooks delete --quiethookchat webhooks deliveries#
Inspect and replay an endpoint's deliveries
hookchat webhooks deliveries [command]Every event delivered to an endpoint is logged with its status: pending, attempting, retrying, delivered, failed, blocked or dlq. list pages the log, summary aggregates the failing rows server side, replay re-drives one delivery and replay-all re-drives every failing delivery in a time window. Delivery timestamps are epoch milliseconds in the API; tables show them as RFC 3339.
# What failed in the last 24 hours
hookchat webhooks deliveries summary 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Re-drive everything that failed since the outage
hookchat webhooks deliveries replay-all 01ARZ3NDEKTSV4RRFFQ69G5FAV --from 6hSubcommands
- hookchat webhooks deliveries list: List an endpoint's deliveries, newest first
- hookchat webhooks deliveries replay: Re-drive one delivery on a fresh attempt budget
- hookchat webhooks deliveries replay-all: Re-drive every failing delivery in a time window
- hookchat webhooks deliveries summary: Aggregate an endpoint's failing deliveries
hookchat webhooks deliveries list#
List an endpoint's deliveries, newest first
hookchat webhooks deliveries list <endpointId> [flags]Calls GET /v1/webhooks/:id/deliveries. One page is printed by default with the next_cursor on stderr (table) or in the envelope (json, yaml); --all walks every page. --status keeps only the named statuses; the filter is applied by the CLI after fetching, so a filtered page may be short. An endpoint id that does not exist under the tenant yields an empty list rather than endpoint_not_found.
# The latest page
hookchat webhooks deliveries list 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Only failed and dlq rows, across every page
hookchat webhooks deliveries list 01ARZ3NDEKTSV4RRFFQ69G5FAV --status failed,dlq --all
# Delivery ids only, for replay scripts
hookchat webhooks deliveries list 01ARZ3NDEKTSV4RRFFQ69G5FAV --status dlq --all --quietFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--all | bool | walk every page instead of printing one page and its next_cursor | |
--cursor | string | resume from a previous next_cursor | |
--limit | int | 50 | page size, 1 to 100 (with --all, the page size used while walking) |
--status | strings | keep only these statuses, comma separated (pending, attempting, retrying, delivered, failed, blocked, dlq) |
hookchat webhooks deliveries replay#
Re-drive one delivery on a fresh attempt budget
hookchat webhooks deliveries replay <endpointId> <deliveryId> [flags]Calls POST /v1/webhooks/:id/deliveries/:deliveryId/replay. A delivery that already succeeded is refused with replay_conflict (exit 8) unless --force is given, in which case the receiver sees a duplicate event id (dedupe on it). A delivery that is mid-attempt is always refused.
# Replay a failed delivery
hookchat webhooks deliveries replay 01ARZ3NDEKTSV4RRFFQ69G5FAV 01J8ZK3M...
# Re-send a delivered one anyway
hookchat webhooks deliveries replay 01ARZ3NDEKTSV4RRFFQ69G5FAV 01J8ZK3M... --forceFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--force | bool | replay even if the delivery already succeeded |
hookchat webhooks deliveries replay-all#
Re-drive every failing delivery in a time window
hookchat webhooks deliveries replay-all <endpointId> [flags]Calls POST /v1/webhooks/:id/deliveries/replay. --from is required and --to defaults to now; both accept an RFC 3339 time, a date, a unix epoch or an age such as 6h. The default statuses are dlq and failed; including delivered requires --force (exit 8 otherwise). The batch is bounded: a short page returns a next_cursor, printed on stderr in table mode. --all keeps going until the batch is exhausted and prints the summed counts.
# Everything that failed in the last 6 hours
hookchat webhooks deliveries replay-all 01ARZ3NDEKTSV4RRFFQ69G5FAV --from 6h
# A precise window, dlq only, walking every batch page
hookchat webhooks deliveries replay-all 01ARZ3NDEKTSV4RRFFQ69G5FAV --from 2026-09-03T00:00:00Z --to 2026-09-03T06:00:00Z --status dlq --all
# Re-send delivered events too (receivers see duplicate event ids)
hookchat webhooks deliveries replay-all 01ARZ3NDEKTSV4RRFFQ69G5FAV --from 1h --status delivered --forceFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--all | bool | keep replaying until the batch is exhausted | |
--cursor | string | continue a batch from a previous next_cursor | |
--force | bool | allow delivered deliveries to be re-sent | |
--from | string | start of the window: RFC 3339, a date, a unix epoch or an age such as 6h (required) | |
--limit | int | batch page size, 1 to 100 (default: server default) | |
--status | strings | statuses to replay, comma separated (default: dlq,failed; delivered needs --force) | |
--to | string | end of the window, same forms as --from (default: now) |
hookchat webhooks deliveries summary#
Aggregate an endpoint's failing deliveries
hookchat webhooks deliveries summary <endpointId> [flags]Calls GET /v1/webhooks/:id/deliveries/summary. By default it covers the last 24 hours and the statuses dlq, failed, blocked and retrying. --since accepts an RFC 3339 time, a date, a unix epoch or an age such as 6h. When the examined-row cap is hit the result is marked truncated and older failures may be missing.
# Failures in the last 24 hours
hookchat webhooks deliveries summary 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Only dlq rows from the last 6 hours
hookchat webhooks deliveries summary 01ARZ3NDEKTSV4RRFFQ69G5FAV --since 6h --status dlqFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--since | string | start of the window: RFC 3339, a date, a unix epoch or an age such as 6h (default: 24h) | |
--status | strings | statuses to include, comma separated (default: dlq,failed,blocked,retrying) |
hookchat webhooks get#
Show one endpoint
hookchat webhooks get <id>Calls GET /v1/webhooks/:id. A deleted or cross-tenant id is endpoint_not_found (exit 4).
# One endpoint
hookchat webhooks get 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Is a rotation overlap still active?
hookchat webhooks get 01ARZ3NDEKTSV4RRFFQ69G5FAV --output json | jq .secondary_activehookchat webhooks list#
List the tenant's live endpoints
hookchat webhooks listCalls GET /v1/webhooks. Deleted endpoints are not listed. No secret is ever returned, only a display prefix of the current one.
# Endpoints as a table
hookchat webhooks list
# Paused endpoints
hookchat webhooks list --output json | jq '.[] | select(.status == "paused")'hookchat webhooks rotate#
Mint a new signing secret with a 24 hour overlap
hookchat webhooks rotate <id>Calls POST /v1/webhooks/:id/rotate. The new whs_ secret is shown exactly once. The previous secret keeps signing for 24 hours, during which every delivery carries two v1 signatures, so a receiver holding either secret keeps verifying while you roll the new one out.
# Rotate and show the new secret
hookchat webhooks rotate 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Capture the new secret for a secret manager
NEW=$(hookchat webhooks rotate 01ARZ3NDEKTSV4RRFFQ69G5FAV --quiet)hookchat webhooks test#
Send a test.event through the real delivery path
hookchat webhooks test <id>Calls POST /v1/webhooks/:id/test. The event is signed and delivered asynchronously like any other; poll "webhooks deliveries list" or your receiver for the delivery id printed here. --quiet prints nothing on success.
# Send a test event
hookchat webhooks test 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Send one and wait for the delivery to settle
hookchat webhooks test 01ARZ3NDEKTSV4RRFFQ69G5FAV --output json | jq -r .delivery_idhookchat webhooks update#
Change an endpoint's URL or events, or pause and resume it
hookchat webhooks update <id> [flags]Calls PATCH /v1/webhooks/:id with only the fields given. --events replaces the subscription filter and --all-events clears it. --disabled pauses deliveries (they queue as pending) and --enabled resumes them. At least one change is required.
# Move an endpoint to a new URL
hookchat webhooks update 01ARZ3NDEKTSV4RRFFQ69G5FAV --url https://example.com/v2/hookchat
# Pause it during a deploy, then resume
hookchat webhooks update 01ARZ3NDEKTSV4RRFFQ69G5FAV --disabled
hookchat webhooks update 01ARZ3NDEKTSV4RRFFQ69G5FAV --enabled
# Subscribe to everything again
hookchat webhooks update 01ARZ3NDEKTSV4RRFFQ69G5FAV --all-eventsFlags
| Flag | Type | Default | Description |
|---|---|---|---|
--all-events | bool | clear the event filter (subscribe to every event) | |
--disabled | bool | pause deliveries (status paused) | |
--enabled | bool | resume deliveries (status active) | |
--events | strings | new event type filter, comma separated | |
--url | string | new HTTPS endpoint URL |