Documentation
How to query a project's data from any frontend. Inside each project, the API tab shows these same examples with your real keys.
Authenticating requests
Every request carries the apikey header. Each project has two keys:
| Key | Where to use it | What it allows |
|---|---|---|
anon | Browser / mobile app | Whatever each table's access rules allow |
service | Only on your server | Everything, it ignores the rules |
When a user signs in they receive a token; also send it in Authorization: Bearer <token>.
Tables
| Method | Path | Action |
|---|---|---|
GET | /api/v1/PROJECT_REF | List tables and columns |
GET | /api/v1/PROJECT_REF/tables/<table> | List rows |
POST | /api/v1/PROJECT_REF/tables/<table> | Insert one row (object) or several (list) |
GET | /api/v1/PROJECT_REF/tables/<table>/<id> | Get one row |
PATCH | /api/v1/PROJECT_REF/tables/<table>/<id> | Update columns of a row |
DELETE | /api/v1/PROJECT_REF/tables/<table>/<id> | Delete a row |
Listings respond with {"data": [...], "count": 42}, where count is the total without pagination.
Filters, ordering and pagination
Filter with column=operator.value. Operators: eq, neq, gt, gte, lt, lte, like, ilike, is (null/true/false) and in.
GET /api/v1/PROJECT_REF/tables/products?price=gte.10&name=ilike.%25coffee%25&order=price.desc&limit=20&offset=40&select=id,name,price GET /api/v1/PROJECT_REF/tables/products?category=in.(drinks,desserts)&stock=is.null
User login
| Method | Path | Body / result |
|---|---|---|
POST | /api/v1/PROJECT_REF/auth/signup | {"email", "password", "data"?} → {user, token} |
POST | /api/v1/PROJECT_REF/auth/login | {"email", "password"} → {user, token} |
GET | /api/v1/PROJECT_REF/auth/user | Current user (requires token) |
PATCH | /api/v1/PROJECT_REF/auth/user | {"data": {...}} saves profile data |
Access rules per table
| Rule | Read | Write |
|---|---|---|
| Public | anyone | anyone |
| Public read | anyone | signed-in users |
| Signed-in users | signed-in users | signed-in users |
| Owner | only their rows | only their rows (automatic owner_id) |
| Private | service key | service key |
File storage
Enable it in the project's Storage tab and create buckets. Public buckets give every file a direct URL; private ones serve files only to the uploader, with the service key, or through a signed URL that expires.
| Method | Path | Action |
|---|---|---|
GET | /api/v1/PROJECT_REF/storage | List buckets |
GET | /api/v1/PROJECT_REF/storage/<bucket>?prefix= | List files |
POST | /api/v1/PROJECT_REF/storage/<bucket>/<path> | Upload (multipart field file; ?upsert=true replaces) |
DELETE | /api/v1/PROJECT_REF/storage/<bucket>/<path> | Delete a file |
POST | /api/v1/PROJECT_REF/storage/sign/<bucket>/<path> | Signed URL: {"expires_in": 3600} |
GET | /storage/v1/PROJECT_REF/<bucket>/<path> | Download (?token= for signed URLs) |
const bucket = db.storage.from("avatars") await bucket.upload("users/ana.png", file, { upsert: true }) const url = bucket.getPublicUrl("users/ana.png") const { data: link } = await bucket.createSignedUrl("users/ana.png", 3600)
Web analytics
Enable it in the project's Analytics tab and add this tag to the <head> of your website. It sets no cookies and stores no IP addresses.
<script defer data-project="PROJECT_REF" src="http://falcondatabase.com/a.js"></script>
Campaigns: add utm_source, utm_medium and utm_campaign to your links.
Portal
The project's Portal tab publishes a standalone app at /app/<username>/<address>/. The project's users sign in there and view or edit the tables you choose, without writing any frontend code.
JavaScript SDK
A single file, no dependencies or build step. Import it straight from your server:
import { createClient } from "http://falcondatabase.com/sdk/falcondb.js" const db = createClient("http://falcondatabase.com", "PROJECT_REF", "ANON_KEY") // Chainable queries const { data, count, error } = await db.from("products") .select("id,name,price") .gte("price", 10) .ilike("name", "%coffee%") .order("price", { desc: true }) .range(0, 19) // Write await db.from("products").insert({ name: "Coffee", price: 2.5 }) await db.from("products").update(7, { price: 3 }) await db.from("products").delete(7) // Login (the token is stored in localStorage and sent automatically) await db.auth.signUp({ email, password }) await db.auth.signIn({ email, password }) const { user } = await db.auth.getUser() db.auth.signOut()
Every call returns { data, error }: it never throws on API errors.
API error messages follow the browser language (Accept-Language header).