Skip to main content

Config File

The bankr.webhooks.json file defines your webhooks — permissions, rate limits, and agent guardrails.

Created automatically by bankr webhooks init and updated by bankr webhooks add.

Example​

{
"webhooks": {
"daily-summary": {
"description": "Slack bot — summarize portfolio on @mention",
"readOnly": true,
"allowedRecipients": { "evm": [], "solana": [] },
"allowedIps": [],
"rateLimit": { "perMinute": 10, "perDay": 1000 },
"maxPayloadBytes": 10240
},
"release-bot": {
"description": "GitHub release announcer",
"readOnly": false,
"allowedRecipients": {
"evm": ["0xAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAa"],
"solana": []
},
"rateLimit": { "perMinute": 5, "perDay": 200 }
}
}
}

Webhook Fields​

Each key in webhooks is the webhook name. Names must be alphanumeric, hyphens, or underscores — max 47 characters.

FieldDefaultDescription
description— (auto-generated)Human-readable description. Shows in the dashboard and bankr webhooks list.
readOnlytrueWhen true, the agent cannot execute write tools (no signing, no submitting transactions). See Security.
allowedRecipients{ evm: [], solana: [] }Per-chain recipient allowlist for transfers. Required (non-empty) if you set readOnly: false.
allowedIps[] (any IP)If non-empty, only requests from these exact IP addresses are accepted. Others get 403.
rateLimit{ perMinute: 10, perDay: 1000 }Per-webhook rate limit. Requests over perMinute return 429; perDay is not enforced.
maxPayloadBytes10240 (10 KB)Max request body size. Oversize requests return 413.

readOnly​

When true (the default), the agent running your handler's prompt has write tools filtered out entirely. It can fetch prices, portfolio data, news, and anything else read-only — but cannot transfer funds, swap tokens, launch tokens, or approve transactions.

When false, the agent can execute write operations — but only to the allowedRecipients you've configured. This is a hard guardrail: even if an attacker smuggles a malicious instruction into your webhook payload, the agent physically cannot send funds to an address that isn't in your allowlist.

allowedRecipients​

A per-chain allowlist of addresses the agent can send funds or assets to. Your own wallet address is always implicitly allowed.

"allowedRecipients": {
"evm": ["0xAaAa...", "0xBbBb..."],
"solana": ["9xq..."]
}
  • Setting readOnly: false with both lists empty is rejected at deploy time.
  • The agent validates every recipient on every transfer-style tool call. There is no path to bypass.
  • Update the list anytime — take effect on the next invocation.

allowedIps​

Restrict which source IPs can invoke your webhook. Useful when your upstream provider publishes a fixed set of egress IPs (some enterprise systems do).

"allowedIps": ["203.0.113.10", "198.51.100.7"]

Entries are matched exactly against the caller's IP — CIDR ranges aren't supported. If empty, any IP is accepted (sig verification in your handler is still the primary auth).

rateLimit​

Prevents a noisy upstream from running the agent in a loop. Enforced per-webhook, on a best-effort basis.

"rateLimit": { "perMinute": 10, "perDay": 1000 }

Requests past perMinute return HTTP 429 immediately — your handler doesn't run and no agent invocation is enqueued. perDay is stored but not currently enforced.

maxPayloadBytes​

Hard cap on request body size. Defaults to 10 KB, which is enough for Slack/GitHub/Stripe events. Raise it if your upstream sends larger payloads (rare).

Name Rules​

  • Alphanumeric, hyphens, or underscores: [a-zA-Z0-9_-]+
  • Max 47 characters
  • Rejected names are caught at bankr webhooks add and again at bankr webhooks deploy

How It's Used​

Every time bankr webhooks deploy runs:

  1. The CLI sends your bankr.webhooks.json config alongside your handler source.
  2. The platform validates the config (names, source size, the readOnly/allowedRecipients invariant).
  3. The per-webhook permissions are stored with the deployment and travel with every invocation to the agent. Changing the config and redeploying is how you update permissions.

For changes that don't require redeploying code, use the dashboard's Settings tab — it updates the stored permissions directly.