Skip to content
Zeitlos
Dashboard

API reference

Every database method, query modifier and filter operator in the Zeitlos SDK.

The database surface of @zeitlosapp/sdk.

Important

These calls are server-side only — server components, route handlers, server actions. See the quickstart.

Create Client

To operate with the database you'll need to create a client first.

TypeScript
import { createClient } from '@zeitlosapp/sdk';

const client = createClient(); // zero-config in a hosted app
const client = createClient<Database>(); // Define types for the shape of your database

Methods

TypeScript
await client.from('posts').list();
await client.from('posts').get(id);
await client.from('posts').create({ title: 'Hello' });
await client.from('posts').update(id, { published: true });
await client.from('posts').delete(id);
MethodReturnsNotes
list(){ records, nextCursor?, count? }Applies any chained modifiers
get(id)the recordThrows record_not_found if missing
create(input)the created recordDon't pass id, created_at, updated_at
update(id, input)the updated recordOnly the fields you pass
delete(id)void

Query modifiers

Chain these before list():

ModifierDescription
.filter(filter)Restrict results — see below
.sort(...fields)'field' ascending, '-field' descending; multiple allowed
.select(...fields)Return only these fields
.expand(...fields)Inline related records one level deep, for relation fields
.limit(n)Page size — the gateway caps it
.cursor(c)Fetch the page after a previous result's nextCursor
.withCount()Also return the total match count
TypeScript
const { records, nextCursor, count } = await client
  .from('posts')
  .filter({ published: true })
  .sort('-created_at')
  .limit(20)
  .withCount()
  .list();

const nextPage = await client.from('posts').cursor(nextCursor).list();

Filters

A filter is an object. A bare value means equals; an object means { operator: value }. Top-level fields are ANDed together.

TypeScript
.filter({ status: 'open' })                      // equals
.filter({ views: { gte: 100 } })                 // one operator
.filter({ title: { contains: 'sale' } })         // string operator
.filter({ tag: { in: ['a', 'b'] } })             // membership
.filter({ archivedAt: { isNull: true } })        // null check

Compose with and, or and not:

TypeScript
.filter({ or: [{ pinned: true }, { featured: true }] })
.filter({ and: [{ views: { gte: 100 } }, { status: 'open' }] })
.filter({ not: { status: 'draft' } })

Operators

OperatorMeaning
eq / neqEquals / does not equal
gt / gteGreater than / or equal
lt / lteLess than / or equal
in / ninIn / not in a list
containsString contains
startsWith / endsWithString prefix / suffix
isNullIs (or is not) null

Which operators are valid depends on the field's type. The gateway rejects an illegal combination with a ZeitlosError.

Errors

Every failure throws a ZeitlosError with a machine-readable .code and, for gateway errors, an HTTP .status.

TypeScript
import { ZeitlosError } from '@zeitlosapp/sdk';

try {
  await client.from('posts').get(id);
} catch (err) {
  if (err instanceof ZeitlosError && err.code === 'record_not_found') {
    // 404
  }
}
CodeWhen
record_not_foundget, update or delete on an id that doesn't exist
validation_failedA value didn't match the field's type or constraints
unique_violationA unique field already holds that value
forbiddenAn access rule or the key's tier denied it
invalid_filterA filter used an operator the field doesn't support
table_not_foundNo such table in this project
field_not_foundNo such field on that table
database_not_enabledThe project has no database yet
quota_exceededA plan limit was hit
network_errorThe service couldn't be reached
config_errorNo URL or key available to the client

Treat unknown codes generically — the list isn't closed.

SDK limitations

The SDK currently does not support any APIs to manage the schema of your database. Creating or altering tables and fields happens in the dashboard or through the MCP server.

There is no SQL API available.