This recipe assumes you are already using Cloudflare at the request boundary. The Worker preserves Cloudflare request context, sends it to Esper, and applies the returned runtime action before forwarding traffic.Documentation Index
Fetch the complete documentation index at: https://docs.esperr.com/llms.txt
Use this file to discover all available pages before exploring further.
What you’ll need
- A deployed Esper API that your Worker can reach.
- An Esper tenant for the application you want to protect.
- An Esper API key for that tenant, stored as a Worker secret.
- At least one mitigation and policy in Esper.
- If you want managed challenge redirects, a challenge mitigation with a default return URL template already configured.
- A decision about failure behavior if Esper is unavailable: fail open or fail closed.
Recipe SourceThe Worker below is the customer-facing version of the
recipes/cloudflare
recipe. You do not need access to the Esper repository to deploy it.What this integration does
The Worker first verifies any Esper challenge proof return parameter. For normal requests, it captures Cloudflare request context, sends one synchronous runtime decision request to Esper, and then immediately applies the returnedallow,
challenge, or block action before forwarding traffic.
Canonical Worker flow:
Challenge proof handling
Esper-managed challenges return visitors to the protected URL with anesper_challenge_proof query parameter. The Worker verifies that token with
POST /api/v1/challenge/proof/verify, stores the proof in a short-lived
first-party pass cookie, removes the query parameter, and redirects the browser
to the cleaned URL.
This keeps the origin and browser URL from retaining the challenge proof token.
The pass cookie lets follow-up requests during the proof TTL skip another
runtime challenge after the Worker verifies the cookie token.
Runtime decision request
For normal requests, the Worker sends onePOST /api/v1/runtime/mitigation
request. The payload preserves the method, path, selected Cloudflare headers,
query parameters, cookies, route parameters, and the original return_url.
The fields.probe value intentionally keeps the runtime payload non-empty
while your tenant-specific request extraction and policy logic reads the request
context.
Environment variables
Required:ESPER_API_KEY
https://api.esperr.com/api/v1 directly. Fork the recipe only
if you need to point at a non-production Esper API host.
Forwarding model
For the standard setup, attach the Worker to a route on the customer’s existing Cloudflare-proxied hostname, such as:allow, the Worker calls fetch(request). Cloudflare then
forwards the original request to the hostname’s configured origin. The customer
does not need to provide their Vercel origin or restate any upstream URL.
Use a custom reverse-proxy fork only for the less common deployment where the
Worker receives traffic for one hostname and must forward allowed requests to a
different origin hostname.
Create the Worker project
Create a new Cloudflare Worker project with Cloudflare’s setup tool:package.json, and install
dependencies. Do not deploy from the setup wizard; deploy only after adding the
Esper Worker code and ESPER_API_KEY secret.
Add the Esper Worker code
Replace the generated Worker entry file, usuallysrc/index.ts, with the
Esper Cloudflare Worker code from this guide.
Deploy
wrangler secret put ESPER_API_KEY prompts
for the secret value.
Bind the Worker to your site
After settingESPER_API_KEY, add a route to the generated Wrangler config.
For current Cloudflare Worker projects, this file is usually wrangler.jsonc.
For example, to run Esper on all requests to arbi.gg, add routes as a
top-level field:
What the Worker applies
allow: forward the request upstream.challenge: redirect to the Esper-managed challenge URL returned by/api/v1/runtime/mitigation.block: return the Esper block response from the inline/api/v1/runtime/mitigationdecision.
Challenge redirects
Sendreturn_url: request.url with each runtime mitigation request. This is the
original URL the visitor requested, and Esper stores it on the challenge session
so a successful challenge can return the visitor to the protected page. The
mitigation’s default return URL template is only a fallback when the integration
does not provide a per-request return_url.
Customer ExperienceThe customer should not have to call Beacon, mitigation, and challenge APIs
separately. The Worker should hide that complexity and make Esper feel like one
deployed protection layer.