Workspaces

Read a workspace's plan, seats, and usage overview

Changed on

Bearer atc:read (or cookie session) — owner/admin only. Same scope floor as the sibling workspace-inventory reads (/coverage, /open-bugs, /recent-projects, /active-runs); cookie sessions hold the full capability set, so this constrains PATs only. bunkai_workspace_billing_overview is SECURITY INVOKER with no caller-supplied actor parameter; its own step-0 gate (bunkai_is_workspace_admin) restricts the read, and this route calls it through the caller's own RLS-scoped client, never a service-role client. A non-admin caller, an unknown workspace id, and a workspace the caller cannot see all collapse into the SAME 404 not_found — never 403, so the response never discloses more than the workspace's existence. The tier ladder (limits, price, display name) is NOT part of this payload; look it up client-side in lib/billing/plan-tiers.ts keyed by the returned plan.

get/api/v1/workspaces/{id}/billing

Request

  • Base URL: http://localhost:3000
  • URL: http://localhost:3000/api/v1/workspaces/{id}/billing
  • Auth: one of:
    • API key in cookie sb-fmbpikzpkafptqximhxn-auth-token
    • HTTP bearer

Path parameters

idstring uuid required

Response

The workspace's billing overview.

plan'community' | 'cloud' | 'enterprise' required

The workspace's workspaces.plan literal. Look up the tier ladder (display name, seat/project/retention limits, price) for this key in lib/billing/plan-tiers.ts — this endpoint does not repeat it.

purchased_seatsinteger nullable required

BK-230 — the Cloud workspace's real purchased seat count (set at checkout completion). null for Community/Enterprise, or a Cloud workspace predating this column — lib/billing/plan-tiers.ts's effectiveSeatLimit() falls back to the tier's flat seatLimit in that case. This is the workspace's ACTUAL seat cap; PLAN_TIERS.cloud.seatLimit (25) is only the plan's maximum purchasable quantity.

active_seatsinteger required

Workspace members with status = 'active' only. Pending invitations and suspended members never count toward this figure.

project_countinteger required

Every project in the workspace. projects carries no soft-delete column, so this is an exact, unfiltered count.

oldest_run_age_daysinteger nullable required

Age in days of the workspace's oldest run (now() - min(runs.created_at)), or null when the workspace has no runs. This reports how much of the plan's retention WINDOW is in use — nothing in this product prunes runs, so this figure is never a countdown to deletion.

Changes

    • warning

      added the new test_outside_plan_project enum value to the / response property for the response status

    • warning

      added the new test_outside_plan_project enum value to the / response property for the response status

    • warning

      added the new test_outside_plan_project enum value to the / response property for the response status

    • warning

      added the new test_outside_plan_project enum value to the / response property for the response status

    • warning

      added the new test_outside_plan_project enum value to the / response property for the response status

    • info

      added the required property to the response with the status