Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create a Cloudflare Worker that proxies API calls from a static frontend to a keyed API, keeping the API key server-side. Use when a client-only app (GitHub Pages, Netlify, Cloudflare Pages) needs to call an API that requires an API key — and exposing that key in the JavaScript bundle is unacceptable. Covers Worker code, CORS headers, secret storage, and the client-side fetch pattern. Verify current Cloudflare pricing, quotas, and product behavior from official documentation before presenting th
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 28% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 89% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 49% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 97% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 48% | 0% |
OverKill Hill P³ · overkillhill.com · github.com/OKHP3
A Cloudflare Worker is a serverless function that runs at Cloudflare's edge. It handles the API call server-side, holds the API key in secrets, and returns
| In scope | Out of scope | |---|---| | A narrow static-frontend-to-keyed-API proxy, CORS policy, secret binding, request validation, and client fetch example | Hiding a public endpoint, replacing authentication or authorization, rate-abuse prevention by assumption, or promising current plan limits without verification | the result to your browser. The key never appears in your JavaScript bundle.
Use this pattern when:
javascript// worker.js — paste this into the Cloudflare Worker editor export default { async fetch(request, env) { // Handle CORS preflight if (request.method === 'OPTIONS') { return new Response(null, { headers: { 'Access-Control-Allow-Origin': env.ALLOWED_ORIGIN || '*', 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Max-Age': '86400', }, }); } if (request.method !== 'POST') { return new Response('Method Not Allowed', { status: 405 }); } // Parse the request body from the client let body; try { body = await request.json(); } catch { return new Response('Invalid JSON', { status: 400 }); } // Call the upstream API with your secret key const upstream = await fetch(env.UPSTREAM_API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', // Add your API-specific auth header here: 'Authorization': `Bearer ${env.API_SECRET_KEY}`, // Or for Anthropic: // 'x-api-key': env.API_SECRET_KEY, // 'anthropic-version': '2023-06-01', }, body: JSON.stringify(body), }); const data = await upstream.json(); return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': env.ALLOWED_ORIGIN || '*', }, }); }, };
my-api-proxy)env.UPSTREAM_API_URL reference and auth header to match your APIAPI_SECRET_KEY = your actual API keyUPSTREAM_API_URL = the API endpoint you're proxying (e.g., https://api.anthropic.com/v1/messages)ALLOWED_ORIGIN = your frontend's domain (e.g., https://username.github.io) — or * for open accesshttps://my-api-proxy.your-account.workers.devVITE_PROXY_URL=https://my-api-proxy.your-account.workers.devtypescript// In your React app — the key never appears here const PROXY_URL = import.meta.env.VITE_PROXY_URL; async function callApi(payload: object) { const res = await fetch(PROXY_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); if (!res.ok) throw new Error(`Proxy error: ${res.status}`); return res.json(); }
For proxying api.anthropic.com/v1/messages:
javascript// In the Worker, replace the fetch call with: const upstream = await fetch('https://api.anthropic.com/v1/messages', { method: 'POST', headers: { 'x-api-key': env.ANTHROPIC_API_KEY, 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: body.model || 'YOUR_CURRENT_MODEL_ID', max_tokens: body.max_tokens || 1000, system: body.system, messages: body.messages, }), });
Do not hard-code plan limits or a permanence claim in an implementation. Check the current official Workers pricing and limits documentation for the account, plan, runtime, and deployment date, then record the verified limits in the project deployment notes.
The ALLOWED_ORIGIN secret controls which domains can call your Worker:
ALLOWED_ORIGIN = https://username.github.ioSetting it to * allows any domain to call your Worker. Use your specific frontend domain in production to prevent others from using your proxy.
ALLOWED_ORIGIN set to your specific frontend domain (not *)*)For higher-security scenarios: add an additional shared secret that the frontend sends and the Worker validates before proxying.
Return the Worker source, secret names, allowed-origin policy, request/response shape, deployment steps, and a verification checklist. Never place a real key in source, logs, examples, or client code. Treat the proxy URL as public and state what abuse controls are still missing.
Built by Jamie Hill · OverKill Hill P³ Published at github.com/OKHP3 Part of the OKHP3/skillz Agent Skill library. MIT License -- free to use, fork, and adapt. A nod to the source is appreciated.
Other measured skills in the registry, with their headline benchmark lift.