Skip to content

Backend with Tadabase

Reading data

Fetch records from your Tadabase tables, from both server and browser.

From the browser

The browser SDK — imported as tada from src/lib/tada.ts — is the fastest path. tada.records.list() takes a table's api_slug (from tada/schema.json) and returns the RLS-scoped records for the signed-in user. Wrap it in useJson for loading / error / revalidation state.

src/pages/Customers.tsx tsx
import { useJson } from '@/lib/useJson';
import { tada } from '@/lib/tada';

export default function Customers() {
  const { data, error, isLoading } = useJson(() =>
    tada.records.list('customers', { limit: 25, order: 'created_at', orderBy: 'desc' }),
  );

  if (isLoading) return <p>Loading…</p>;
  if (error) return <p>Failed to load.</p>;

  return (
    <ul>
      {data?.items?.map((c) => <li key={c.id}>{c.field_1}</li>)}
    </ul>
  );
}

list() takes far more than page and limit. Filter with a condition group, keyword-search across searchable fields, and pull aggregates in the same call — all applied server-side, all still RLS-scoped.

tsx
// Overdue invoices, newest first, with a total
const { data } = await tada.records.list('invoices', {
  filters: { items: [{ field_id: 'field_22', operator: 'is before today' }] },
  order: 'field_22', orderBy: 'desc',
  summary: ['count', 'sum:field_114'],
});
// data.items = [...]   data.summary = { count: 7, 'sum:field_114': 12500 }

From a backend route

When you need custom server logic — combining tables, calling a secret-guarded API, shaping a response — use the server SDK (TadaServer) inside a route under routes/. Pass the end-user's token so RLS still applies as that user.

routes/svc.js js
import { TadaServer } from '../lib/tada-server.js';

const tada = TadaServer.fromEnv();

export async function listCustomers(req, res) {
  const token = req.headers.authorization?.replace('Bearer ', '');
  const { status, body } = await tada.listRecords(token, 'customers', { limit: 25 });
  res.status(status).json(body);
}

RLS just works

Every data call runs as the signed-in user through the Domain API. Tadabase's RLS is enforced server-side, record-by-record and field-by-field — if a user can't see a row in the builder, they can't see it through Vibe either.

Ready to build

Skip the docs.
Just describe it.

Tadabase AI builds it, hosts it and keeps it running. Real backend, real domain, real app.

Start Building