---
title: "Read Billing Summary"
method: GET
path: "/api/v1/billing/summary"
tags: ["billing"]
---

# Read Billing Summary

`GET /api/v1/billing/summary`

Read the workspace's own funding.

Member-readable: a member who cannot see the balance cannot tell a refused
turn from a broken one.

## Response `200`

Successful Response

- BillingSummaryResponse — What a workspace may know about its own funding. ``balance`` is the same customer-safe projection the workspace response serves, carried whole rather than restated: a flattened copy would name one number twice and let the two names drift, and the client already reads this shape. The fields beside it are account facts no customer-safe projection holds. ``period_end`` is when the current period ends; ``resets_on`` repeats it only when that end grants another period, so the page never calls the end of a cancelling, unpaid or ended plan a reset. ``cancellable`` answers whether Stripe still holds a subscription to cancel, so the page never offers a cancellation the portal would reject; ``subscribable`` answers whether checkout would take a new subscription, so the page offers one exactly where it would. ``plan_charge`` is the recurring charge the workspace still faces, absent where no single figure states it or the plan has ended.
  - `balance` PaidBalanceCustomerProjection, required — Customer-safe view of a subscribed workspace's spendable balance. Plan usage is a share, never dollars. The only dollar figure is ``paid_overage_usd``: overage the customer explicitly bought, which only a confirmed payment can add. It is absent, not zero, when they bought none, so an overrun past the plan never reads as a dollar debt. ``includes_given_usage`` says usage staff gave is part of the share, and nothing more. It carries no amount on purpose: a top-up moves the share, and an amount beside it would price in dollars what the customer never bought. ``status`` rides along because an admitted turn on a past-due account is otherwise indistinguishable from a healthy one — the refusal payload can only carry the warning once work is already being refused, which is after the point of warning anyone. ``spendable_now`` states whether the balance can be spent, rather than leaving a client to re-derive it from the status. A balance survives the statuses that refuse every turn, so a client deciding for itself which those are holds a second copy of ``keeps_paid_access`` that nothing keeps in step.
    - `status` 'pending' | 'active' | 'past_due' | 'unpaid' | 'cancelled', required — Subscription state as MAIA understands it, not as Stripe reports it. ``PAST_DUE`` is the retry window: full access with a visible warning. ``UNPAID`` is that window exhausted — paid work refuses until payment succeeds, but the subscription has not ended, so purchased usage is kept. ``CANCELLED`` is paid access ended. Purchased usage is kept there too — no status takes it — but only a status that keeps paid access may spend it.
    - `plan_usage` PlanUsageShare, required — What is left of a plan's usage, as a share of it and never as dollars. Plan usage is disclosed the same way whoever paid for it, including any allowance MAIA grants on top of a subscription: the customer did not buy those dollars one by one, so a dollar figure would quote them a price they never agreed to. Shaped as the free allowance's measured states so one meter renders both.
      - `status` 'available' | 'near_limit' | 'exhausted', required
      - `remaining_percent` integer, required
      - `display_remaining_percent` string, required
    - `paid_overage_usd` string, nullable, required
    - `display_paid_overage` string, nullable, required
    - `includes_given_usage` boolean
    - `spendable_now` boolean, required
  - `period_end` string, date, required
  - `resets_on` string, date, nullable, required
  - `cancel_requested_at` string, date-time, nullable, required
  - `cancellable` boolean, required
  - `subscribable` boolean, required
  - `plan_charge` SubscriptionPrice, required — What Stripe bills a subscription each interval. The amount and its cadence are one value because either alone misstates the charge: an amount with no cadence cannot be read, and a cadence with no amount says nothing. Held whole, a surface cannot render half of it. This is the subscription's own price, not the configured list price, so a workspace billed a negotiated rate is never quoted someone else's.
    - `amount_usd` string, required
    - `interval` 'day' | 'week' | 'month' | 'year', required

## Changes

- **2026-09-19** `924eeadc29ad` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/maia-analytics/apis/maia-api/changes/api/v1/billing/summary/get.md)

---

[API](https://skmtc.dev/maia-analytics/apis/maia-api.md) · [All operations](https://skmtc.dev/maia-analytics/apis/maia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/maia-analytics/apis/maia-api/revisions/7720763f8bf1?raw)
