Platform bindings

Every app is handed a set of managed bindings on the env object passed to your api/*.js routes. They're provisioned and wired for you — there are no keys to paste or services to stand up. Read one off env and use it.

What you get

BindingWhat it isAvailabilityDocs
env.DBSQL database (SQLite)AutomaticDatabase
env.STORAGEFile storage + public file URLsAutomaticFile storage
env.AUTHUser accounts, sessions, 2FAAlways onAuth
env.PAYMENTSStripe checkout & subscriptionsSet Stripe keyPayments
env.AIOpenAI, Anthropic, Workers AIAttachAI
env.EMAILSend transactional emailAttachEmail
env.CACHEKey-value cache (KV)Attach

Automatic bindings are attached to every app. Always on means it's built into the runtime. Attach means it's optional — your assistant adds it with attach_resource when you ask for it. Binding names are fixed; you get one of each per app.

Using a binding

Bindings live on the env argument of your route handler:

// api/signup.js
export default {
  async fetch(request, env, ctx) {
    const { email, password } = await request.json();
    const result = await env.AUTH.signUp({ email, password });
    if (!result.ok) return Response.json({ error: result.error }, { status: 400 });
    // env.AUTH returns a Response with the session cookie already set
    return result.response;
  },
};

Alongside the bindings above you also get env.APP_ID, env.ENVIRONMENT ("production" or a preview / branch name), and any environment variables you've set on the app.

Provisioning

A database and storage come attached by default. The full set of attachable resources, and how to manage them over MCP (attach_resource, detach_resource, list_resources), is covered in Build & deploy an app. Secrets and config values are managed with set_app_env / list_app_env / delete_app_env and injected at deploy.