billing

Retrieve one closed billing period statement

Changed on

GET /billing/usage/periods/ and GET /billing/usage/periods/{id}/ -- the durable statements CycleCloseService writes at cycle close (see BillingPeriodSummary's docstring). List and detail are bundled deliberately: they share a queryset, a permission, and a serializer tree, so shipping them together avoided a second PR that would only add fifty lines.

Scoped to the caller's resolved pool exactly like BillingUsageViewSet: resolve_billing_root then get_pooled_scope_ids, both resolved once in get_queryset(). A pk outside that pool is filtered out of the queryset before get_object() ever runs, so it 404s -- never 403 -- and this endpoint never confirms the existence of another tenant's statement.

IsAuthenticated only, matching GET /billing/usage/'s read-never-blocks rule: a closed statement is exactly the kind of read an scope needs in order to resolve billing, including while RESTRICTED.

History is forward-only: an scope with no closed periods yet gets 200 with an empty list, never a 404 -- there is nothing wrong with that scope, cycle close simply has not run for it yet. A caller with no active scope (request.scope is None) is a different state -- there is no pool to resolve a billing root against at all -- and gets 403, matching GET /billing/usage/'s _require_scope rule rather than the empty-list state above.

get/billing/usage/periods/{id}{format}

Request

  • The document declares no server URL.
  • Auth: one of:
    • HTTP bearer
    • API key in cookie sessionid

Path parameters

format'.json' required
idstring required

Headers

X-Organization-Idstring

Selects the active organization for this request. Optional for callers that belong to exactly one active organization — the single membership is resolved implicitly. Required when the caller has two or more active memberships; omitting it in that case returns 400. If the header names an organization the caller is not an active member of, the server returns 403.

Response

idinteger required

pk of this statement.

billing_period_startstring date-time required

Inclusive start of the closed period.

billing_period_endstring date-time required

Exclusive end of the closed period.

plan_slugstring required

The billing plan in force for this period, snapshotted at close time -- a later plan change does not rewrite this.

plan_namestring required

Display name of the plan in force for this period.

billing_intervalstring required

The subscription's billing interval for this period.

currencystring required

The plan's currency for this period, e.g. "USD".

overage_totalstring decimal required

Overage money charged for this period.

chargedboolean required

Whether an overage charge was actually made for this period.

payment_idinteger nullable required

pk of the Payment that settled this period's overage. null when charged is false.

closed_atstring date-time required

When CycleCloseService wrote this statement.

Changes

    • ▲

      removed the required property // from the response with the status

    • ○

      added the required property // to the response with the status

    • ○

      endpoint added