API v2 and Real User Scenarios

Stable

Which public Control Plane routes matter to the user, which new runtime fields now appear on a database, and how to read the autoscaler through the API.

Updated: March 21, 2026

The public user interface of the Control Plane is API v2. It is exactly what Console, CLI, and external integrations use.

Basic rules

  • the base URL usually looks like this: https://<cp-host>/v2
  • authorization is sent as Authorization: Bearer <API_KEY>
  • PostgreSQL connections from applications go not to the Control Plane, but to Gateway: postgres://...@<gateway-host>:5432/...

What the user usually does

1. Create a tenant

POST /v2/tenants

The response usually includes:

  • tenant;
  • pg_user;
  • pg_password;
  • dsn_template.

2. Create a database inside a tenant

POST /v2/tenants/:tenant/dbs

At minimum, you only need to send:

{
  "name": "app",
  "size": "L1"
}

Important:

  • start_immediately is disabled;
  • initial_scale is not used in the normal managed scenario;
  • the database starts automatically on the first connection through Gateway.

3. Retrieve tenant credentials again

GET /v2/tenants/:tenant/credentials

4. Read resource state

  • GET /v2/tenants
  • GET /v2/tenants/:tenant
  • GET /v2/tenants/:tenant/dbs
  • GET /v2/tenants/:tenant/dbs/:db
  • GET /v2/dbs/:id

Describe/list requests are now especially useful because they expose not only the database lifecycle, but also the autoscaler state.

5. Delete resources

  • DELETE /v2/tenants/:tenant/dbs/:db
  • DELETE /v2/tenants/:tenant?cascade=true

Deletion is asynchronous, so after the request the resource may remain in deleting for some time.

6. Get catalog events

GET /v2/events

This is a Server-Sent Events stream that Console uses for near real-time state updates.

What is now visible in the database response

In addition to the classic state, size, current_scale, and target_scale fields, a database now has useful autoscaler runtime fields:

  • current_profile
  • target_profile
  • candidate_profile
  • candidate_worker_id
  • candidate_writer_term
  • scale_state
  • freeze_new_checkouts
  • lease_control_epoch
  • autoscale_cooldown_until
  • scale_phase_started_at
  • scale_phase_deadline_at
  • scale_failure_reason

In practice, this lets you see through the API:

  • whether a profile handoff is in progress;
  • whether the candidate writer is prepared;
  • whether new checkouts are frozen;
  • whether the transition failed and why.

How to read these fields

  • current_scale / target_scale — whether the writer is off or on.
  • current_profile / target_profile — which profile the writer currently uses and which profile it is moving to.
  • scale_state — the current handoff stage.
  • freeze_new_checkouts=true — a normal controlled cutover phase, not an outage.
  • scale_failure_reason — the main quick diagnosis when the autoscaler falls into FAILED.

Accounts and tokens

API v2 also includes routes for accounts and keys:

  • POST /v2/accounts
  • POST /v2/accounts/:account/api-keys
  • GET /v2/account/profile
  • POST /v2/account/contact
  • GET /v2/api-keys/me
  • POST /v2/api-keys/rotate
  • POST /v2/api-keys/revoke
  • GET /v2/billing/summary
  • POST /v2/account/delete

What is returned for connection

When creating a tenant or reading credentials, the user receives three main fields:

  • pg_user
  • pg_password
  • dsn_template

The typical template looks like this:

postgres://<pg_user>:<pg_password>@<gateway-host>:5432/<db-name>?sslmode=require

A good working scenario

The most practical user path for automation looks like this:

create tenant -> save pg_user/pg_password/dsn_template -> create db -> connect the application through Gateway -> read state and scale_state through describe