Workers Binding API
VPC bindings provide a fetch() API for accessing private services from your Worker through Cloudflare Tunnel. Both VPC Services and VPC Networks expose the same fetch() method — the difference is in routing scope.
A VPC Service binding routes requests to a specific pre-registered host and port. The VPC Service configuration always determines the connection target, even if a different URL or host is present in the fetch() call.
- The host provided in
fetch()does not control routing. It only populates theHostheader and, when usinghttps, the Server Name Indication (SNI) value. - The port provided in
fetch()is ignored — the port specified in the VPC Service configuration is always used.
A VPC Network binding grants access to any service reachable through the bound tunnel or Cloudflare Mesh. The URL passed to fetch() determines the actual destination — hostname or IP address and port.
Makes an HTTP request to the private service through the configured tunnel.
const response = await env.MY_BINDING.fetch(resource, options);resource(string | URL | Request) — The URL to fetch. Must be an absolute URL including protocol, host, and path (for example,http://internal-api/api/users).options(optional RequestInit) — Standard fetch options including:method— HTTP method (GET, POST, PUT, DELETE, etc.)headers— Request headersbody— Request bodysignal— AbortSignal for request cancellation
Returns a Promise<Response> that resolves to a standard Fetch API Response object ↗.
The following examples apply to both VPC Service and VPC Network bindings.
export default { async fetch(request, env) { const privateRequest = new Request( "http://internal-api.company.local/users", ); const response = await env.MY_BINDING.fetch(privateRequest); const users = await response.json();
return new Response(JSON.stringify(users), { headers: { "Content-Type": "application/json" }, }); },};export default { async fetch(request, env) { const privateRequest = new Request( "http://internal-api.company.local/users", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${env.API_TOKEN}`, }, body: JSON.stringify({ name: "John Doe", email: "john@example.com", }), }, );
const response = await env.MY_BINDING.fetch(privateRequest);
if (!response.ok) { return new Response("Failed to create user", { status: response.status }); }
const user = await response.json(); return new Response(JSON.stringify(user), { headers: { "Content-Type": "application/json" }, }); },};export default { async fetch(request, env) { const privateRequest = new Request("https://10.0.1.50/api/data"); const response = await env.MY_BINDING.fetch(privateRequest);
return response; },};To bind a VPC Service or VPC Network in a Worker, your user needs Connectivity Directory Bind (or Connectivity Directory Admin). Binding directly to a tunnel through a VPC Network binding requires Connectivity Directory Admin. For role definitions, refer to Roles.
- Configure VPC Services
- Configure VPC Networks
- Refer to usage examples