Start
Getting started
Sign up for hosted dabadata, the realtime app backend, and you have a live row in a page of your own in a few minutes, with nothing to install. Everything on this page uses the hosted service at https://dabadata.com. Running dabadata on a server of your own is on Self-hosting; it speaks the same API, so what you build moves from one to the other.
Sign up
Open dabadata.com/console/auth/register and create an account with your email and a password. We mail you a confirmation link; open it in the same browser. Prefer no password? Use "Email me a link" on the sign-in page, or "Continue with Google" when it is offered. Free, no card. Ways to sign in has the details.
Your workspace and my-first-app
The confirmation signs you in to the console, where two things are waiting:
- A workspace named after your email, on the Free plan, with you as its owner. It is where your team, your plan and your projects live.
- A project called
my-first-appwith ataskstable and the rules of the demo: anyone signed in reads tasks, admins and editors create them, an admin or the task's owner updates one, only admins delete.
Every project has a live and a test environment with their own data and keys. Flip the switch in the top bar to test: that is where you try things.
Copy the keys
Open Keys. The environment the top bar is on comes first (the other one is folded below it). Each environment has two keys:
- The publishable key (
pk_test_...) names the project from a browser. It grants nothing by itself and is safe in your page. Copy it. - The secret key (
sk_test_...) bypasses every rule and belongs on a server. It is shown once, when it is made, and the keys ofmy-first-appwere made for you without being shown. Press Rotate secret key under the test keys, confirm, and copy the new one from the dialog. Rotating makes a new secret key and shows it once; the one it replaces keeps working for 24 hours, then stops.
Keep the secret key in your shell for the next step, not in any page:
export DABADATA_SECRET_KEY=sk_test_... # the test secret key you just copiedGet a user token
The tasks table is for signed-in people only, so the page needs someone to be. Your backend normally mints a token for each person after its own sign-in; for now, mint one by hand:
curl -X POST https://dabadata.com/v1/users/token \
-H "Authorization: Bearer $DABADATA_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"id":"alice","name":"Alice","role":"editor"}'{ "token": "<user token>", "expiresAt": "...", "refreshToken": "<refresh token>", "refreshExpiresAt": "..." }Alice is an editor, so she may create tasks. The token lives an hour; mint another when it runs out. Later you can let people sign up and sign in by themselves instead: Sign-in for your app's users.
Paste the snippet
Keys → Snippets → Plain HTML gives you a page built from your real values. Here it is with Alice's token and a form to add a task. Save it as index.html, put in your publishable key and the token, and open it in a browser:
<!doctype html>
<meta charset="utf-8">
<title>my-first-app</title>
<form id="add"><input name="title" placeholder="New task" required> <button>Add</button></form>
<ul id="rows"></ul>
<script src="https://dabadata.com/client/dist/dabadata.iife.js?v=5bce207b"></script>
<script>
const db = dabadata.createClient({
url: "https://dabadata.com",
key: "pk_test_EXAMPLEexample0000000000", // identifies the project (test); safe in a browser
token: "<user token>", // Alice, from the curl above
});
const rows = new Map();
const list = document.getElementById("rows");
const render = () => list.replaceChildren(...[...rows.values()].map((r) =>
Object.assign(document.createElement("li"), { textContent: r.title })));
db.subscribe("tasks", {}, {
onRows(all) { rows.clear(); for (const r of all) rows.set(r.id, r); render(); },
onChange({ op, row }) { if (op === "delete") rows.delete(row.id); else rows.set(row.id, row); render(); },
onError(err) { console.warn(err.explanation ?? err.message); },
});
document.getElementById("add").onsubmit = async (e) => {
e.preventDefault();
await db.insert("tasks", { title: new FormData(e.target).get("title") });
e.target.reset();
};
</script>Your first live row
Open the page in two tabs and add a task in one: it appears in both at once. dabadata filled in owner with Alice's id and done with its default, and sent the new row to every subscription allowed to read it. Back in the console, the Overview of the test environment now says Your app is live, and the call is in the trace with the rule that allowed it.
Now try a role that may not create: mint a token for {"id":"carol","role":"viewer"}, use it in the page and add a task. The insert is refused, and the browser console shows why: create tasks: denied, role "viewer" not in ["admin","editor"].
Where to go from here:
- Sign-in for your app's users - let people sign up, with hosted pages or
db.auth, instead of minting tokens. - Tables and Rules - your own tables and policy, applied as a definition (Definitions on a hosted project).
- Invite your team and see what each console page does.
- When it works on test, apply the same definition to live, switch the page to the live publishable key and put it online.
Hosting your app
The quickest way to put a static app online - a plain HTML page, or the build output of Vite, React, Vue, Svelte or Solid - is a site on dabadata itself: dabadata sites deploy ./dist --site my-app puts it at https://my-app.dabadata.site, next to its data, and adds that address to the environment's allowed origins for you. Your own domain can be connected from Starter.
Any other static host works too, such as Cloudflare Pages, Netlify or GitHub Pages. The page talks to https://dabadata.com straight from the browser with the publishable key, so there is nothing else to deploy.
- Put the site online and note its address, for example
https://my-app.pages.dev. - In the console, open Settings → Project on the environment the page uses and set its allowed origins (CORS) to that address. Then only your site can use the publishable key from a browser (Allowed origins). Keep
http://localhost:5173or similar on test while you develop. - The page on live uses the live publishable key; a preview build can keep the test key.
Anything that needs the secret key - minting user tokens, scripts, applying definitions - runs on a server or a serverless function of your own, never in the page.
From the terminal
The dabadata command-line tool does what the console does, from a terminal or a script: sign in once through the browser, then pull and push definitions, follow the trace and the logs, run SQL and export.
dabadata login # shows a code; approve it in the console
dabadata projects list
dabadata use prj_xxxxxxxxxxxx:test # the project and environment later commands act on
dabadata pull # the definition in force -> dabadata.json
dabadata types # TypeScript types of it -> dabadata-types.ts (createClient<Database>)
dabadata push # dry run, then apply on confirm (.json, or a .ts evaluated locally)
dabadata migrate rename tasks.title name --definition dabadata.json # keep the values; also drop-table, drop-column, retype
dabadata trace tail # every call as it happens, with the rule that decided it
dabadata sql "select count(*) from tasks"
dabadata mcp setup claude-code # the one-line MCP setup for your coding agentdabadata login opens a console page that asks "Approve sign-in for the dabadata CLI on <your computer>?" with the code the terminal shows; check that the two match and press Approve. It is a single file per platform (macOS and Linux, ARM and Intel) with nothing to install beside it; dabadata --help lists every command. Its sign-in is an account token that acts with your role in the workspace, listed with your sessions on the account page, where you can revoke it.