Skip to content

Bolt.new app with OpenRouter: AI launch checklist

Bolt.new apps call OpenRouter with your own API key, from server code, so OpenRouter's own limits are your safety net. Of the 20 checks before you charge users, Bolt.new handles 0, partly handles 1, and leaves 19 to you.

Checked 12 Nov 2026 against each platform's docs; every fact links to its source.

How AI calls work in Bolt.new

Built-in AI
No built-in AI gateway for app features found. Bolt's docs index has no page on built-in AI, OpenAI or Anthropic for apps.
How calls run
Through Bolt Cloud server functions (also called edge functions), which list 'Calling external AI APIs like OpenAI' as a common use case. Bolt deploys them when it creates or updates them. Runtime, timeouts and auth are not documented.
API keys
You bring the key. Bolt's troubleshooting page uses OPENAI_API_KEY as the example secret; if you use your own Supabase, secrets can also be set in Supabase under Edge Functions > Secrets (both stay in sync).
Who pays
You pay each AI provider directly. Bolt bills tokens for building, and Bolt Cloud plans include an amount of hosting usage; at the limit the site 'stops displaying publicly until your usage resets'. Server-function usage pricing: not found.
Database
Bolt Cloud database (Bolt creates one when a project needs it); secrets prefixed SUPABASE_ are reserved for Bolt's database connection, which suggests Supabase underneath (inference, not stated). Advanced settings allow connecting your own Supabase instead.

Keys and secrets

Where secrets live
Database icon (top center) → Secrets. Requires a database. Visible only to the project owner (or owner, co-owners and team Admins on teams). Value never shown again after saving.
Server-side by default?
Secrets are read only by server functions and never written into project files, browser code or the published site. Values in .env are different: browser code can read them.
How keys end up in the browser
Keeping the AI key in .env and reading it from browser code; Bolt warns that if browser code reads a value, 'that value ends up in what's sent to anyone visiting your published site.' Editors and co-owners can also see .env.
Secret scanning
Project security audit (paid plans; Publish menu → Run security audit; free of tokens; 30 per day) checks that private keys aren't in code or sent to browsers. Database security check (all plans) flags rules like 'a permission rule that allows anyone to read a table'.

The 20 checks, in Bolt.new

What Bolt.new does for you, and what to ask it (or your coding agent) to add. Tick them off in the interactive checklist.

Cost and abuse

  • You add it

    A spending cap per user

    Ask Bolt: 'Create an ai_usage table in the Bolt database and, in the server function that calls OpenAI, sum today's cost for the signed-in user and return a daily-limit error before calling the provider when it's over $2.'

    support.bolt.new ↗

  • You add it

    Rate limits on every AI endpoint

    Bolt documents no rate limiting, so ask Bolt: 'Add a rate_limits table and check it at the start of every AI server function by user id (or IP when signed out), returning 429 after 10 calls a minute.'

    support.bolt.new ↗

  • Partly

    AI keys only on the server

    Secrets (database icon → Secrets) only reach server functions, but .env values read by browser code ship with the site, so ask Bolt: 'Move every AI key out of .env and VITE_ variables into Secrets and call providers only from server functions,' then run Publish → Run security audit.

    support.bolt.new ↗

  • You add it

    Retries capped, with a timeout

    Ask Bolt: 'In each AI server function add a 30-second timeout and at most 2 retries on 429 and 5xx only, and remove any retry loop in the React code.'

    support.bolt.new ↗

  • You add it

    A budget alert at each AI provider

    Bolt neither bills nor caps AI usage, so set a hard limit in each provider: OpenAI project hard limit, Anthropic workspace spend limit, Gemini project spend cap, OpenRouter per-key credit limit, fal alerts.

    support.bolt.new ↗

Charging for AI use

  • You add it

    Every AI call charged or deliberately free

    Ask Bolt to list every server function that calls an AI provider, including image generation and webhook handlers, and mark each one as charged to the user or free on purpose.

    support.bolt.new ↗

  • You add it

    Credits deducted on the server, after success

    Ask Bolt: 'Create a user_credits table whose permission rules let users read only their own row and never update it, and deduct inside the AI server function after saving the result'; then check the database Security tab for rules that let anyone read or write.

    support.bolt.new ↗

  • You add it

    Failed AI calls refunded

    Ask Bolt: 'In the AI server function, refund reserved credits and log a refund row with the reason when the provider errors, times out, refuses, or returns empty or invalid output.'

    support.bolt.new ↗

  • You add it

    One charge per request, even on a double click

    Ask Bolt: 'Send a request_id from the client, store it with a unique constraint on ai_results, return the saved result on a repeat, and disable the Generate button while it runs.'

    support.bolt.new ↗

A record of every AI result

  • You add it

    Each AI result stored with its feature, model, prompt version and settings

    Server-function logs only cover the past hour, so ask Bolt to create ai_results (feature, model, prompt_version, params, input, user_id, provider request id, timestamps) written by the server function.

    support.bolt.new ↗

  • You add it

    Retries and corrections saved next to the original, never over it

    Ask Bolt: 'On retry or edit, insert a new ai_results row with parent_id and version instead of updating the old one, and show the latest version by default.'

    support.bolt.new ↗

  • You add it

    What users do next with each AI result, recorded on the server

    Ask Bolt to create an ai_events table and a log-ai-event server function called from the Retry, Undo, Edit, Copy and Export buttons.

    support.bolt.new ↗

What worked, for whom, at what cost

  • You add it

    Worked first time, per feature, model and prompt version

    Ask Bolt to add an admin-only page showing worked-first-time by feature, model and prompt version for 7 and 30 days, with counts.

    support.bolt.new ↗

  • You add it

    A cost record for every AI step

    Ask Bolt to compute cost from the provider's reported usage with one price table in the server function and save an ai_costs row per call, retries included.

    support.bolt.new ↗

  • You add it

    Wasted AI spend and real cost per result, per feature

    Ask Bolt to add an admin query joining ai_costs and ai_events for total spend, spend on results that didn't work, and cost per result that worked, per feature and model.

    support.bolt.new ↗

  • You add it

    Who the AI fails for

    Ask Bolt to save language, length band, input kind, plan and new-user flag with each result and show worked-first-time per trait.

    support.bolt.new ↗

Switching safely

  • You add it

    Prompts in version control, with version labels

    Ask Bolt to move prompt strings out of the server functions into a prompts module with version labels saved on every result.

    support.bolt.new ↗

  • You add it

    Model and prompt switchable by a flag

    Ask Bolt to read the model id and prompt version from an app_settings table (Secrets are meant for credentials) so you can switch without republishing, with a user-id-hashed split.

    support.bolt.new ↗

  • You add it

    Real past requests to replay before a change

    Ask Bolt for an admin-only server function that replays 50 anonymised past requests through a chosen model and prompt version and saves the results and cost next to the originals.

    support.bolt.new ↗

  • You add it

    A plan for model shutdowns

    Ask Bolt to list every model id in the server functions, move them to one config, and write MODELS.md with the provider's retirement dates.

    support.bolt.new ↗

OpenRouter limits to set before launch

Per-key limit
Key dialog → 'Key limit' → 'Credit limit', reset interval and 'Include BYOK usage in limit' (toggle appears only with BYOK keys configured). API: PATCH https://openrouter.ai/api/v1/keys/{key_hash} with limit (USD), limit_reset (daily, weekly, monthly; unset = lifetime; resets at midnight UTC) and include_byok_in_limit (default false).
When a key hits its limit
Conflicting docs: the capping guide says requests fail with 403 'Key limit exceeded'; the limits reference says over-limit requests return 402 with limit_source openrouter_key_limit (or openrouter_guardrail_budget / openrouter_workspace_budget). Test before relying on either.
Workspace and guardrails
Workspace budget: one pooled cap for all members and keys. Guardrail budgets: per member or per key, daily/weekly/monthly; 'the first limit reached blocks the request'; the lower of key limit and member guardrail wins.
Account balance
Prepaid credits; an 'in-flight spending budget' (a fraction of balance) can fail paid requests with 402 even when balance is positive; a negative balance can error even free models.
Alerts and top-up
Low-balance alerts and auto top-up: not found in the pages read.
Key scoping
Per-key credit limits and per-key guardrails (model, provider, ZDR and data-region policy). Keys are owned by a member or a workspace; spend is attributed to the key's creator, so per-person enforcement needs one key per person. Management API key can create keys (POST /api/v1/keys).
Rate limits
Free model variants (':free'): 20 RPM; 50 requests/day if under 10 credits ever purchased, 1,000/day at 10+. Paid models: 'no platform-level request cap' (upstream provider limits still apply). Key-management endpoints 10,000 requests/day. Cloudflare DDoS protection blocks dramatic excess.
Where usage shows
Activity page filters by API key, model, provider and user; export CSV or PDF grouped by Model, API Key or Creator. GET /api/v1/activity (management key, last 30 days) filters by api_key_hash. GET https://openrouter.ai/api/v1/key returns usage, usage_daily, usage_weekly, usage_monthly, limit_remaining and applicable budgets for the calling key.

openrouter.ai ↗openrouter.ai ↗openrouter.ai ↗openrouter.ai ↗

Mistakes Bolt.new apps make at launch

  1. Database tables shipped without row-level security or with 'anyone can read' rules.

    TNW (April 2026) reports Bolt.new's default configuration leaves RLS disabled; scanner vendors describe Bolt tables frequently deployed with RLS off. Bolt's own database security check exists to flag 'a permission rule that allows anyone to read a table'.

    thenextweb.com ↗vibeappscanner.com ↗support.bolt.new ↗

  2. AI key kept in .env (e.g. VITE_OPENAI_API_KEY) and read from browser code.

    Bolt's secrets page warns .env values read by browser code end up in what's sent to every visitor; Vite bundles VITE_-prefixed variables into client code.

    support.bolt.new ↗vibe-eval.com ↗

  3. AI server function left callable by anyone (JWT verification off, CORS '*', no rate limit).

    Bolt's own troubleshooting example for an OpenAI chatbot sets Access-Control-Allow-Origin to '*', and its webhook fix is to turn off JWT verification for the function; Bolt documents no rate limiting. Copied onto an AI endpoint this makes a public, unthrottled bill.

    support.bolt.new ↗support.bolt.new ↗

Questions

How do AI calls work in a Bolt.new app with OpenRouter?

Bolt.new apps call OpenRouter with your own API key, from server code, so OpenRouter's own limits are your safety net.

Can Bolt.new cap AI spending per user?

You add it. Ask Bolt: 'Create an ai_usage table in the Bolt database and, in the server function that calls OpenAI, sum today's cost for the signed-in user and return a daily-limit error before calling the provider when it's over $2.'

Where should the OpenRouter key live in Bolt.new?

Partly. Secrets (database icon → Secrets) only reach server functions, but .env values read by browser code ship with the site, so ask Bolt: 'Move every AI key out of .env and VITE_ variables into Secrets and call providers only from server functions,' then run Publish → Run security audit.

How do I stop one user running up my OpenRouter bill?

Add a per-user daily cap in your own code, checked before every AI call. Then set a limit at OpenRouter as a backstop: Key dialog → 'Key limit' → 'Credit limit', reset interval and 'Include BYOK usage in limit' (toggle appears only with BYOK keys configured). API: PATCH https://openrouter.ai/api/v1/keys/{key_hash} with limit (USD), limit_reset (daily, weekly, monthly; unset = lifetime; resets at midnight UTC) and include_byok_in_limit (default false).

More checklists