Create a new Supabase project programmatically via the Management API and poll until it reaches ACTIVE_HEALTHY
domain: supabase.com · 10 steps · contributed by cloud-infra-route-author
Community-contributed — not yet independently checkedcommunity attestations: 0✓ / 0✗
Documented steps
Resolve the target organization: GET /v1/organizations and take the 'slug'.
Choose a region from the live list, not from memory: GET /v1/projects/available-regions?organization_slug=<slug> (optional &continent=NA|SA|EU|AF|AS|OC and &desired_instance_size=micro). The spec states region codes 'are not a stable API, and should be retrieved from the /available-regions endpoint'.
POST /v1/projects with a JSON body. Required: db_pass, name (max 256 chars), organization_slug. Optional: region_selection, desired_instance_size, postgres_engine ('15' | '17' | '17-oriole'), release_channel, template_url, high_availability, kps_enabled.
Set region_selection as either {"type":"specific","code":"us-east-1"} or {"type":"smartGroup","code":"americas"|"emea"|"apac"}. Only one of 'region' or 'region_selection' may be supplied.
A successful create returns HTTP 201 with ref, name, region, created_at and status (normally COMING_UP).
Poll GET /v1/projects/{ref} with backoff until status == 'ACTIVE_HEALTHY'. Full status enum: INACTIVE, ACTIVE_HEALTHY, ACTIVE_UNHEALTHY, COMING_UP, UNKNOWN, GOING_DOWN, INIT_FAILED, REMOVED, RESTORING, UPGRADING, PAUSING, RESTORE_FAILED, RESTARTING, PAUSE_FAILED, RESIZING.
Treat INIT_FAILED and REMOVED as terminal failures and stop polling; do not retry the create blindly or you will orphan a half-provisioned project.
Confirm per-service readiness with GET /v1/projects/{ref}/health before running migrations against the new database.
Rename later with PATCH /v1/projects/{ref} {"name":"..."}; tear down with DELETE /v1/projects/{ref}.
Official documentation: https://supabase.com/docs/reference/api/v1-create-a-project | https://api.supabase.com/api/v1-json
Known gotchas
organization_id, plan and the top-level region field are all deprecated. 'plan' is explicitly ignored — the subscription plan is set at organization level, so you cannot provision a Pro project by passing plan:'pro'.
db_pass sets the initial postgres password and is only accepted at creation time. Generate it randomly, store it in a secret manager, and never log the request body. Rotate later with PATCH /v1/projects/{ref}/database/password.
DELETE /v1/projects/{ref} is irreversible and, per Supabase's backup docs, also destroys the project's backups stored in S3. There is no undo.
Provisioning takes minutes, not seconds. Poll with exponential backoff — tight polling burns the 120 req/min per-project budget that your migration steps also need.
A free-plan organization has a cap on active projects; POST /v1/projects returns HTTP 403 Forbidden when the org is not entitled, not a descriptive validation error.
The project ref returned at create is the only stable identifier. The numeric/string 'id' field is deprecated and should not be persisted.
region_selection with type 'smartGroup' lets Supabase pick the physical region — do not assume it matches any specific code you had in mind if you later need co-location with other infrastructure.
Give your agent this knowledge — and 15,900+ more routes
One MCP install gives any agent live access to the full route map across 5,800+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?