shovelbasedocs

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.

Why use it

This is the control plane, and it's a different axis from the project API your app talks to. /rest/v1 and friends read and write the data inside a project; the management API creates and configures the projects themselves. Keep the two straight and the security model falls out naturally: app code holds an anon 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 real Postgres and real RLS policies rather than mocks, and delete it when the branch merges.
Infrastructure as code
Keep flags, 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 ~/.shovelbase/config.json. Treat it like a root credential: it can read every key and delete every project in the organization.

terminal
TOKEN=$(curl -s -X POST https://shovelbase.com/api/auth/cli-token \
-H 'Content-Type: application/json' \
-d '{"email": "admin@…", "password": "…"}' | jq -r .token)
curl -s https://shovelbase.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:

provision.sh
set -euo pipefail
API=https://shovelbase.com/api
AUTH="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/null
do 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>.shovelbase.com.
ANON=$(curl -s "$API/projects/$REF" -H "$AUTH" | jq -r .anon_key)
echo "SHOVELBASE_URL=https://$REF.shovelbase.com"
echo "SHOVELBASE_ANON_KEY=$ANON"

Projects & schema

EndpointMethodsPurpose
/api/projectsGET, POSTList / create projects
/api/projects/<ref>GET, DELETEProject detail (incl. keys) / delete
/api/projects/<ref>/migrationsGET, POSTApplied migrations / apply one
/api/projects/<ref>/sqlPOSTRun arbitrary SQL as the project owner
/api/projects/<ref>/tablesGETSchema catalog — tables, columns, definitions
/api/projects/<ref>/tables/exportGETDownload a table as CSV
/api/projects/<ref>/tables/importPOSTImport CSV rows (multipart)
/api/projects/<ref>/backupsGET, POSTList backups + current job / back up now
/api/projects/<ref>/backups/restorePOSTRestore from a given backup

Functions, schedules & secrets

EndpointMethodsPurpose
/api/projects/<ref>/functionsGET, POSTList / deploy edge functions
/api/projects/<ref>/functions/<name>GET, PUT, DELETERead source / redeploy (merges files, preserves verify_jwt + MCP flags) / delete
/api/projects/<ref>/schedulesGET, POST, PATCH, DELETECron schedules for functions — list / create / update / delete
/api/projects/<ref>/schedules/runPOSTRun a schedule immediately
/api/projects/<ref>/secretsGET, POST, DELETEFunction secrets (applied live)

Auth

EndpointMethodsPurpose
/api/projects/<ref>/auth/usersGET, PATCH, DELETEList users / ban-unban / delete — note there is no POST; users are invited, not created
/api/projects/<ref>/auth/users/sendPOSTSend an auth email: { type: "invite" | "recovery" | "confirmation", email } — "invite" creates the user
/api/projects/<ref>/auth/configGET, PUTSite URL + additional redirect URLs
/api/projects/<ref>/auth/providersPOST, DELETEEnable / disable Google and Apple sign-in
/api/projects/<ref>/auth/providers/apple-secretPOSTSign an Apple client secret from the stored .p8 — returns it, saves nothing
/api/projects/<ref>/auth/emailsGET, PUTEmail template subjects and HTML bodies
/api/projects/<ref>/auth/confirm-configGET, PUTRequire-confirmation toggle
/api/projects/<ref>/auth/reset-pageGET, PUTHosted reset page HTML (and confirm-page for the confirmation equivalent)

Storage, queues & flags

EndpointMethodsPurpose
/api/projects/<ref>/storageGET, POST, DELETEBrowse / upload / delete objects
/api/projects/<ref>/storage/bucketsGET, POST, PATCH, DELETEList / create / toggle public-private / delete buckets
/api/projects/<ref>/storage/signGETMint a signed URL for a private object
/api/projects/<ref>/queuesGET, POST, DELETEList (with message counts) / create / delete SQS queues
/api/projects/<ref>/queues/<name>/messagesPOSTEnqueue a message
/api/projects/<ref>/queues/triggersGET, POST, PATCH, DELETEQueue triggers — list / create / update (functions, enabled) / delete
/api/projects/<ref>/queues/webhooksGET, POST, DELETEQueue webhooks (public inbound URL → queue) — list / create / delete
/api/projects/<ref>/flagsGET, POST, PATCH, DELETEList / create / toggle / set rollout percentage / delete feature flags

Web & domains

EndpointMethodsPurpose
/api/projects/<ref>/sitesGETList published static sites
/api/projects/<ref>/sites/<site>GET, POST, DELETESite manifest (paths + ETags) / upload a file / prune paths or delete the site
/api/projects/<ref>/sites/<site>/invalidatePOSTInvalidate attached CloudFront distributions after a publish
/api/projects/<ref>/domainsGET, POST, DELETEList / connect / disconnect a domain
/api/projects/<ref>/domains/<domain>/recordsGET, POST, DELETEList / add / delete DNS records
/api/projects/<ref>/distributionsGET, POST, DELETEAttach / detach a custom domain to a site or the project API

Monitoring

EndpointMethodsPurpose
/api/projects/<ref>/servicesGET, POSTService health / restart containers
/api/projects/<ref>/services/logs?service=…GETService logs (rest, auth, storage, functions, queues, sites, postgres)
/api/projects/<ref>/observability[?section=…]GETResources overview, or per-product detail (database, auth, storage, functions, queues, sites)
/api/projects/<ref>/signals?range=…GETSignals overview aggregates
/api/projects/<ref>/signals/eventsGETRaw event feed, newest first, paginated
/api/projects/<ref>/signals/usersGETUser profiles derived from events
/api/projects/<ref>/signals/queryPOSTRun a chart config and get its data (no need to save the chart first)
/api/projects/<ref>/signals/metaGETEvent names / property keys / top property values in a range
/api/projects/<ref>/signals/chartsGET, POSTSaved charts (PATCH, DELETE on /charts/<id>)

Sources & organization

Sources mirror the project endpoints for the surfaces they have — database, functions, schedules, secrets, logs — under /api/sources/<slug> instead of /api/projects/<ref>.

EndpointMethodsPurpose
/api/sourcesGET, POSTList / create sources (blank — name only)
/api/sources/<slug>GET, DELETESource detail / delete
/api/sources/<slug>/functionsGET, POSTList / deploy source functions (GET, PUT, DELETE on /functions/<name>)
/api/sources/<slug>/schedulesGET, POST, PATCH, DELETESource schedules (POST /schedules/run to fire one now)
/api/sources/<slug>/secretsGET, POST, DELETESource function secrets
/api/sources/<slug>/sqlPOSTRun SQL against the source database
/api/sources/<slug>/tablesGETSource schema catalog (+ /export, /import)
/api/sources/<slug>/servicesGET, POSTSource service health / restart (+ /services/logs)
/api/orgGET, PATCHOrganization detail / rename
/api/org/membersGET, POST, DELETEAdmin 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.