Errors, Limits, and Integrator Recommendations

Stable

The Control Plane error format, trial/PAYG, the active L1/L2 autoscale contract, and practical integration rules.

Updated: March 21, 2026

The Control Plane tries to return predictable, automation-friendly responses. For an integrator, this means the API can be safely used in CI/CD, provisioning scripts, and internal services — if you follow several rules.

Error format

Public user-facing errors are returned in JSON form:

{
  "error": "...",
  "message": "...",
  "details": { ... }
}

What the status codes usually mean:

  • 400 BadRequest — invalid payload, a required field is missing, or the name failed validation;
  • 401 Unauthorized — the token is missing, invalid, or expired;
  • 403 Forbidden — the token scope or permissions do not allow the operation;
  • 404 NotFound — the resource was not found or is hidden by access filters;
  • 409 Conflict / LimitExceeded — a state conflict, the resource already exists, or a hard limit has been reached;
  • 5xx — an internal platform error or a failure while interacting with internal services.

It is also useful to remember OperationDisabled: this is how the Control Plane responds to manual start/stop/scale and to the start_immediately / initial_scale fields, which are disabled in the current user scenario.

Trial and PAYG

For the trial logic, the hard limits are:

  • up to 1 tenant;
  • up to 2 databases;
  • up to 10 CU·h of compute;
  • up to 5 GiB of egress.

On the product side, the plan id standard_payg already exists, and the size model is ready for the full L1–L5 line.

What matters about the size contract

For an integrator, it is important to distinguish honestly between:

  • the user-facing size model L1–L5;
  • the currently active autoscale runtime contract L1/L2.

This means:

  • the application and the UI can already work with the full size line;
  • in the current live writer handoff, the critical supported range is L1 <-> L2.

What matters about the describe API

For a database, it is now useful to read not only state, but also the new fields:

  • current_profile
  • target_profile
  • candidate_profile
  • scale_state
  • freeze_new_checkouts
  • scale_failure_reason

This matters for integration because:

  • you can distinguish a normal cold start from a profile handoff;
  • you can see a controlled freeze/drain phase;
  • you can diagnose a failed cutover correctly.

Rules for integrators

  1. Treat create and delete as asynchronous operations.
    Immediately after the request, the resource may still not be in a final state.

  2. Do not build automation around manual lifecycle.
    In the current managed scenario, the correct path is auto-start on connect and auto-stop on idle.

  3. Save tenant credentials and dsn_template immediately.
    They are the basic connection data for any application.

  4. Account for token scope and permissions.
    Most unexpected 403 responses are caused by exactly this.

  5. Do not treat worker_id, candidate_worker_id, and backend_addr as business identifiers.
    These are runtime fields, not a stable product contract.

  6. Expect the first connection to a stopped database to take longer than the warm path.
    This is the normal cost of the serverless model.

  7. If you use describe/list for operational logic, account for scale_state.
    Otherwise, automation may mistakenly treat a controlled handoff as an outage.

The conclusion is simple: the best integration scenario in SPG99 is to work with the entities account / tenant / database and let the platform perform orchestration automatically, including the new writer autoscaler.