Kreo — Backend as a Service (BaaS): Postgres, REST API, Auth & Realtime
EN<br>FR
Try it. It's free.<br>Sign in
Postgres, with an API.
Kreo is a Backend-as-a-Service — built for developers. You write SQL, and every table gets an automated REST API, realtime subscriptions and a Redis cache. We run the servers, the backups, the TLS — all of it.
Try it. It's free.<br>Read the docs
Try the live API demo — no signup<br>Free during beta · 100k requests/month · no card.
# every table you make is already a REST endpoint<br>curl https://app.kreo.work/api/rest/users \<br>-H "x-kreo-api-key: $KREO_KEY"
{ "id": 1, "email": "ada@kreo.work", "plan": "growth" },<br>{ "id": 2, "email": "linus@kreo.work", "plan": "starter" }<br>Postgres 15 · Redis · WebSockets · pgvector · WebAuthn · AES-256
cached reads
servers to think about
ORMs to fight
EU<br>hosted and operated
What is this
A hosted Postgres database. You write your schema in SQL, and you get a REST API, realtime over WebSockets, a Redis cache and auth on top. No ORM. No boilerplate. No servers to babysit.
Teams kept rebuilding the same backend for every project — Postgres, auth, a CRUD API, a cache, websockets. The same week of work, every time. So we built it once, properly, and now we host it. You design tables, you call the API. We handle pooling, backups, TLS and the 3am pages.
It's not magic. It's Postgres you don't have to operate.
From zero to an API
Five minutes, start to finish.
01
Sign up
You get a Postgres database. Empty, and yours.
02
Make a table
In the SQL console or the table editor.
CREATE TABLE todos (<br>id bigserial PRIMARY KEY,<br>task text NOT NULL,<br>done boolean DEFAULT false<br>);
03
Call it
Grab an API key and hit the endpoint.
curl https://app.kreo.work/api/rest/todos \<br>-H "x-kreo-api-key: $KREO_KEY"
What you get
Six things. One server. Real code.
A REST API, generated from your tables
Create a table, it's an endpoint. GET, POST, PATCH, DELETE. Filtering, sorting and pagination live in the query string — nothing to wire up.
Filter with ?plan=eq.growth<br>Sort and paginate in the URL<br>JSON in, JSON out
# filter, sort, paginate — all in the URL<br>curl "https://app.kreo.work/api/rest/users?plan=eq.growth&order=created_at.desc&limit=20" \<br>-H "x-kreo-api-key: $KREO_KEY"
# write a row<br>curl -X POST https://app.kreo.work/api/rest/posts \<br>-H "x-kreo-api-key: $KREO_KEY" \<br>-d '{ "title": "hello", "body": "first one" }'
Realtime over WebSockets
Your data, live. Subscribe to a table and get an event on every INSERT, UPDATE and DELETE. No polling, no cron, no glue.
Per-table channels<br>INSERT / UPDATE / DELETE<br>Push straight to the UI
const ch = kreo.channel("messages")
ch.on("INSERT", row => addToFeed(row))<br>ch.on("UPDATE", row => patchRow(row))<br>ch.on("DELETE", row => removeRow(row.id))
ch.subscribe()
Turbo-Cache, backed by Redis
Flip caching on per table. Reads come from Redis instead of disk, in single-digit milliseconds. And cached reads don't count against your quota.
Per-table, one toggle<br>Writes bust the cache automatically<br>Cached reads are free
GET /api/rest/products
200 OK<br>X-Cache: HIT<br>X-Response-Time: 4ms
Snapshots, before you break things
Take a snapshot before a risky migration. If it goes sideways, restore it in one call. Sleep better.
One call to snapshot<br>One click to restore<br>Keep as many as you need
# snapshot before a risky migration<br>curl -X POST https://app.kreo.work/api/db/snapshots \<br>-H "x-kreo-api-key: $KREO_KEY" \<br>-d '{ "name": "before-migration" }'
Auth and API keys
Email and password, passkeys, TOTP for humans. Scoped API keys for machines. Lock a key to an IP range if you're paranoid — and you should be.
Passkeys (WebAuthn) and TOTP<br>API keys with IP allowlists<br>Sessions are stateless JWTs
import { createClient } from "@kreo/client"
const kreo = createClient({ apiKey: process.env.KREO_KEY })<br>const { data } = await kreo.from("orders").select()
One real Postgres per project
Not a wrapper, not a toy. A real Postgres schema, isolated from everyone else at the database-role level. Bring your own SQL — views, indexes, constraints, pgvector.
Your own schema, isolated<br>Indexes, views, constraints<br>pgvector for embeddings
CREATE TABLE posts (<br>id bigserial PRIMARY KEY,<br>title text NOT NULL,<br>body text,<br>created_at timestamptz DEFAULT now()<br>);
CREATE INDEX idx_posts_created ON posts (created_at DESC);
Also in the box
The boring stuff, already done.
The things that quietly eat a week each. They're here, tested, and you don't have to think about them.
Custom domains<br>Serve your API from api.yourapp.com. HTTPS sorts itself out.
Audit logs<br>Every sensitive action logged, with IP and user agent.
IP allowlists<br>Lock an API key to a CIDR range. Leaked key, useless elsewhere.
Connection pooling<br>Tuned for you. You won't run out of connections.
Multi-tenant isolation<br>Each org gets its own DB role. Enforced by Postgres, not by hoping.
Cache invalidation<br>A write to a table clears its cached reads. Automatically.
Typed SDK<br>Generate a...