Feature
The API is your schema
Every table is served by PostgREST, reading directly from the PostgreSQL catalog. No registry to keep in sync — a table created a second ago is queryable now.
- Generated
- API Generation
- Works with
- Any frontend
- Plan
- Free to start
What is API Generation?
Every table in your project is served by PostgREST — the same engine Supabase runs — reading directly from the PostgreSQL catalog. There is no separate API registry to generate, deploy, or keep in sync: the API *is* the schema, so a table created a second ago is queryable immediately, and a column renamed a second ago is reflected without a rebuild. You get filtering, ordering, pagination, full-text search, and embedded resources across two surfaces that share one engine and one authorization path.
How it works
Backenly exposes two surfaces over the same engine. `/api/v1/{projectId}/db/{table}` is Backenly's stable REST contract — list, create, get, update, delete with typed responses. `/api/v2/{projectId}/{table}` passes PostgREST's native grammar through untouched: `?price=gte.100`, `?or=(a.eq.1,b.eq.2)`, `?order=created_at.desc`, and embedded resources — `?select=*,author(*)` returns a post and its author in one round trip. If you already know Supabase or PostgREST, you know this API.
Why it matters
Generated API layers drift. The moment the code that serves your data is separate from the schema that defines it, the two can disagree — and that gap is where stale endpoints, forgotten authorization checks, and 'the table exists but the API doesn't' bugs live. Reading from the catalog removes the gap by construction. Authorization is enforced by PostgreSQL grants and row-level security rather than by application code, so a request for another tenant's rows fails on a missing database privilege instead of on a check somebody remembered to write.
In practice
Every endpoint is testable from the dashboard the moment it exists: the APIs view lists each route per table, and an inline tester sends real requests against your live backend — type a JSON body into POST /auth/signup, send it, and watch the actual HTTP response, then open the users table and see the row it created. From code, the SDK mirrors the API one-to-one: backend.tasks.list({ where: { status: 'todo' }, orderBy: 'due_date', limit: 25 }) for filtered queries, backend.projects.list({ include: ['tasks'] }) to resolve relations server-side in one request, and backend.tasks.count(...) when you need numbers without rows. Because row-level security lives in the database, all of these return only what the calling user is allowed to see — there is no way to forget an authorization check in your client code.
What you get
Two surfaces, one engine
/api/v1 is Backenly’s stable REST contract — list, create, get, update, delete with typed responses. /api/v2 is PostgREST’s native grammar, passed through untouched. Both read the same catalog and share one authorization path.
Embedded resources in one round trip
?select=*,author(*) returns a post and its author together — the relationship is resolved from the foreign key in the catalog, so there is nothing to configure and no N+1 to hand-optimize.
Authorization in the database, not the app
Grants and row-level security decide what a request can reach. A read for another tenant’s rows — or for the auth table, or through an embedded resource — is refused by Postgres itself, not by a check in application code that someone has to remember to write.
Typed clients and a drift gate
Generate an OpenAPI spec and a typed client from the CLI. `backenly diff` exits non-zero when your committed types drift from the live schema, so contract drift fails CI instead of production.
Common questions
Is this a custom API layer or a real standard?
It is PostgREST — the same open-source engine Supabase runs — reading directly from your PostgreSQL catalog. On query capability Backenly is at parity with Supabase: same engine, same grammar, embedded resources included. If you already know one, you know the other.
Do I have to regenerate the API when my schema changes?
No. The API is the schema. PostgREST reads the catalog, so a table or column created a second ago is queryable immediately — there is no registry to regenerate, redeploy, or keep in sync.
Can I add custom API logic or custom endpoints?
Yes — serverless TypeScript functions and event triggers add custom business logic that runs on API events, on a schedule, or at a public HTTPS endpoint.
Is there API documentation?
Every project’s live endpoints are browsable in the dashboard with an inline request tester, and the CLI exports an OpenAPI spec plus a typed client for your codebase.