Build your product. Your agent sets up the backend.
dabadata is a hosted backend written for AI agents to read. Plain Postgres underneath, tables and rules in one definition,
live data, sign-in, file storage, AI calls and your frontend on your own domain. Every allow and deny comes with a sentence that explains it, so you can see every decision your agent made.
A table in Postgres. Plain rows in expenses: the three columns plus id, created_at, updated_at and created_by. Nothing to migrate away from.
Four rules. Anyone signed in reads. Members add expenses. Whoever paid edits their own. They or an admin delete.
A live feed. Subscribe once and every insert, update and delete you are allowed to see arrives over the socket.
An explanation on every decision.delete expenses: allowed by any[1] owner(paid_by): row.paid_by "dana" == user "dana"
What you get
A database with a brain on top
Everything below is built and running today, on one server, over plain Postgres tables.
Declared tables
Name a table and its columns - text, int, float, bool, date, datetime, json, userId or a ref - and dabadata creates a plain Postgres table. Every row also gets id, created_at, updated_at and created_by, which clients never set.
One rule per operation - read, create, update, delete - built from anyone, authenticated, role, owner, any and all. A missing rule means nobody, and an unsafe file is refused before it is applied.
Every evaluation returns a sentence naming the path that decided, like delete tasks: denied, role "viewer" not in ["admin"]. The client, the trace and the agent all get the same sentence.
Every call writes one row: who called, the op and table, the decision, the rule and its explanation, the values before and after. It also records the fan-out - how many live subscribers the change reached.
One socket carries all of a client's subscriptions. The server sends the matching rows, then a change message for every insert, update and delete the subscriber's read rule lets them see.
Your backend signs people in its own way and mints a user token with their id, name and role. Declare the providers you trust (Google, Apple, Clerk, Auth0, Firebase, Supabase, Keycloak or your own JWTs) and hand their tokens straight to dabadata. The project key is for your servers, view tokens are for the viewer, and a call with no token is anonymous.
An agent reads the schema with a plain-language summary of its rules, changes rows under those rules and reads the trace. It can simulate a decision before acting, and a denial comes back with its explanation.
The plugin mirrors a site's changes - posts, meta, users, comments, terms, WooCommerce orders - as they happen. The viewer, in wp-admin or on its own, shows Tables, Trace and a Rules simulator.
You describe the app. Your agent sets up the backend.
dabadata is written to be read by an AI agent: /llms.txt, every docs page as markdown, an OpenAPI file and an MCP server. You keep the parts that need you - what to build and whether it is right.
1
Sign up and hand over the keys
Free, no card. Copy the test environment's keys from the console into the project's .env, where the agent can read them and your browser code never ships them.
.envbash
DABADATA_URL=https://dabadata.com
DABADATA_PUBLISHABLE_KEY=pk_test_... # safe in a browser
DABADATA_SECRET_KEY=sk_test_... # server only
2
Tell your agent what to build
Claude Code, Cursor, Codex or any agent that reads the web and your files. One link teaches it the API, the rules and the safe way to write.
prompttext
Read https://dabadata.com/llms.txt
and follow it. My keys are in .env.
Build: a shared expenses app for my
flat - who paid what, who owes whom.
3
It checks the plan, then applies it
The agent writes the tables and one rule per operation, asks for a dry run, and applies only what it saw. Applying adds tables and columns, never drops one, and an unsafe definition is refused before anything changes.
Every denial names the rule that decided, in words, with a trace id. The agent fixes the rule or the call instead of retrying blind, and you can read the same trace in the console.
403 forbidden: the explanationtext
delete expenses: denied,
role "member" not in ["admin"]
# with a traceId for the full record
Debugging access is reading, not guessing. Every mutation, read and subscription leaves one row behind: who called, what they tried, which rule applied and the sentence that explains the outcome.
The simulator answers the question directly. As user X, on row Y, is this allowed, and which rule decided? It changes nothing and runs the same rule engine as the real call.
An agent reads the same trace. When its write is refused, the MCP server hands back the explanation and the trace id, so it can repair its own mistake instead of retrying blind.
Trace
live
10:43:02Carolviewerdenieddelete tasksdelete tasks: denied, role "viewer" not in ["admin"]
10:42:48Bobeditorallowedupdate tasksupdate tasks: allowed by any[1] owner(owner): row.owner "bob" == user "bob"-> 3 live subscribers
10:42:31Carolviewerdeniedinsert taskscreate tasks: denied, role "viewer" not in ["admin","editor"]
10:42:15Aliceadminallowedinsert taskscreate tasks: allowed by role: role "admin" in ["admin","editor"]-> 3 live subscribers
10:42:07Carolviewerallowedsubscribe tasksread tasks: allowed by authenticated: user "carol" is authenticated
Built for
One API, three ways in
Every way in uses the same API, the same rules and the same trace.
Developers
Integrate from your own app with the zero-dependency JS client or the HTTP API: insert, update, delete, query and subscribe. Every refusal arrives with its explanation and its trace id.
Point your own agent at the MCP server. It reads the schema and its rules in plain language, works under the same rules as everyone else, and reads the trace when something is refused.
Start with the WordPress plugin. It mirrors every change your site makes, so you watch your data flow live while the site keeps running exactly as it does today.