Build a backend in minutes
Turn one Plexivo Postgres into your app’s backend: a table, sign-in for your users and a Data API, called from JavaScript or Flutter.
In this guide you create a database, add a table that each user can see only their own rows of, and read and write it from your app, with no backend server to write or run. Read Plexivo Postgres as a backend for everything it can do.
1. Create a database#
Choose Create, then Plexivo Postgres, and create it as in Create your first database. Wait until it is running.
2. Turn on the Data API#
- Open the Connect tab and find From a browser or mobile app.
- Set the Allowed web origin to the exact HTTPS address your web app runs on, for example
https://app.example.com. Requests from a browser on any other origin are refused. Leave it empty if only a mobile app or your server will call the API. - Choose Turn on Data API. Copy the Project URL and the Publishable key. The secret key is shown once: store it in Plexivo Secrets; you will not need it in your app.
https:// origin is accepted, so http://localhost:5173 is refused. Serve your development build over HTTPS on a fixed port and use that address, such as https://localhost:5173, as the origin. Requests without a browser origin, from a mobile app, Node or a test script, are not checked against it. The console sets one origin when you turn the Data API on; to change the list later (up to 20 origins), send PUT /api/v1/tenants/{tenant_id}/client-data-projects/{id} with {"allowed_origins": [...]} and an API key.3. Turn on sign-in#
Email and password sign-in is on as soon as the Data API is; the Authentication tab lists it under Providers. To add Google, GitHub or Microsoft later, open Sign-in methods on the same tab and add your own OAuth client.
4. Create a table with a policy#
Open the SQL editor tab and tick Write mode; you confirm each statement before it commits. The editor runs one statement at a time, so run these two separately:
create table notes (
id bigint generated always as identity primary key,
owner uuid not null default auth.uid(),
body text not null,
created_at timestamptz not null default now()
)alter table notes enable row level securityThe SQL editor creates tables and indexes but not policies. Add the policy from your laptop with psql through the Plexivo CLI. In one terminal, open a tunnel to your database; it prints the connection string to use:
plexivo db connect my-backendIn a second terminal, run the policy with that connection string and your database password:
psql "postgresql://…@127.0.0.1:5432/…" -c "create policy notes_owner on notes
for all to authenticated
using (owner = auth.uid())
with check (owner = auth.uid())"The table is reachable through the Data API only because row-level security is on and it has a policy. The policy lets a signed-in user see and change only their own notes, and owner fills itself in with their id.
From a server, you can instead send all three statements in one request to the Data API’s /sql/v1 with the secret key. See SQL editor for what runs where.
5. Call it from your app#
JavaScript and TypeScript, for the browser, React Native, Vue or Node 20 and later:
npm install @plexivo/clientimport { createClient } from '@plexivo/client';
const db = createClient(PLEXIVO_DATA_URL, PLEXIVO_PUBLISHABLE_KEY);
await db.auth.signUp({ email, password });
await db.from('notes').create({ body: 'My first note' });
const notes = await db.from('notes')
.order('created_at', 'desc')
.limit(20);Flutter and Dart:
dependencies:
plexivo_client: ^0.3.0import 'package:plexivo_client/plexivo_client.dart';
final db = PlexivoClient(dataUrl, publishableKey);
await db.signUp(email: email, password: password);
await db.from('notes').create({'body': 'My first note'});
final notes = await db.from('notes')
.order('created_at', 'desc')
.limit(20);PLEXIVO_DATA_URL is the Project URL and PLEXIVO_PUBLISHABLE_KEY the publishable key from step 2.
6. Make it live#
On the Data API tab, choose notes and switch on Realtime. Then every signed-in user sees their own changes as they happen:
db.channel('changes:notes')
.onChange(({ type, record }) => console.log(type, record))
.subscribe();Next steps#
Updated 27 October 2026