// Tools

xeroctl webhooks

Subscribe an HTTPS endpoint to project events, fire a test delivery, and audit the delivery log.

Signing secret is returned exactly once at create. Thirty-two event types across eight families: batch, response, file, conversation, exec, agent, join_key, ox.

Overview

  • Delivery: POST over HTTPS with a JSON body. 2xx within 10 s counts as success.
  • Signature: HMAC-SHA256(secret, timestamp + "." + body), hex-encoded, sent as X-Webhook-Signature.
  • Replay defence: subscribers must reject deliveries with X-Webhook-Timestamp older than five minutes.
  • Retry policy: exponential backoff up to six attempts, terminal state exhausted; visible via --deliveries.
  • Test rate: --test is capped at 10 invocations per hour per webhook.

The webhooks command uses one positional ID plus one action flag (--create, --update, --delete, --test, --deliveries). Action flags are mutually exclusive; omit them all and the command lists.

Usage Pattern

bash
xeroctl webhooks # List all webhooks xeroctl webhooks <uuid> # Show webhook details xeroctl webhooks --create --url <url> --events <e> # Create a webhook xeroctl webhooks <uuid> --update --url <url> # Update a webhook xeroctl webhooks <uuid> --delete # Delete a webhook xeroctl webhooks <uuid> --test # Send a test event xeroctl webhooks <uuid> --deliveries # List delivery history

list

List all webhook subscriptions for the project. This is the default action when no ID or action flag is given.

bash
xeroctl webhooks xeroctl webhooks --limit 50 xeroctl webhooks --after 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10

Options

Option Description
--limit <n> Maximum number of results (default 20, server cap 100)
--after <cursor> Pagination cursor: webhook UUID to start after

Output columns: ID, URL, EVENTS, ACTIVE, CREATED. Webhook IDs are bare UUIDs (no whk_ prefix).

get

Show details of a specific webhook subscription. Provides URL, subscribed events, active state, and creation and update timestamps. The signing secret is not displayed here: it is returned exactly once in the create response and never re-exposed. If you lost it, delete the webhook and create a new one.

bash
xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 -o json

create

Create a new webhook subscription. Both --url and --events are required. The webhook is active by default unless --inactive is specified.

bash
# Create a webhook for batch events xeroctl webhooks --create \ --url https://example.com/hooks/xerotier \ --events batch.completed,batch.failed # Create in inactive state xeroctl webhooks --create \ --url https://example.com/hooks/xerotier \ --events response.completed,response.failed \ --inactive # Dry-run (validate without creating) xeroctl webhooks --create \ --url https://example.com/hooks/xerotier \ --events agent.enrolled \ --dry-run

Options

Option Description
--url <url> Webhook delivery URL (required)
--events <events> Comma-separated event types to subscribe to (required)
--active Set webhook to active state (default)
--inactive Create webhook in inactive state
--dry-run Validate inputs and show what would be created without persisting

Signing secret: The server auto-generates a 32-byte hex signing secret when the webhook is created and returns it exactly once in the create response. Store it immediately; subsequent xeroctl webhooks <id> calls will not display it. The signing secret cannot be supplied or rotated; to change it, delete the webhook and create a new one.

Delivery Headers

Every delivery carries three vendor headers in addition to Content-Type: application/json. Subscribers verify by recomputing the HMAC and comparing in constant time.

Header Value
X-Webhook-ID UUID of the delivery attempt (not the webhook). Use as an idempotency key.
X-Webhook-Timestamp Unix epoch seconds at signing time. Reject deliveries older than five minutes.
X-Webhook-Signature HMAC-SHA256(secret, timestamp + "." + raw_body), hex-encoded.

Payload envelope (id, object, type, created_at, data) and verification snippets in Python, Node, and Swift are documented in the Webhooks API reference.

update

Update an existing webhook. All fields are optional, only the provided fields are changed.

bash
# Update the URL xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --update --url https://new.example.com/hook # Change subscribed events xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --update --events response.completed,batch.completed,file.uploaded # Activate or deactivate xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --update --active xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --update --inactive # Dry-run (preview the change without persisting) xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --update --inactive --dry-run

Options

Option Description
--url <url> New webhook delivery URL
--events <events> Comma-separated replacement event type list
--active Set webhook to active
--inactive Set webhook to inactive
--dry-run Show what would change without persisting the update

State flag conflict: --active and --inactive cannot be used together. (Action-flag exclusivity is covered in Overview.)

Cannot change the signing secret: Update does not accept a --secret flag and the server has no field to change the signing secret. To rotate, delete the webhook and create a new one (the create response will return the new secret exactly once).

delete

Delete a webhook subscription. A confirmation prompt is shown by default.

bash
# With confirmation prompt xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --delete # Skip confirmation xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --delete --force # Dry run xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --delete --dry-run

Options

Option Description
--force Skip the confirmation prompt
--dry-run Show what would be deleted without making changes

test

Send a test event to the webhook endpoint. Useful for verifying connectivity and payload handling before relying on live events.

bash
xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --test

On success, the command prints the HTTP status code returned by your endpoint. On failure, an error message is displayed.

Dry run: Passing --dry-run will show what would happen without sending the test event.

Rate limit: The test endpoint is rate-limited to 10 invocations per hour per webhook.

deliveries

List the delivery history for a webhook. Shows each delivery attempt with event type, HTTP status code, success status, and timestamp.

bash
xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --deliveries xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --deliveries --limit 50 xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --deliveries --after 7b2d4c1a-9e3f-4a8b-bc56-1f0e8d3a4b2c

Options

Option Description
--limit <n> Maximum number of delivery records to return (default 20, server cap 100)
--after <cursor> Pagination cursor: delivery UUID to start after

Output columns: ID, EVENT_TYPE, STATUS (HTTP code), SUCCESS, CREATED. The higher-level delivery state (pending, delivered, failed, exhausted) is currently only exposed via the REST API.

Event Types

Pass event type names as a comma-separated string to --events. Unknown event types are rejected by the server with a 400 error. The canonical list (grouped by family) is below.

Batch (3)

Event TypeDescription
batch.completedA batch job completed successfully.
batch.failedA batch job failed.
batch.cancelledA batch job was cancelled.

Response (2)

Event TypeDescription
response.completedA response completed successfully.
response.failedA response failed.

File (2)

Event TypeDescription
file.uploadedA file was uploaded.
file.deletedA file was deleted.

Conversation (2)

Event TypeDescription
conversation.createdA conversation was created.
conversation.deletedA conversation was deleted.

Exec / XEM (15)

Event TypeDescription
exec.dispatchedA XEM tool invocation was dispatched to an execution agent.
exec.completedA XEM tool invocation completed successfully.
exec.failedA XEM tool invocation failed (non-zero exit or transport error).
exec.timeoutA XEM tool invocation exceeded its declared timeout.
exec.ambiguousA XEM invocation target was ambiguous and needs operator resolution.
exec.approval_requestedAn approval request was enqueued for a destructive invocation.
exec.approvedAn approval request was approved.
exec.rejectedAn approval request was explicitly rejected.
exec.approval_escalatedAn approval request was escalated to the next contact.
exec.approval_timed_outAn approval request timed out without a decision.
exec.agent_enrolledA XEM execution agent completed enrollment.
exec.agent_offlineA XEM execution agent transitioned to offline.
exec.discovery_pendingA XEM discovery request is awaiting operator action.
exec.workspace_createdAn operational workspace was created.
exec.workspace_budget_exhaustedA workspace consumed its inference-token budget for the current window.

Agent (5)

Event TypeDescription
agent.createdAn agent record was created via the management API.
agent.updatedAn agent record was updated via the management API.
agent.deletedAn agent was soft-deleted via the management API.
agent.enrolledAn agent finished enrollment and is eligible for dispatches.
agent.key_rotatedAn agent's CURVE transport keypair rotated.

Join Key (2)

Event TypeDescription
join_key.createdA new join key was minted via the management API.
join_key.revokedA join key was revoked.

Observability (1)

Event TypeDescription
ox.alert.raisedA learning invariant was violated (raised at critical severity).

Payload envelope shape and signature verification math: see Delivery Headers on this page and the Webhooks API reference.

Examples

Create and Verify a Webhook

bash
# Create (server returns the signing secret in the response - store it now) xeroctl webhooks --create \ --url https://hooks.example.com/xerotier \ --events batch.completed,response.completed # Verify the test event is delivered (use the UUID returned by create) xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --test # Review delivery log xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --deliveries

Temporarily Disable a Webhook

bash
xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --update --inactive # Re-enable later xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --update --active

List and Clean Up

bash
# List all webhooks xeroctl webhooks # Get details of a specific webhook xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 # Delete unused webhook xeroctl webhooks 0f3c1a8e-2d6b-4d4e-9a17-7b4c2a9d8e10 --delete --force