stitchdb-js/management: create and run projects from code with an access token, including backups, compute, replicas, flags, cron, queues and every other dashboard feature. Also the agent client for agent keys.
stitchdb-js/management calls the Management API, the same API the CLI uses. It runs on a server (Node, Deno, Bun, Edge Functions), never in a browser: the tokens it takes can change and delete projects.
npm install stitchdb-jsimport { createManagementClient } from 'stitchdb-js/management'
const mgmt = createManagementClient({ accessToken: process.env.STITCHDB_ACCESS_TOKEN })
const { data: project, error } = await mgmt.projects.create({ name: 'shop' }, { idempotencyKey: 'pr-42' })
if (error) throw error
await mgmt.migrations.apply(project.ref, [{ version: '20261101000000', name: 'init', sql: 'create table orders (id bigint primary key)' }])
const { data: res } = await mgmt.database.query(project.ref, 'select count(*) from orders')#Options
| Option | Use |
|---|---|
accessToken | A personal access token (sdb_pat_…), organization token (sdb_org_…), OAuth access token or project token (sdb_prj_…). See Access tokens and Organization and project tokens. |
apiUrl | Default https://stitchdb.com |
fetch, headers | Your own fetch, extra headers on every request |
retries | How often 429, 502 and 503 answers are retried (default 3, waiting as long as Retry-After says) |
#Results and errors
Methods don't throw. Each one resolves to { data, error, status, nextCursor }. error is a ManagementError with the HTTP status, the message, and code and hint when the server sends them. SQL errors also carry the Postgres code, detail and position. For lists with pages, pass nextCursor back as cursor.
const { data, error, status } = await mgmt.backups.restore(ref, backupId)
if (error) console.error(status, error.message) // 403: your role cannot do thisA token only gets what it may do in the dashboard. Read-only tokens can read, organization tokens need the scopes each route lists (see the route tables), and some changes need the Administrator or Owner role in the project. Answers never contain stored keys or signing secrets.
#Projects and code
| Group | Methods |
|---|---|
projects | list, get, create, update, delete, pause, restore, restart, apiKeys, rotateKeys, limits, updateLimits, usage, metrics |
database | query, checkQuery, dump, types, advisors, queryPerformance, resetQueryPerformance |
migrations, branches | list, apply, check, repair / list, create, get, delete, merge, masking, setMasking, maskingPreview |
functions, secrets | list, get, deploy, update, delete, body, versions, logs, stats, usage / list, set, delete |
webhooks, logDrains, logs, domains | Project webhooks, log drains, log search, custom domains |
integrations | vercel.* and cloudflare.* (list, browse, link, update, sync, unlink), github.* |
authConfig | get, update, sso.list, sso.create, sso.update, sso.delete (SAML providers) |
organizations, tokens, claimLinks, agents | Members, invitations, the audit log, organization and project tokens, claim links, agent keys and approvals |
#Dashboard features
| Group | Methods |
|---|---|
backups | list, create, restore, exportLink, downloadLink, pitr, restoreToTime, jobs, job, restoreTable |
compute, replicas | get, catalog, estimate, change / list, add, remove, auto.get, auto.set |
budget, exports | get, set, delete, test / list, start, startImport, restoreImport, delete |
flags | get, enable, disable, create, update, delete, stats, segments.*, history, restore, test |
rateLimits, inbound | get, update, installSql, removeSql / get, enable, disable, endpoints.*, events.* |
statusPage | get, enable, disable, update, incidents.* (create, update, editUpdate, delete), subscribers.* |
cron, queues | list, runs, create, update, delete / list, create, delete, messages, send, read, archive, deleteMessage |
push, purchases | get, configure, test, disable / get, configure, testWebhook, retryDelivery, disable |
links, metering | get, enable, disable, updateSettings, items.* / the same, plus setStripe, stripeCustomers, setStripeCustomers, retryStripe, customers, customer, export (CSV text) |
heartbeat, crashes | get, enable, disable, updateSettings, test, monitors.* (rotateToken) / the same with issues.* |
recycleBin, history, sharedViews | get, setTable, restore, purge / get, setTable, revert / list, create, get, update, delete, addMembers, removeMember, audit |
// Restore to a point in time into a new branch, then look at the job
const { data: job } = await mgmt.backups.restoreToTime(ref, { target_time: '2026-11-01T12:00:00Z', branch: 'before-incident' })
await mgmt.backups.job(ref, job.id)
// A bigger compute size: pick one from the catalog, price it, then change (billed from the prepaid balance)
const { data: sizes } = await mgmt.compute.catalog(ref)
await mgmt.compute.estimate(ref, { size_key: 'sz_…' })
await mgmt.compute.change(ref, { size_key: 'sz_…' })
// Feature flags, cron and queues
await mgmt.flags.enable(ref)
await mgmt.flags.create(ref, { key: 'new-checkout', type: 'boolean', enabled: true })
await mgmt.cron.create(ref, { name: 'nightly', schedule: '0 3 * * *', command: 'select app.cleanup()' })
await mgmt.queues.send(ref, 'emails', { message: { to: '[email protected]' } })
// Post an incident on the status page
await mgmt.statusPage.incidents.create(ref, { title: 'Sign-in errors', impact: 'major', status: 'investigating', message: 'Some sign-ins fail.' })
// Link a Cloudflare Worker: the API URL and keys are written as its secrets
await mgmt.integrations.cloudflare.link(ref, { token: process.env.CF_TOKEN, account_id: 'abc…', kind: 'worker', name: 'api-worker' })mgmt.request(method, path, options) calls any route that has no method yet (paths relative to /platform/v1), and mgmt.openapi() returns the OpenAPI document.
#Agent client
An agent key (sdb_agt_…) belongs to one project. Its SQL runs under the key's policy: the query firewall, approvals, the query log and undo.
import { createAgentClient } from 'stitchdb-js/management'
const agent = createAgentClient({ agentKey: process.env.STITCHDB_AGENT_KEY })
const { data: me } = await agent.whoami() // name, project, policy
const { data, error } = await agent.sql("update orders set status = 'shipped' where id = 42", { session: 'ticket-881' })
if (data?.status === 'pending_approval') {
// A person approves or rejects it in the dashboard; check later with the id
await agent.approval(data.approval_id)
}
await agent.revert('ticket-881', { dry_run: false }) // undo everything the session changed| Method | Does |
|---|---|
whoami() | The key's name, project and policy |
sql(query, { session? }) | Run SQL; statements with the same session can be undone together. A statement that needs approval resolves with status: "pending_approval" and an approval id. |
dbCredentials({ ttl_minutes? }), listDbCredentials() | A temporary Postgres login with the key's rights, and the current ones |
approval(id) | The state of an approval request |
session(id), revert(id, { dry_run? }) | A session's timeline, and undo (a dry run unless dry_run: false) |
See the Agent API for the routes behind these methods.