REST and admin API
Kurabase exposes a Supabase-style REST surface. The contract is deliberately smaller than PostgreSQL or PostgREST as a whole.
Data routes
| Route | Purpose |
|---|---|
GET /rest/v1/:table | Query a relation. |
POST /rest/v1/:table | Insert rows. |
PATCH /rest/v1/:table | Update matching rows. |
DELETE /rest/v1/:table | Delete matching rows. |
POST /rest/v1/rpc/:function | Call an SQL-language function. |
GET /meta/v1/instance | Discover public instance configuration and wallet-management support. |
POST /auth/v1/session/intent | Create an EIP-712 wallet-signing intent for { user, scope }. |
POST /auth/v1/session | Exchange a pre-signed session envelope. |
Requests include the publishable apikey. Authenticated requests add Authorization: Bearer <token>. The API uses PostgREST-style query parameters, Prefer for return and count semantics, and zero-based inclusive Range headers.
Browser CORS and local PNA
The application gateway is designed for direct browser requests. It responds to
CORS preflight with the methods and request headers used by @kurabase/js and
Supabase-style REST clients, including apikey, Authorization, Prefer,
profile and range headers. It exposes Content-Range and Kurabase block,
revision, and transaction headers to browser code.
No proxy is required merely to make frontend data requests. Send only the
publishable apikey from a browser. Administrative/server credentials never
become CORS-safe and must remain server-side.
For local pages, the gateway sends the Private Network Access opt-in required
by Chromium when an origin such as http://localhost:3010 accesses
http://127.0.0.1:55421. If preflight fails, first confirm the page is calling
the public application gateway URL from kura status and inspect the
OPTIONS response; a wallet prompt cannot repair a request that the browser
did not send.
Anonymous or default-context reads are possible only when RLS allows them. A regular write requires a valid independently issued session.
Filters
The supported surface includes eq, neq, gt, gte, lt, lte, is, in, like, ilike, match, not, and logical or or and expressions. These filters apply to reads and matching update or delete requests.
JSONB columns also support containment (cs) and contained-by (cd) with valid JSON values. For example, an object filter works with both official supabase-js and @kurabase/js:
await db.from('documents').select('id').contains('meta', { tags: ['red'] })
overlaps (ov) is supported for declared one-dimensional integer[], text[], boolean[], and uuid[] columns. Both SDKs serialize .overlaps('tags', ['red']) as a PostgreSQL array filter. JSON request bodies use ordinary JSON arrays for those typed columns. Ranges, multidimensional or bounded arrays, and JSONB overlap remain unsupported. For JSONB array containment used with the official SDK, pass a JSON filter expression such as .filter('meta', 'cs', '[3,1]'); the independent SDK also accepts a JavaScript array in .contains().
Administrative routes
Privileged SQL and migration endpoints accept either a generated dev-server credential for trusted automation or an owner/developer management wallet session. A local Dashboard uses its same-origin Studio proxy, which holds the dev-server credential inside the local stack; browser code never receives it.
| Route | Purpose |
|---|---|
GET /admin/v1/instance | Read instance metadata including contract, gateway, chain ID, authority state, block, and revision. |
GET /admin/v1/catalog | Read the relational catalog and applied migration list. |
POST /admin/v1/sql | Execute a SQL command and return rows, affected count, block, revision, and transaction hash. |
GET /admin/v1/migrations | List applied migration versions. |
POST /admin/v1/migrations | Submit { version, sql } as an atomic migration. |
GET /meta/v1/instance needs no project key and returns only public data: chain and contract identifiers, the delegated gateway state, a publishable project key, current revision information, and walletManagementSupported. It never returns a server credential, gateway signing key, or session token.
For wallet sign-in, the SDK posts { user, scope: 'user' | 'admin' } to /auth/v1/session/intent, verifies the returned EIP-712 domain and typed data, asks an EIP-1193 wallet to sign, then exchanges the signed envelope through /auth/v1/session. admin uses a distinct AdminSession type and is accepted only from a current owner or developer through a privileged delegated gateway. The Dashboard does not ask for a server key or pasted session token.
Keep any automation credential in a trusted server-side environment. Use kura key dev to explicitly print the local KURA_DEV_SERVER_KEY for a dev server; it is an operational gateway credential, not a browser setup value.
Stable failure behavior
The gateway returns structured error fields: code, message, details, and hint. Requests outside the supported SQL or REST contract fail explicitly rather than producing a best-effort result.