Skip to main content

GET /api/v1/billing

Returns a monthly usage summary for your account. Use this to track consumption, build invoices, and monitor quota.
curl "https://api.myustadia.com/api/v1/billing?month=2026-06" \
  -H "Authorization: Bearer sk_live_..."
The month query parameter is optional. It defaults to the current calendar month. Format: YYYY-MM.
# Current month (default)
GET /api/v1/billing

# Specific month
GET /api/v1/billing?month=2026-04

Response shape

{
  "month": "2026-06",
  "client_id": "acme_corp",
  "summary": {
    "courses_total": 12,
    "courses_ready": 11,
    "courses_partial": 0,
    "courses_error": 1,
    "distinct_external_refs": 5,
    "total_modules": 48
  },
  "quota_seconds": {
    "quota_seconds": 7200,
    "consumed_seconds": 3428,
    "remaining_seconds": 3772,
    "percent_consumed": 48,
    "is_unlimited": false,
    "metered_billing_enabled": false
  },
  "breakdown_by_ref": [
    {
      "external_ref": "acme-emea",
      "courses": 3,
      "courses_ready": 3,
      "modules": 12
    }
  ],
  "note": "distinct_external_refs = number of unique external_ref values used this month. Use this to count billable units (e.g. companies served by ARESS). quota_seconds.percent_consumed is the authoritative usage figure."
}

Fields

Top level

FieldTypeDescription
monthstringThe billing month returned, in YYYY-MM format
client_idstringYour account identifier
summaryobjectAggregate course counts for the month
quota_secondsobjectAuthoritative seconds-bucket usage view
breakdown_by_refarrayPer-external_ref course and module counts
notestringHuman-readable annotation; subject to change

summary

FieldDescription
courses_totalAll courses created this month (excludes sandbox)
courses_readyCourses that reached ready status
courses_partialCourses stopped mid-generation due to quota exhaustion (partial_quota_exceeded)
courses_errorCourses that ended in error
distinct_external_refsCount of unique external_ref values used this month. Use this to count billable clients or projects.
total_modulesSum of module_count across all courses this month

quota_seconds

This is the authoritative usage view. Show percent_consumed to clients as their usage gauge.
FieldTypeDescription
quota_secondsintegerTotal seconds allocated to your account this billing period
consumed_secondsintegerSeconds used so far this month
remaining_secondsintegerquota_seconds - consumed_seconds, floored at 0
percent_consumedintegerUsage as a percentage (0-100). This is the figure to surface to clients.
is_unlimitedbooleantrue if quota_seconds is 0 or unset (unlimited plan)
metered_billing_enabledbooleanWhether quota enforcement is active on your account. When true, launches are rejected with 429 quota_exceeded once remaining_seconds reaches 0. When false, generation is not blocked on quota.
There is no free tier: generation always consumes from the seconds bucket. When metered_billing_enabled is true and the bucket is exhausted, new launches are rejected with 429 quota_exceeded.

breakdown_by_ref

One entry per distinct external_ref value used this month. Useful for building per-client or per-project usage summaries.
FieldDescription
external_refThe caller-supplied reference string
coursesTotal courses created under this ref this month
courses_readyCourses that reached ready
modulesTotal modules across all courses under this ref

Usage monitoring pattern

Poll /billing on a schedule to track quota burn and alert before exhaustion:
import httpx

resp = httpx.get(
    "https://api.myustadia.com/api/v1/billing",
    headers={"Authorization": "Bearer sk_live_..."},
)
data = resp.json()
pct = data["quota_seconds"]["percent_consumed"]

if pct >= 90:
    alert("Quota at {}% -- approaching limit".format(pct))
percent_consumed is clamped at 100 even if consumed_seconds slightly exceeds quota_seconds due to in-flight jobs completing after the soft cap.