Management API
Everything the CLI and portal UI do goes through the portal's own HTTP API — there is no private back channel. Anything you can click, you can script.
This page is for your own tooling. If the caller is an AI client, use the MCP endpoint instead: it's these same operations exposed as MCP tools — with argument schemas, a project-scoped token you can rotate, and the docs served alongside them — rather than endpoints a model has to guess its way around.
This is the control plane, and it's a different axis from the project API your app talks to. /api/auth, /api/functions/v1, /api/storage/v1 and friends are what an app calls at runtime — none of them reach a table directly, a function has to sit in front; the management API instead creates and configures the projects themselves. Keep the two straight and the security model falls out naturally: app code holds a public project key and can never provision infrastructure, while a management token can provision anything and therefore never belongs in an app.
Reach for it whenever a human clicking the portal is the bottleneck — when project setup has to be reproducible, or when the thing that needs to act isn't a person.
- Provision a project per customer
- A B2B product that gives every tenant an isolated database: create the project, apply migrations, and read back the keys, all from your signup flow, instead of clicking through the portal for each new account.
- Ephemeral environments in CI
- Spin up a throwaway project for a pull request, run the test suite against a real database and real functions rather than mocks, and delete it when the branch merges. (For most CI,
snoozestack devagainst the checkout is even simpler — no hosted project needed at all.) - Infrastructure as code
- Keep secrets, scheduled functions, and DNS records in a script under version control, so a rebuilt project is identical to the one it replaced.
- Internal admin tooling
- Build your own support console — look up a user, ban an account, re-run a schedule — without giving support staff portal logins.
Authenticating#
Exchange your admin email and password for a bearer token at /api/auth/cli-token — the same token the CLI stores in ~/.snoozestack/config.json. Treat it like a root credential: it can read every key and delete every project in the organization.
TOKEN=$(curl -s -X POST https://snoozestack.com/api/auth/cli-token \ -H 'Content-Type: application/json' \ -d '{"email": "admin@…", "password": "…"}' | jq -r .token) curl -s https://snoozestack.com/api/projects -H "Authorization: Bearer $TOKEN"A worked example — provision a project, wait for it, apply a schema, and print the keys an app would need:
set -euo pipefailAPI=https://snoozestack.com/apiAUTH="Authorization: Bearer $TOKEN" # 1. Create the project — the response is the project row, incl. its keys.REF=$(curl -s -X POST "$API/projects" \ -H "$AUTH" -H 'Content-Type: application/json' \ -d '{"name": "tenant-acme"}' | jq -r .slug) # 2. Wait for the service containers to come up (the endpoint returns an# array, one entry per service, each with a "healthy" boolean).until curl -sf "$API/projects/$REF/services" -H "$AUTH" \ | jq -e 'length > 0 and all(.healthy)' >/dev/nulldo sleep 3; done # 3. Apply the schema. "version" is the ordering key migrations are recorded# under — the CLI uses a timestamp, so anything sortable works.curl -s -X POST "$API/projects/$REF/migrations" \ -H "$AUTH" -H 'Content-Type: application/json' \ -d '{"version": "20260720120000", "name": "init", "sql": "create table public.todos (id bigint generated always as identity primary key);"}' # 4. Hand the app its credentials. There is no "url" field — a project is# always served at https://<slug>.snoozestack.com.ANON=$(curl -s "$API/projects/$REF" -H "$AUTH" | jq -r .anon_key)echo "SNOOZESTACK_URL=https://$REF.snoozestack.com/api"echo "SNOOZESTACK_ANON_KEY=$ANON"Projects & schema#
| Endpoint | Methods | Purpose |
|---|---|---|
/api/projects | GET, POST | List / create projects |
/api/projects/<ref> | GET, DELETE | Project detail (incl. keys) / delete |
/api/projects/<ref>/migrations | GET, POST | Applied migrations / apply one |
/api/projects/<ref>/sql | POST | Run arbitrary SQL as the project owner |
/api/projects/<ref>/tables | GET | Schema catalog — tables, columns, definitions |
/api/projects/<ref>/tables/export | GET | Download a table as CSV |
/api/projects/<ref>/tables/import | POST | Import CSV rows (multipart) |
/api/projects/<ref>/backups | GET, POST | List backups + current job / back up now |
/api/projects/<ref>/backups/restore | POST | Restore from a given backup |
Functions, schedules & secrets#
| Endpoint | Methods | Purpose |
|---|---|---|
/api/projects/<ref>/functions | GET, POST | List / deploy edge functions |
/api/projects/<ref>/functions/<name> | GET, PUT, DELETE | Read source / redeploy (merges files, preserves auth + MCP flags) / delete |
/api/projects/<ref>/schedules | GET, POST, PATCH, DELETE | Cron schedules for functions — list / create / update / delete |
/api/projects/<ref>/schedules/run | POST | Run a schedule immediately |
/api/projects/<ref>/secrets | GET, POST, DELETE | Function secrets (applied live) |
Auth#
| Endpoint | Methods | Purpose |
|---|---|---|
/api/projects/<ref>/auth/users | GET, PATCH, DELETE | List users / ban-unban / delete — note there is no POST; users are invited, not created |
/api/projects/<ref>/auth/users/send | POST | Send an auth email: { type: "invite" | "recovery" | "confirmation", email } — "invite" creates the user |
/api/projects/<ref>/auth/config | GET, PUT | Site URL + additional redirect URLs |
/api/projects/<ref>/auth/providers | POST, DELETE | Enable / disable Google and Apple sign-in |
/api/projects/<ref>/auth/providers/apple-secret | POST | Sign an Apple client secret from the stored .p8 — returns it, saves nothing |
/api/projects/<ref>/auth/emails | GET, PUT | Email template subjects and HTML bodies |
/api/projects/<ref>/auth/reset-config | GET, PUT | Where the hosted password page hands off to instead of rendering its form |
/api/projects/<ref>/auth/reset-page | GET, PUT | Hosted password page HTML |
Storage & queues#
| Endpoint | Methods | Purpose |
|---|---|---|
/api/projects/<ref>/storage | GET, POST, DELETE | Browse / upload / delete objects |
/api/projects/<ref>/storage/buckets | GET, POST, PATCH, DELETE | List / create / toggle public-private / delete buckets |
/api/projects/<ref>/storage/sign | GET | Mint a signed URL for a private object |
/api/projects/<ref>/queues | GET, POST, DELETE | List (with message counts) / create / delete queues |
/api/projects/<ref>/queues/<name>/messages | POST | Enqueue a message |
/api/projects/<ref>/queues/triggers | GET, POST, PATCH, DELETE | Queue triggers — list / create / update (functions, enabled) / delete |
/api/projects/<ref>/queues/webhooks | GET, POST, DELETE | Queue webhooks (public inbound URL → queue) — list / create / delete |
Web & domains#
| Endpoint | Methods | Purpose |
|---|---|---|
/api/projects/<ref>/sites | GET | List published static sites |
/api/projects/<ref>/sites/<site> | GET, POST, DELETE | Site manifest (paths + ETags) / upload a file / prune paths or delete the site |
/api/projects/<ref>/sites/<site>/publish | POST | Turn staged uploads into a new, previewable version — not live until promoted |
/api/projects/<ref>/sites/<site>/promote | POST | Make a version live and flush the edge cache — also how to roll back |
/api/projects/<ref>/sites/<site>/versions | GET | Version history for a site |
/api/projects/<ref>/domains | GET, POST, DELETE | List / connect / disconnect a domain |
/api/projects/<ref>/domains/<domain>/records | GET, POST, DELETE | List / add / delete DNS records |
/api/projects/<ref>/distributions | GET, POST, DELETE | Attach / detach a custom domain to a site or the project API |
Monitoring#
| Endpoint | Methods | Purpose |
|---|---|---|
/api/projects/<ref>/services | GET, POST | Service health / restart containers |
/api/projects/<ref>/services/logs?service=… | GET | Service logs (auth, storage, functions, queues, sites, postgres) |
/api/projects/<ref>/observability[?section=…] | GET | Resources overview, or per-product detail (database, auth, storage, functions, queues, sites) |
/api/projects/<ref>/signals?range=… | GET | Signals overview aggregates |
/api/projects/<ref>/signals/events | GET | Raw event feed, newest first, paginated |
/api/projects/<ref>/signals/users | GET | User profiles derived from events |
/api/projects/<ref>/signals/query | POST | Run a chart config and get its data (no need to save the chart first) |
/api/projects/<ref>/signals/meta | GET | Event names / property keys / top property values in a range |
/api/projects/<ref>/signals/charts | GET, POST | Saved charts (PATCH, DELETE on /charts/<id>) |
Organization#
| Endpoint | Methods | Purpose |
|---|---|---|
/api/org | GET, PATCH | Organization detail / rename |
/api/org/members | GET, POST, DELETE | Admin accounts — list / invite / remove |
Responses are JSON; failures carry a non-2xx status and an { "error": "…" } body. See the CLI reference for the commands that wrap the most common of these calls.