Environment Variables
PocketBase instances on PocketBase Cloud support environment variables — the right place for API keys and configuration used by your hooks. Values are stored encrypted at rest and injected into the instance’s process, so secrets never live in your hook code.
Typical uses:
- API keys for third-party services your hooks call with
$http.send()(Stripe, Resend, OpenAI, …) - Webhook signing secrets
- Feature flags or per-environment configuration
Step 1: Add a variable
Using the portal
- Open your PocketBase instance in the portal
- Go to the Env Vars page
- Click Add Variable, enter a key and value (e.g.,
STRIPE_SECRET_KEY), and save
Using the CLI
pb cloud env set STRIPE_SECRET_KEY=sk_live_… --target pb --name my-app-db
pb cloud env ls --target pb --name my-app-db
pb cloud env rm STRIPE_SECRET_KEY --target pb --name my-app-db
Bulk-import a dotenv file, or let a deploy push it for you — a .env beside
pb.json is sent to the instance on every pb cloud pb deploy:
pb cloud env import .env.production --target pb --name my-app-db
cd db
pb cloud pb deploy # pushes .env alongside the hooks
pb cloud pb deploy --skip-env # leaves cloud env vars alone
Inside a linked directory the --name is optional. --target pb is the
default, so pb cloud env ls alone works there too.
Either way, the instance restarts automatically to pick up the change — expect a few seconds of downtime, so batch your edits rather than saving one key at a time.
Step 2: Read it in your hooks
Inside hook files, read environment variables with $os.getenv():
routerAdd("POST", "/api/checkout", (e) => {
const res = $http.send({
url: "https://api.stripe.com/v1/checkout/sessions",
method: "POST",
headers: {
Authorization: `Bearer ${$os.getenv("STRIPE_SECRET_KEY")}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: "mode=payment&...",
});
return e.json(200, res.json);
});
Any hook context can read variables the same way — record event handlers and cron jobs included:
cronAdd("daily-report", "0 8 * * *", () => {
$http.send({
url: $os.getenv("SLACK_WEBHOOK_URL"),
method: "POST",
body: JSON.stringify({ text: "Daily report ready" }),
});
});
When you develop locally, the same
$os.getenv() calls read your shell’s environment — export the variables
before ./pocketbase serve, or keep them in the .env the deploy will push.
Updating and deleting variables
Edit or remove variables from the Env Vars page, or with
pb cloud env set / pb cloud env rm. Every change triggers an automatic
restart, after which $os.getenv() returns the new value — there’s no cache to
clear and no redeploy step.
Security notes
- Values are encrypted at rest and only decrypted when the instance starts
pb cloud env lsand the portal both show names only — the platform never returns stored values in plaintext, so keep a copy of anything you can’t regenerate- Keep secrets out of hook files — hooks are stored as code, and code gets copied, exported, and pasted into chat windows; environment variables don’t
- Never expose secrets through a custom route’s response — return only the data the client needs
Environment variables for backends
Backends have their own separate variables, managed on each backend’s
Env Vars page or with --target backend — see
backend environment variables. A
common setup is the same secret (e.g., a Stripe key) added in both places if
both your hooks and your backend talk to the same third-party service.