Skip to content

Your First Project

A project is an isolated tenant — its own database, bucket, JWT secret, and keys. This page covers provisioning a project, what you get back, and the full lifecycle. You can do all of this from the console, the CLI, or the Management API; each is shown.

Create a project

Console

Open http://localhost:39004ProjectsNew Project. Enter a name; the slug is derived automatically.

CLI

Terminal window
anvilbase projects create "My App"
# or with an explicit slug
anvilbase projects create "My App" --slug my-app

Management API

Terminal window
curl -X POST http://localhost:39001/api/v1/projects \
-H "Authorization: Bearer $ANVILBASE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"My App","description":"demo"}'

If slug is omitted it’s derived from name (lowercased, non-alphanumerics → hyphens, padded to ≥3 chars). A provided slug must be lowercase alphanumeric + hyphens, 3–50 chars, no leading/trailing hyphen.

What you get back

The create response is a ProjectCreatedResponse — the only time the jwt_secret and service_role_key are ever returned:

{
"id": "3f2b…",
"name": "My App",
"slug": "my-app",
"status": "active",
"db_name": "platform_3f2b…",
"db_host": "postgres",
"db_port": 5432,
"storage_bucket": "bucket-3f2b…",
"anon_key": "anvilbase_anon_my-app_…",
"service_role_key": "anvilbase_service_role_my-app_…",
"jwt_secret": "…96 hex chars…",
"max_db_size_mb": null,
"max_storage_size_mb": null,
"max_edge_function_count": null,
"created_at": "2026-06-04T12:00:00Z"
}

Store service_role_key and jwt_secret now. They are never returned again. The anon_key can always be re-read; the service_role_key can be revealed again from the console/CLI (an audit-logged action) but never re-fetched from the create payload.

Your project’s endpoints

Every data-plane service is addressed by the project UUID:

ServiceEndpoint
REST (data)/v1/rest/<project_id>/...
Auth/v1/auth/<project_id>/...
Storage/v1/storage/<project_id>/...
Edge Functions/v1/functions/<project_id>/...
Realtime (WS)/v1/realtime/<project_id>/socket/websocket
eIDAS (optional)/v1/eidas/<project_id>/...

For the SDK, the base URL is http://<host>/v1/<project_id> with the anon_key.

anvilbase projects info <id> prints these for you.

The two keys (recap)

KeyUse it inBypasses RLS?
anon_keyclient code (browser, mobile)no
service_role_keyserver code onlyyes

Details and the security model: API Keys & Scopes.

Re-reading keys later

Terminal window
# Anon plaintext + service_role masked (safe to screen-share)
anvilbase projects keys <project_id>
# Reveal service_role plaintext (audit-logged)
anvilbase projects keys <project_id> --show-service-role

In the console: open the project → API tab.

Quotas

A project can carry optional resource limits, enforced server-side:

FieldMeaning
max_db_size_mbdatabase size cap
max_storage_size_mbobject-storage cap (writes return 429 when exceeded)
max_edge_function_countnumber of deployed functions

Set them at create time or update later:

Terminal window
curl -X PATCH http://localhost:39001/api/v1/projects/$PROJECT_ID \
-H "Authorization: Bearer $ANVILBASE_TOKEN" -H "Content-Type: application/json" \
-d '{"max_db_size_mb":1000,"max_storage_size_mb":5000,"max_edge_function_count":50}'

null means unlimited (operator’s disk is the only limit).

Lifecycle

create
draft ─────────► active ──┐
│ ▲ │ suspend / resume
│ └─────┘
│ delete (soft)
deleted ──► (DB + bucket deprovisioned in background)
Terminal window
# List (optionally filter by status)
anvilbase projects list
curl "http://localhost:39001/api/v1/projects?status=active&limit=50" -H "Authorization: Bearer $ANVILBASE_TOKEN"
# Inspect
anvilbase projects info <project_id>
# Update name / description / settings / quotas
curl -X PATCH .../api/v1/projects/<id> -d '{"description":"prod app"}' ...
# Delete (soft-delete + deprovision). Returns 204.
anvilbase projects delete <project_id>

Soft-deleted projects are always excluded from listings. The database and bucket are torn down asynchronously.

Rotating project secrets

You can rotate a project’s JWT secret or its API keys at any time:

Terminal window
# Invalidates ALL existing JWTs immediately, returns a new secret
anvilbase secrets rotate jwt --project <project_id>
# Issues fresh anon + service_role keys; old keys stop working immediately
anvilbase secrets rotate api-keys --project <project_id>

There is no grace window on API-key rotation — coordinate with consumers first. See API Keys & Scopes → Rotation.

Next