[{"data":1,"prerenderedAt":957},["ShallowReactive",2],{"docs-navigation":3,"content-query-5B1gAHaPZR":354},[4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136,139,142,145,148,151,154,157,160,163,166,169,172,175,178,181,184,187,190,193,196,199,202,205,208,211,214,217,220,223,226,229,232,235,238,241,244,247,250,253,256,259,262,265,268,271,274,277,280,283,286,289,291,294,297,300,303,306,309,312,315,318,321,324,327,330,333,336,339,342,345,348,351],{"_path":5,"title":6},"/docs/account/account-management","Account management",{"_path":8,"title":9},"/docs/account/mfa","Multi-factor authentication (MFA)",{"_path":11,"title":12},"/docs/account/team","Teams and sub-accounts",{"_path":14,"title":15},"/docs/account/billing-and-subscriptions","Billing & subscriptions",{"_path":17,"title":18},"/docs/account/access-tokens","Webhook Relay access tokens: permissions and subscription scopes",{"_path":20,"title":21},"/docs/clawhub","Webhook Relay on ClawHub",{"_path":23,"title":24},"/docs/email","Receive emails as webhooks",{"_path":26,"title":27},"/docs/email/payload","Email webhook payload",{"_path":29,"title":30},"/docs/email/filtering-and-policy","Sender filtering & policy",{"_path":32,"title":33},"/docs/email/cli","Create & poll email addresses from the CLI",{"_path":35,"title":36},"/docs","Getting Started",{"_path":38,"title":39},"/docs/installation/cli","CLI",{"_path":41,"title":42},"/docs/installation/docker","Docker container",{"_path":44,"title":45},"/docs/installation/docker-compose","Docker Compose",{"_path":47,"title":48},"/docs/installation/kubernetes","Kubernetes",{"_path":50,"title":51},"/docs/installation/autostart-windows","Autostart (Windows)",{"_path":53,"title":54},"/docs/installation/autostart-linux","Autostart (Linux)",{"_path":56,"title":57},"/docs/installation/autostart-macos","Autostart (MacOS)",{"_path":59,"title":60},"/docs/installation/behind-proxy","HTTP proxy configuration",{"_path":62,"title":63},"/docs/mcp","MCP Server",{"_path":65,"title":66},"/docs/outbound","Outbound Gateway: send webhooks to your customers",{"_path":68,"title":69},"/docs/outbound/setup","Set up the Outbound Gateway",{"_path":71,"title":72},"/docs/outbound/receiving","Receive and verify outbound webhooks",{"_path":74,"title":75},"/docs/outbound/operating","Monitor, retry and recover deliveries",{"_path":77,"title":78},"/docs/outbound/migrate","Migrate to the Outbound Gateway",{"_path":80,"title":81},"/docs/outbound/migrate/svix","Migrate from Svix",{"_path":83,"title":84},"/docs/outbound/migrate/hookdeck-outpost","Migrate from Hookdeck Outpost",{"_path":86,"title":87},"/docs/outbound/migrate/convoy","Migrate from Convoy",{"_path":89,"title":90},"/docs/outbound/migrate/hook0","Migrate from Hook0",{"_path":92,"title":93},"/docs/outbound/migrate/diy","Migrate a homegrown webhook sender",{"_path":95,"title":96},"/docs/security","Security & Tech",{"_path":98,"title":99},"/docs/service-connections","Service Connections",{"_path":101,"title":102},"/docs/service-connections/ai-providers","AI provider connections",{"_path":104,"title":105},"/docs/service-connections/aws_s3","AWS S3",{"_path":107,"title":108},"/docs/service-connections/aws_sns","AWS SNS",{"_path":110,"title":111},"/docs/service-connections/aws_sqs","AWS SQS",{"_path":113,"title":114},"/docs/service-connections/azure","Azure",{"_path":116,"title":117},"/docs/service-connections/gcp_gcs","GCP Cloud Storage",{"_path":119,"title":120},"/docs/service-connections/gcp_pubsub","GCP Pub/Sub",{"_path":122,"title":123},"/docs/service-connections/secrets","Secrets",{"_path":125,"title":126},"/docs/skills","Agent Skills",{"_path":128,"title":129},"/docs/skills-cli","skills.sh — the Agent Skills CLI",{"_path":131,"title":132},"/docs/tunnels/demoing-your-website","Demoing your website",{"_path":134,"title":135},"/docs/tunnels/regions","Regions",{"_path":137,"title":138},"/docs/tutorials/cicd/jenkins-bitbucket","Jenkins and Bitbucket",{"_path":140,"title":141},"/docs/tutorials/cicd/jenkins-generic-webhook-trigger","Jenkins Generic Webhook Trigger with Bitbucket",{"_path":143,"title":144},"/docs/tutorials/cicd/jenkins-github","Jenkins and GitHub",{"_path":146,"title":147},"/docs/tutorials/cicd/jenkins-plugin","Jenkins Plugin",{"_path":149,"title":150},"/docs/tutorials/cicd/jenkins-plugin-multibranch","Jenkins Multibranch Pipelines",{"_path":152,"title":153},"/docs/tutorials/cicd/kubernetes-operator","Kubernetes Operator",{"_path":155,"title":156},"/docs/tutorials/cicd/terraform-atlantis","Terraform Atlantis",{"_path":158,"title":159},"/docs/tutorials/cicd/webhook-exec","Execute scripts on webhook",{"_path":161,"title":162},"/docs/tutorials/edge/home-assistant","Home Assistant",{"_path":164,"title":165},"/docs/tutorials/edge/javascript-app","JavaScript app",{"_path":167,"title":168},"/docs/tutorials/edge/node-red","Node-RED",{"_path":170,"title":171},"/docs/tutorials/email/airtable","Email to Airtable",{"_path":173,"title":174},"/docs/tutorials/email/api","Email to API",{"_path":176,"title":177},"/docs/tutorials/email/database","Email to Database",{"_path":179,"title":180},"/docs/tutorials/email/discord","Email to Discord",{"_path":182,"title":183},"/docs/tutorials/email/google-sheets","Email to Google Sheets",{"_path":185,"title":186},"/docs/tutorials/email/microsoft-teams","Email to Microsoft Teams",{"_path":188,"title":189},"/docs/tutorials/email/notion","Email to Notion",{"_path":191,"title":192},"/docs/tutorials/email/slack","Email to Slack",{"_path":194,"title":195},"/docs/tutorials","Tutorials",{"_path":197,"title":198},"/docs/tutorials/n8n/email-trigger","n8n Email Trigger (Inbound Email)",{"_path":200,"title":201},"/docs/tutorials/n8n/webhook-trigger","n8n Webhook Trigger (No Public IP)",{"_path":203,"title":204},"/docs/tutorials/n8n/whatsapp-cloud-api-webhook","n8n WhatsApp Cloud API Webhook Setup",{"_path":206,"title":207},"/docs/tutorials/outbound/send-webhooks-nodejs","Send webhooks to your customers from a Node.js / TypeScript app",{"_path":209,"title":210},"/docs/tutorials/outbound/send-webhooks-go","Send webhooks to your customers from a Go service",{"_path":212,"title":213},"/docs/tutorials/outbound/nextjs-saas-webhooks","Add webhooks to a Next.js SaaS app",{"_path":215,"title":216},"/docs/tutorials/transform/docker-to-slack","DockerHub webhook to Slack notification",{"_path":218,"title":219},"/docs/tutorials/transform/enrich-webhooks","Enrich webhooks from APIs",{"_path":221,"title":222},"/docs/tutorials/transform/stripe-to-plain","Sync Stripe subscriptions to Plain.com tenants",{"_path":224,"title":225},"/docs/tutorials/warehouse/bigquery","GCP BigQuery",{"_path":227,"title":228},"/docs/webhooks/alerts","Alerts",{"_path":230,"title":231},"/docs/webhooks/auth/username-password","Username and password",{"_path":233,"title":234},"/docs/webhooks/auth/hmac","HMAC",{"_path":236,"title":237},"/docs/webhooks/auth/jwt","JWT authentication",{"_path":239,"title":240},"/docs/webhooks/auth/http-method","Auth using request method",{"_path":242,"title":243},"/docs/webhooks/auth/ip-allowlist","Source IP allowlist",{"_path":245,"title":246},"/docs/webhooks/cors","CORS for webhooks",{"_path":248,"title":249},"/docs/webhooks/cron/using-cron-webhooks","Schedule recurring webhooks",{"_path":251,"title":252},"/docs/webhooks/custom-domains","Custom webhook domains",{"_path":254,"title":255},"/docs/webhooks/custom-subdomains","Custom webhook subdomains",{"_path":257,"title":258},"/docs/webhooks/custom-webhook-response","Custom response to webhooks",{"_path":260,"title":261},"/docs/webhooks/durable-webhooks","Durable webhooks: reliable delivery with automatic retries",{"_path":263,"title":264},"/docs/webhooks/functions/manipulating-json","JSON encoding",{"_path":266,"title":267},"/docs/webhooks/functions/make-http-request","Make HTTP request",{"_path":269,"title":270},"/docs/webhooks/functions/modify-request","Modify webhook headers, body, method and path",{"_path":272,"title":273},"/docs/webhooks/functions/multipart-form-data","Multipart form to JSON",{"_path":275,"title":276},"/docs/webhooks/functions/url-encoded-data","URL Encoded Form",{"_path":278,"title":279},"/docs/webhooks/functions/working-with-time","Working with time",{"_path":281,"title":282},"/docs/webhooks/functions/send-emails","Sending emails",{"_path":284,"title":285},"/docs/webhooks/functions/crypto-functions","Base64, encryption",{"_path":287,"title":288},"/docs/webhooks/functions/integrate-into-cicd","Integrating into CI/CD",{"_path":290,"title":225},"/docs/webhooks/functions/big-query",{"_path":292,"title":293},"/docs/webhooks/functions/accessing-metadata","Accessing metadata",{"_path":295,"title":296},"/docs/webhooks/functions/response-functions","Response (post-delivery) functions",{"_path":298,"title":299},"/docs/webhooks/functions/alerting","Alerting from functions",{"_path":301,"title":302},"/docs/webhooks/functions/helper-libraries","Helper libraries",{"_path":304,"title":305},"/docs/webhooks/functions/transform-webhook-payload","Transform a webhook payload",{"_path":307,"title":308},"/docs/webhooks/functions/filter-webhooks","Filter or drop webhooks before forwarding",{"_path":310,"title":311},"/docs/webhooks/functions/provider-helpers","Provider-aware function helpers",{"_path":313,"title":314},"/docs/webhooks/functions/kv-store","KV store for functions: persist state, dedupe and cache with TTL",{"_path":316,"title":317},"/docs/webhooks/functions/file-store","File store for functions: save files and share pre-signed URLs",{"_path":319,"title":320},"/docs/webhooks/functions","Webhook transformations (functions): modify body, headers, method and path",{"_path":322,"title":323},"/docs/webhooks/internal/localhost","Receive webhooks on localhost with the relay CLI",{"_path":325,"title":326},"/docs/webhooks/large-webhooks","Large Webhooks",{"_path":328,"title":329},"/docs/webhooks/outbound-throttling","Outbound throttling: control webhook delivery speed",{"_path":331,"title":332},"/docs/webhooks/polling-webhooks","Polling webhooks with /v1/events",{"_path":334,"title":335},"/docs/webhooks/public/public-destination","Forward to public URL",{"_path":337,"title":338},"/docs/webhooks/public/multiple-destination-urls","Forward webhooks to multiple destinations",{"_path":340,"title":341},"/docs/webhooks/replay-on-agent-connect","Webhook replay on agent connect: recover missed webhooks",{"_path":343,"title":344},"/docs/webhooks/static-ip-address","Static IP Address",{"_path":346,"title":347},"/docs/webhooks/tls-ssl-errors","Fix TLS/SSL handshake errors: unsupported protocol, wrong version number, handshake failure",{"_path":349,"title":350},"/docs/webhooks/websocket-server","Connecting to websocket server",{"_path":352,"title":353},"/docs/webhooks/zero-retention-buckets","Zero Retention Buckets",{"_path":242,"_dir":355,"_draft":356,"_partial":356,"_locale":357,"title":243,"description":358,"intro":359,"type":360,"order":361,"section":355,"level":362,"layout":363,"tags":364,"body":367,"_type":950,"_id":951,"_source":952,"_file":953,"_stem":954,"_extension":955,"sitemap":956},"auth",false,"","Accept webhooks on an input only from the IP addresses and CIDR ranges you list. Everything else gets a 403 before it is forwarded.","Restrict an input to the source IPs your providers send from. Requests from any other address are rejected with 403 before anything is stored, run or forwarded.","example",5,"Beginner","doc",[365,366],"Security","Webhooks",{"type":368,"children":369,"toc":942},"root",[370,395,407,414,493,499,517,523,536,671,730,736,744,749,755,833,838,844,936],{"type":371,"tag":372,"props":373,"children":374},"element","p",{},[375,378,384,386,393],{"type":376,"value":377},"text","An input's ",{"type":371,"tag":379,"props":380,"children":381},"strong",{},[382],{"type":376,"value":383},"source IP allowlist",{"type":376,"value":385}," limits which addresses can send webhooks to it. When the list is not empty, a request whose source IP doesn't match any entry is rejected with ",{"type":371,"tag":387,"props":388,"children":390},"code",{"className":389},[],[391],{"type":376,"value":392},"403",{"type":376,"value":394}," at the edge. It isn't stored, no function runs, and nothing is forwarded to your outputs or agents.",{"type":371,"tag":372,"props":396,"children":397},{},[398,400,405],{"type":376,"value":399},"The allowlist is available on the ",{"type":371,"tag":379,"props":401,"children":402},{},[403],{"type":376,"value":404},"Business, Pro and Enterprise",{"type":376,"value":406}," plans.",{"type":371,"tag":408,"props":409,"children":411},"h2",{"id":410},"rules",[412],{"type":376,"value":413},"Rules",{"type":371,"tag":415,"props":416,"children":417},"ul",{},[418,455,467,488],{"type":371,"tag":419,"props":420,"children":421},"li",{},[422,424,430,432,438,440,446,447,453],{"type":376,"value":423},"Each entry is an IPv4 or IPv6 address (",{"type":371,"tag":387,"props":425,"children":427},{"className":426},[],[428],{"type":376,"value":429},"203.0.113.10",{"type":376,"value":431},", ",{"type":371,"tag":387,"props":433,"children":435},{"className":434},[],[436],{"type":376,"value":437},"2001:db8::1",{"type":376,"value":439},") or a CIDR range (",{"type":371,"tag":387,"props":441,"children":443},{"className":442},[],[444],{"type":376,"value":445},"198.51.100.0/24",{"type":376,"value":431},{"type":371,"tag":387,"props":448,"children":450},{"className":449},[],[451],{"type":376,"value":452},"2001:db8::/32",{"type":376,"value":454},").",{"type":371,"tag":419,"props":456,"children":457},{},[458,460,465],{"type":376,"value":459},"Up to ",{"type":371,"tag":379,"props":461,"children":462},{},[463],{"type":376,"value":464},"20 entries",{"type":376,"value":466}," per input.",{"type":371,"tag":419,"props":468,"children":469},{},[470,472,478,480,486],{"type":376,"value":471},"A single address is stored as ",{"type":371,"tag":387,"props":473,"children":475},{"className":474},[],[476],{"type":376,"value":477},"/32",{"type":376,"value":479}," (IPv4) or ",{"type":371,"tag":387,"props":481,"children":483},{"className":482},[],[484],{"type":376,"value":485},"/128",{"type":376,"value":487}," (IPv6). Host bits in a range are cleared, and duplicates are removed.",{"type":371,"tag":419,"props":489,"children":490},{},[491],{"type":376,"value":492},"An empty list allows every sender. That's the default, so existing inputs are unchanged.",{"type":371,"tag":408,"props":494,"children":496},{"id":495},"set-it-in-the-dashboard",[497],{"type":376,"value":498},"Set it in the dashboard",{"type":371,"tag":372,"props":500,"children":501},{},[502,504,509,511,515],{"type":376,"value":503},"Open ",{"type":371,"tag":379,"props":505,"children":506},{},[507],{"type":376,"value":508},"Buckets → your bucket → the input → Settings",{"type":376,"value":510},". In the ",{"type":371,"tag":379,"props":512,"children":513},{},[514],{"type":376,"value":243},{"type":376,"value":516}," card, enter one address or range per line and save. The card shows invalid lines inline and counts entries out of 20.",{"type":371,"tag":408,"props":518,"children":520},{"id":519},"set-it-through-the-api",[521],{"type":376,"value":522},"Set it through the API",{"type":371,"tag":372,"props":524,"children":525},{},[526,528,534],{"type":376,"value":527},"Send ",{"type":371,"tag":387,"props":529,"children":531},{"className":530},[],[532],{"type":376,"value":533},"ip_allowlist",{"type":376,"value":535}," when you create or update an input:",{"type":371,"tag":537,"props":538,"children":539},"code-block",{},[540],{"type":371,"tag":541,"props":542,"children":546},"pre",{"code":543,"language":544,"meta":357,"className":545,"style":357},"curl -X PUT https://my.webhookrelay.com/v1/buckets/$BUCKET_ID/inputs/$INPUT_ID \\\n  -u \"$RELAY_KEY:$RELAY_SECRET\" \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"ip_allowlist\": [\"203.0.113.10\", \"198.51.100.0/24\", \"2001:db8::/32\"]}'\n","bash","language-bash shiki shiki-themes github-dark",[547],{"type":371,"tag":387,"props":548,"children":549},{"__ignoreMap":357},[550,600,639,657],{"type":371,"tag":551,"props":552,"children":555},"span",{"class":553,"line":554},"line",1,[556,562,568,574,579,585,590,595],{"type":371,"tag":551,"props":557,"children":559},{"style":558},"--shiki-default:#B392F0",[560],{"type":376,"value":561},"curl",{"type":371,"tag":551,"props":563,"children":565},{"style":564},"--shiki-default:#79B8FF",[566],{"type":376,"value":567}," -X",{"type":371,"tag":551,"props":569,"children":571},{"style":570},"--shiki-default:#9ECBFF",[572],{"type":376,"value":573}," PUT",{"type":371,"tag":551,"props":575,"children":576},{"style":570},[577],{"type":376,"value":578}," https://my.webhookrelay.com/v1/buckets/",{"type":371,"tag":551,"props":580,"children":582},{"style":581},"--shiki-default:#E1E4E8",[583],{"type":376,"value":584},"$BUCKET_ID",{"type":371,"tag":551,"props":586,"children":587},{"style":570},[588],{"type":376,"value":589},"/inputs/",{"type":371,"tag":551,"props":591,"children":592},{"style":581},[593],{"type":376,"value":594},"$INPUT_ID ",{"type":371,"tag":551,"props":596,"children":597},{"style":564},[598],{"type":376,"value":599},"\\\n",{"type":371,"tag":551,"props":601,"children":603},{"class":553,"line":602},2,[604,609,614,619,624,629,634],{"type":371,"tag":551,"props":605,"children":606},{"style":564},[607],{"type":376,"value":608},"  -u",{"type":371,"tag":551,"props":610,"children":611},{"style":570},[612],{"type":376,"value":613}," \"",{"type":371,"tag":551,"props":615,"children":616},{"style":581},[617],{"type":376,"value":618},"$RELAY_KEY",{"type":371,"tag":551,"props":620,"children":621},{"style":570},[622],{"type":376,"value":623},":",{"type":371,"tag":551,"props":625,"children":626},{"style":581},[627],{"type":376,"value":628},"$RELAY_SECRET",{"type":371,"tag":551,"props":630,"children":631},{"style":570},[632],{"type":376,"value":633},"\"",{"type":371,"tag":551,"props":635,"children":636},{"style":564},[637],{"type":376,"value":638}," \\\n",{"type":371,"tag":551,"props":640,"children":642},{"class":553,"line":641},3,[643,648,653],{"type":371,"tag":551,"props":644,"children":645},{"style":564},[646],{"type":376,"value":647},"  -H",{"type":371,"tag":551,"props":649,"children":650},{"style":570},[651],{"type":376,"value":652}," 'Content-Type: application/json'",{"type":371,"tag":551,"props":654,"children":655},{"style":564},[656],{"type":376,"value":638},{"type":371,"tag":551,"props":658,"children":660},{"class":553,"line":659},4,[661,666],{"type":371,"tag":551,"props":662,"children":663},{"style":564},[664],{"type":376,"value":665},"  -d",{"type":371,"tag":551,"props":667,"children":668},{"style":570},[669],{"type":376,"value":670}," '{\"ip_allowlist\": [\"203.0.113.10\", \"198.51.100.0/24\", \"2001:db8::/32\"]}'\n",{"type":371,"tag":372,"props":672,"children":673},{},[674,676,681,683,689,691,696,698,705,707,713,714,720,722,728],{"type":376,"value":675},"On an update, leaving ",{"type":371,"tag":387,"props":677,"children":679},{"className":678},[],[680],{"type":376,"value":533},{"type":376,"value":682}," out keeps the current list, and ",{"type":371,"tag":387,"props":684,"children":686},{"className":685},[],[687],{"type":376,"value":688},"[]",{"type":376,"value":690}," clears it. Reads always return the field, as ",{"type":371,"tag":387,"props":692,"children":694},{"className":693},[],[695],{"type":376,"value":688},{"type":376,"value":697}," when it's empty. The ",{"type":371,"tag":699,"props":700,"children":702},"a",{"href":701},"/docs/mcp/",[703],{"type":376,"value":704},"MCP server",{"type":376,"value":706}," tools ",{"type":371,"tag":387,"props":708,"children":710},{"className":709},[],[711],{"type":376,"value":712},"create_input",{"type":376,"value":431},{"type":371,"tag":387,"props":715,"children":717},{"className":716},[],[718],{"type":376,"value":719},"update_input",{"type":376,"value":721}," and ",{"type":371,"tag":387,"props":723,"children":725},{"className":724},[],[726],{"type":376,"value":727},"get_input",{"type":376,"value":729}," accept and return the same field.",{"type":371,"tag":408,"props":731,"children":733},{"id":732},"what-a-blocked-sender-sees",[734],{"type":376,"value":735},"What a blocked sender sees",{"type":371,"tag":541,"props":737,"children":739},{"code":738},"HTTP/1.1 403 Forbidden\n\nsource IP 192.0.2.44 is not allowed to send webhooks to this endpoint\n",[740],{"type":371,"tag":387,"props":741,"children":742},{"__ignoreMap":357},[743],{"type":376,"value":738},{"type":371,"tag":372,"props":745,"children":746},{},[747],{"type":376,"value":748},"The response never reveals the list. Rejected requests don't create webhook logs, so traffic from unknown addresses can't fill your logs or leave its payloads in your account.",{"type":371,"tag":408,"props":750,"children":752},{"id":751},"errors-when-saving",[753],{"type":376,"value":754},"Errors when saving",{"type":371,"tag":756,"props":757,"children":758},"table",{},[759,778],{"type":371,"tag":760,"props":761,"children":762},"thead",{},[763],{"type":371,"tag":764,"props":765,"children":766},"tr",{},[767,773],{"type":371,"tag":768,"props":769,"children":770},"th",{},[771],{"type":376,"value":772},"Status",{"type":371,"tag":768,"props":774,"children":775},{},[776],{"type":376,"value":777},"When",{"type":371,"tag":779,"props":780,"children":781},"tbody",{},[782,800,816],{"type":371,"tag":764,"props":783,"children":784},{},[785,795],{"type":371,"tag":786,"props":787,"children":788},"td",{},[789],{"type":371,"tag":387,"props":790,"children":792},{"className":791},[],[793],{"type":376,"value":794},"400",{"type":371,"tag":786,"props":796,"children":797},{},[798],{"type":376,"value":799},"An entry isn't an IPv4/IPv6 address or CIDR range. The message names the entry.",{"type":371,"tag":764,"props":801,"children":802},{},[803,811],{"type":371,"tag":786,"props":804,"children":805},{},[806],{"type":371,"tag":387,"props":807,"children":809},{"className":808},[],[810],{"type":376,"value":794},{"type":371,"tag":786,"props":812,"children":813},{},[814],{"type":376,"value":815},"The list has more than 20 entries.",{"type":371,"tag":764,"props":817,"children":818},{},[819,828],{"type":371,"tag":786,"props":820,"children":821},{},[822],{"type":371,"tag":387,"props":823,"children":825},{"className":824},[],[826],{"type":376,"value":827},"402",{"type":371,"tag":786,"props":829,"children":830},{},[831],{"type":376,"value":832},"The account is below Business and the request adds entries.",{"type":371,"tag":372,"props":834,"children":835},{},[836],{"type":376,"value":837},"If an account moves below Business, its existing allowlists keep being enforced, so the protection doesn't silently disappear. Entries can still be removed or the list cleared, but new ones can't be added.",{"type":371,"tag":408,"props":839,"children":841},{"id":840},"notes",[842],{"type":376,"value":843},"Notes",{"type":371,"tag":415,"props":845,"children":846},{},[847,872,890,918],{"type":371,"tag":419,"props":848,"children":849},{},[850,855,857,863,864,870],{"type":371,"tag":379,"props":851,"children":852},{},[853],{"type":376,"value":854},"Which IP is checked.",{"type":376,"value":856}," The source address of the connection to Webhook Relay. ",{"type":371,"tag":387,"props":858,"children":860},{"className":859},[],[861],{"type":376,"value":862},"X-Forwarded-For",{"type":376,"value":431},{"type":371,"tag":387,"props":865,"children":867},{"className":866},[],[868],{"type":376,"value":869},"X-Real-IP",{"type":376,"value":871}," and similar headers are ignored, because any sender could forge them.",{"type":371,"tag":419,"props":873,"children":874},{},[875,880,882,888],{"type":371,"tag":379,"props":876,"children":877},{},[878],{"type":376,"value":879},"Your own proxy or CDN.",{"type":376,"value":881}," If you put a proxy or CDN in front of a ",{"type":371,"tag":699,"props":883,"children":885},{"href":884},"/features/custom-domains/",[886],{"type":376,"value":887},"custom domain",{"type":376,"value":889},", webhooks arrive from that proxy, so allowlist its IP ranges.",{"type":371,"tag":419,"props":891,"children":892},{},[893,898,900,906,908,916],{"type":371,"tag":379,"props":894,"children":895},{},[896],{"type":376,"value":897},"Where to find provider ranges.",{"type":376,"value":899}," Most providers publish the addresses they send webhooks from. For example, GitHub lists them under ",{"type":371,"tag":387,"props":901,"children":903},{"className":902},[],[904],{"type":376,"value":905},"hooks",{"type":376,"value":907}," in its ",{"type":371,"tag":699,"props":909,"children":913},{"href":910,"rel":911},"https://api.github.com/meta",[912],"nofollow",[914],{"type":376,"value":915},"meta API",{"type":376,"value":917},".",{"type":371,"tag":419,"props":919,"children":920},{},[921,926,928,934],{"type":371,"tag":379,"props":922,"children":923},{},[924],{"type":376,"value":925},"Combine it with signatures.",{"type":376,"value":927}," An allowlist stops traffic from unknown networks. A ",{"type":371,"tag":699,"props":929,"children":931},{"href":930},"/features/verify-webhook-signatures/",[932],{"type":376,"value":933},"signature check",{"type":376,"value":935}," proves the payload came from the provider and wasn't changed. Use both for webhooks that reach private networks.",{"type":371,"tag":937,"props":938,"children":939},"style",{},[940],{"type":376,"value":941},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":357,"searchDepth":641,"depth":641,"links":943},[944,945,946,947,948,949],{"id":410,"depth":602,"text":413},{"id":495,"depth":602,"text":498},{"id":519,"depth":602,"text":522},{"id":732,"depth":602,"text":735},{"id":751,"depth":602,"text":754},{"id":840,"depth":602,"text":843},"markdown","content:docs:webhooks:auth:5.ip-allowlist.md","content","docs/webhooks/auth/5.ip-allowlist.md","docs/webhooks/auth/5.ip-allowlist","md",{"loc":242},1794645197608]