REST API
Overview
Section titled “Overview”Rebase automatically generates a complete API from your collection definitions:
- REST API — CRUD endpoints for every collection at
/api/data/:slug - OpenAPI spec — Machine-readable spec at
/api/docs - Swagger UI — Interactive API explorer at
/api/swagger(dev mode only)
No code is required — define your collections and the API appears automatically.
REST Endpoints
Section titled “REST Endpoints”For each collection, the following endpoints are generated:
| Method | Path | Description |
|---|---|---|
GET |
/api/data/:slug |
List entities |
GET |
/api/data/:slug/count |
Count entities |
GET |
/api/data/:slug/:id |
Get a single entity |
POST |
/api/data/:slug |
Create a entity |
PUT |
/api/data/:slug/:id |
Update a entity |
DELETE |
/api/data/:slug/:id |
Delete a entity |
Subcollection Routes
Section titled “Subcollection Routes”Nested relations are accessible via URL paths:
GET /api/data/authors/42/posts → list author's postsGET /api/data/authors/42/posts/7 → get a specific post by authorPOST /api/data/authors/42/posts → create a post for authorPUT /api/data/authors/42/posts/7 → update the postDELETE /api/data/authors/42/posts/7 → delete the postRouting Mechanics & Segment Parsing
Section titled “Routing Mechanics & Segment Parsing”To handle arbitrary nested subcollection depths, Rebase routes incoming requests using Hono’s :rest{.+} parameter regex. The internal segment parsing engine analyzes paths by counting slash-separated segments:
- Odd segment count (e.g.,
authors/42/posts-> 3 segments) represents a collection list request. - Even segment count (e.g.,
authors/42/posts/7-> 4 segments) represents an operation on a specific entity ID. The last segment is popped as the targetentityId.
The engine filters out reserved system namespaces (e.g., history) from the path segment analysis to prevent collisions with built-in endpoints.
Authentication
Section titled “Authentication”All data endpoints require authentication by default. Include a Bearer token in the Authorization header:
curl -H "Authorization: Bearer <access-token>" \ https://api.example.com/api/data/productsFor server-to-server calls, use the service key:
curl -H "Authorization: Bearer <service-key>" \ https://api.example.com/api/data/productsFiltering
Section titled “Filtering”Use PostgREST-style query parameters to filter results. The format is ?field=operator.value:
# Exact matchGET /api/data/products?active=eq.true
# Comparison operatorsGET /api/data/products?price=gt.100GET /api/data/products?price=lte.50
# Multiple filters (AND)GET /api/data/products?active=eq.true&price=gt.10
# IN operator — match any value in a setGET /api/data/products?status=in.(draft,published)
# NOT INGET /api/data/products?status=nin.(archived,deleted)
# Array containsGET /api/data/products?tags=cs.electronics
# Array contains anyGET /api/data/products?tags=csa.(electronics,books)Filter Operators
Section titled “Filter Operators”| Operator | Meaning | Example |
|---|---|---|
eq |
Equals (==) |
?active=eq.true |
neq |
Not equals (!=) |
?status=neq.draft |
gt |
Greater than (>) |
?price=gt.100 |
gte |
Greater or equal (>=) |
?price=gte.100 |
lt |
Less than (<) |
?price=lt.50 |
lte |
Less or equal (<=) |
?price=lte.50 |
in |
In array | ?status=in.(a,b,c) |
nin |
Not in array | ?status=nin.(a,b) |
cs |
Array contains | ?tags=cs.value |
csa |
Array contains any | ?tags=csa.(a,b) |
Logical Operators
Section titled “Logical Operators”Use or and and for complex conditions:
# OR: match products that are either cheap or on saleGET /api/data/products?or=(price.lt.10,on_sale.eq.true)
# AND: explicit conjunctionGET /api/data/products?and=(active.eq.true,price.gt.0)Sorting
Section titled “Sorting”Use orderBy with the format field:direction:
# Sort by price descendingGET /api/data/products?orderBy=price:desc
# Sort by name ascending (default)GET /api/data/products?orderBy=name:ascPagination
Section titled “Pagination”Use limit and offset, or page:
# Limit and offsetGET /api/data/products?limit=20&offset=40
# Page-based (uses default limit of 20)GET /api/data/products?page=3The default limit is 20, the maximum is 100.
Response Format
Section titled “Response Format”List responses include pagination metadata:
{ "data": [ { "id": 1, "name": "Widget", "price": 29.99 }, { "id": 2, "name": "Gadget", "price": 49.99 } ], "meta": { "total": 150, "limit": 20, "offset": 0, "hasMore": true }}Single entity responses return a flat object:
{ "id": 1, "name": "Widget", "price": 29.99, "created_at": "2026-01-15T10:30:00Z"}Text Search
Section titled “Text Search”Use searchString for full-text search across string fields:
GET /api/data/products?searchString=wireless%20keyboardVector Search
Section titled “Vector Search”If a collection defines a property with a type of vector, you can perform high-speed similarity searches using pgvector distance operations compiled directly in the database query.
GET /api/data/products?vector_search=embedding&vector=[0.15,0.22,-0.05]&vector_distance=cosine&vector_threshold=0.8Vector Query Parameters
Section titled “Vector Query Parameters”| Parameter | Type | Description |
|---|---|---|
vector_search |
string |
The name of the vector property to query against. |
vector |
string |
A JSON-serialized array of floats representing the query vector. |
vector_distance |
string |
The distance metric to evaluate. Supported values: cosine (default, <=>), l2 (<->), inner_product (<#>). |
vector_threshold |
number |
Maximum distance threshold. Only records with distance less than this threshold are returned. |
Relation Inclusion
Section titled “Relation Inclusion”Use the include parameter to embed related entities:
# Include specific relationsGET /api/data/articles?include=author,categories
# Include all relationsGET /api/data/articles?include=*Included relations are embedded directly in the response:
{ "id": 1, "title": "Getting Started", "author_id": 42, "author": { "id": 42, "name": "Jane Doe", "email": "jane@example.com" }}Field Selection
Section titled “Field Selection”Use fields to select specific columns:
GET /api/data/products?fields=id,name,priceLifecycle Hook Pipeline
Section titled “Lifecycle Hook Pipeline”Every REST mutation operation (POST, PUT, DELETE) runs through a strict, sequential hook execution pipeline:
Request ──► beforeSave/beforeDelete (blocking) ──► DB Operation ──► afterSave/afterDelete (deferred) ──► ResponseBlocking vs. Deferred Hooks
Section titled “Blocking vs. Deferred Hooks”-
Blocking Hooks (
beforeSave,beforeDelete) These hooks are executed synchronously in the main request cycle before committing the database transaction. They can modify incoming payloads, run custom validations, or abort the request entirely by throwing an error. -
Deferred Hooks (
afterSave,afterDelete) These hooks execute asynchronously after the database transaction has successfully committed. They use deferred promises (fire-and-forget), meaning they run in the background and do not block the client’s HTTP response. Ideal for sending webhooks, triggering push notifications, or queuing external tasks.
OpenAPI / Swagger
Section titled “OpenAPI / Swagger”- OpenAPI spec:
GET /api/docs— Returns the full OpenAPI 3.0 JSON specification - Swagger UI:
GET /api/swagger— Interactive API explorer (dev mode only)
The OpenAPI spec is auto-generated from your collection definitions and includes all endpoints, query parameters, and response schemas.
API Keys
Section titled “API Keys”API keys provide machine-to-machine authentication for agents, MCP servers, CI pipelines, and external integrations. They support per-collection permission scoping and optional full admin access.
Creating an API Key
Section titled “Creating an API Key”# Via CLIrebase api-keys create --name "My Integration" \ --permissions '[{"collection":"orders","operations":["read","write"]}]'
# Via REST (requires admin auth)curl -X POST http://localhost:3000/api/admin/api-keys \ -H "Authorization: Bearer <service-key>" \ -H "Content-Type: application/json" \ -d '{ "name": "My Integration", "permissions": [{ "collection": "orders", "operations": ["read", "write"] }] }'The response includes the full plaintext key (rk_live_...) exactly once — store it immediately.
Using an API Key
Section titled “Using an API Key”curl http://localhost:3000/api/data/orders \ -H "Authorization: Bearer rk_live_abc123..."Permissions and RLS: two independent gates
Section titled “Permissions and RLS: two independent gates”An API key’s request passes through two authorization checks, and both must allow it:
- The key’s permission list — collection × operation, checked at the route layer.
- Row-Level Security — API keys do not bypass RLS. A key runs as
uid: "api-key:<id>"with theservicerole (plusadminwhenadmin: true). Admin keys pass via the built-in admin policies; a non-admin key only sees rows that a security rule explicitly grants to theservicerole or to the public. Owner-style rules (owner_id = auth.uid()) never match an API key.
So a non-admin key with "*" permissions can still get empty results — that’s
RLS working, not a bug. Either grant the service role in the relevant
collections’ security rules, or use an admin key.
Custom Functions
Section titled “Custom Functions”Function invocations are scoped like collections, under the functions
namespace: {"collection": "functions", "operations": ["write"]} grants every
function, "functions/<name>" grants one, and the global "*" wildcard grants
all. A key without such an entry cannot invoke functions at all.
Storage
Section titled “Storage”Storage works the same way, under the storage namespace:
{"collection": "storage", "operations": ["read", "write"]} lets the key
download/list (read), upload and create folders (write), and delete files
(delete). The global "*" wildcard also grants storage. A key without such
an entry cannot touch storage. TUS resumable-upload routes count as write
for every step (including the offset check and cancel), so a write-scoped key
can complete an upload on its own.
Admin Access for Agents and MCP
Section titled “Admin Access for Agents and MCP”By default, API keys get the service role (data access only). Add "admin": true to grant the key full admin access — including /api/admin/* routes for schema management, user management, and more, plus cron, backups, and logs. Use this for agents, MCP servers, and CI:
# CLIrebase api-keys create --name "My Agent" --admin --full-access
# RESTcurl -X POST http://localhost:3000/api/admin/api-keys \ -H "Authorization: Bearer <service-key>" \ -H "Content-Type: application/json" \ -d '{ "name": "My Agent", "admin": true, "permissions": [{ "collection": "*", "operations": ["read", "write", "delete"] }] }'Key Options
Section titled “Key Options”| Field | Type | Description |
|---|---|---|
name |
string |
Human-readable label |
permissions |
ApiKeyPermission[] |
Per-collection access ("*" = everything; "functions/<name>" = one function; "storage" = file storage) |
admin |
boolean |
Grant admin role — admin routes + RLS admin policies |
rate_limit |
number | null |
Requests per 15-min window (null = the server default, 1000) |
expires_at |
string | null |
ISO-8601 expiration timestamp |
The CLI requires an explicit scope: pass --permissions '<json>' or opt into
--full-access — there is no silent full-access default.
Keys can be listed, updated, and revoked via /api/admin/api-keys or the rebase api-keys CLI commands.
Metadata Endpoint
Section titled “Metadata Endpoint”Get a list of all available collections and their structure:
GET /api/collectionsNext Steps
Section titled “Next Steps”- Client SDK — Type-safe client for the REST API
- Collections — Define your data schema
- Security Rules (RLS) — Control access per row
