Skip to content
esc

Search pages and sections. Try a tool name, an error code, a route.

↑↓ navigate↵ openesc close

Guides · Guides

Host your app elsewhere

Your app talks to its project's API directly, from any origin: a publishable key in the browser, a secret key on your server. Everything you need is on the project's Deployments → Third-party tab, with a copy button for each step.

1 · The API URL#

The project's data API, https://proj-<id>.manybases.com/v1. Every call from your app goes there; it is the url of createClient(url, key).

2 · A publishable key#

The browser needs the project's pk_. Any publishable key of the project will do, whoever created it — your agent, the API keys screen or the panel of the Third-party tab: every one signs users up. (Until 2026-09-07 one issued by an agent was inert and could not; that rule is removed.) The value is shown once at creation; lost it? rotate it.

A secret key (sk_) is only needed if you have server code that must see every row; it is created by a signed-in human and never reaches a browser.

3 · Environment variables#

Paste into .env.local, then the same three where your host keeps environment variables (Vercel: Project → Settings → Environment Variables), and redeploy:

NEXT_PUBLIC_MANYBASES_URL=https://proj-<id>.manybases.com/v1
NEXT_PUBLIC_MANYBASES_PUBLISHABLE_KEY=pk_…   # paste the value shown once at creation
MANYBASES_SECRET_KEY=            # server-side only — never with a public prefix

NEXT_PUBLIC_ is Next's prefix for values inlined in the browser; Vite uses VITE_. The suffix is ours, and the SDK exports these names as ENV.

4 · Code#

bash
npm install @manybases/js
js
import { createClient } from "@manybases/js";

// Browser or server: the publishable key. It is public by design.
export const mb = createClient(
  process.env.NEXT_PUBLIC_MANYBASES_URL!,
  process.env.NEXT_PUBLIC_MANYBASES_PUBLISHABLE_KEY!,
);

const { data, error } = await mb.from("habits").list({ limit: 10 });
js
// Server only (a route handler, a server action): the secret key sees every row.
import { createClient } from "@manybases/js";

export const admin = createClient(
  process.env.NEXT_PUBLIC_MANYBASES_URL!,
  process.env.MANYBASES_SECRET_KEY!,
);

What to expect#

  • 300 requests per minute per key, shared by every visitor of your app: a paginated list costs one call per page.
  • The browser keeps the user's session in localStorage — your Content Security Policy protects it, the SDK cannot.
  • No automatic retry, no idempotency key unless you ask for one on insert.
  • CORS is open to every origin, without credentials: the API answers preflights before any check, and browsers cache them for up to two hours.
  • A site hosted on Manybases itself (manybases.online) is in exactly the same position: a different origin from the API, the same rules.

Next: SDK for the full surface, Access presets for what each visitor may read and write, Invite users for the first sign-ups.