/billingRead each site's tiers and usage
Per active site: its tier in each product (Consent and Event monitoring, each Free or Pro), what that costs a month, and this month's metered usage against its allowance.
Auth header
Authorization: Bearer tsk_live_…The key needsbilling:read
Example request
curl "https://app.tagsentry.ai/api/v1/billing" \ -H "Authorization: Bearer tsk_live_…"Response 200
paymentProblemobject | nullrequiredNull when Stripe has reported nothing wrong. Never changes what a banner serves.
paymentProblem.severitystringrequiredpaymentProblem.headlinestringrequiredsitesarray of objectrequiredsites[].siteIdstringrequiredsites[].domainstringrequiredsites[].tiersobjectrequiredsites[].tiers.consentstringrequiredOne of
free,paidsites[].tiers.monitoringstringrequiredOne of
free,paidsites[].monthlyPriceCentsintegerrequiredWhat this site's two products cost a month, before usage.
sites[].awaitingStripeReconciliationbooleanrequiredsites[].usageobjectrequiredsites[].usage.billingMonthstringrequiredsites[].usage.countedThroughstring | nullrequiredThe end of the last counted window. Later events are not in these figures yet.
sites[].usage.hasUnconfirmedWindowsbooleanrequiredsites[].usage.byDimensionarray of objectrequiredsites[].usage.byDimension[].dimensionstringrequiredsites[].usage.byDimension[].productstringrequiredsites[].usage.byDimension[].tierstringrequiredsites[].usage.byDimension[].quantityintegerrequiredsites[].usage.byDimension[].includedinteger | nullrequiredsites[].usage.byDimension[].overQuantityintegerrequired
Example response
{ "paymentProblem": { "severity": "…", "headline": "…" }, "sites": [ { "siteId": "3f6c1b8e-2d4a-4c7e-9a51-0b8f2e6d7c10", "domain": "silverpine.example", "tiers": { "consent": "free", "monitoring": "free" }, "monthlyPriceCents": 0, "awaitingStripeReconciliation": false, "usage": { "billingMonth": "2026-09", "countedThrough": "2026-09-26T14:02:00.000Z", "hasUnconfirmedWindows": false, "byDimension": [ { "dimension": "…", "product": "…", "tier": "…", "quantity": 0, "included": 0, "overQuantity": 0 } ] } } ]}More about this endpoint
usage.countedThrough is where the count stops; later events are not in it yet.
Payment state never changes what a banner serves. Owner-minted keys only. A site-pinned key sees its own site and no account payment state.
Errors401 · 403 · 429 · 500
401Missing, malformed, unknown, revoked or expired API key. These are deliberately indistinguishable in the response -- distinguishing them would confirm to a caller that a token was once real.403The key authenticated but does not carry the scope(s) this operation requires, or (`domain_not_verified`) the site's domain is not verified, so its consent records are not released.429A rate limit or quota was exceeded. The body names WHICH one.500Something failed on our side. The requestId in the body is what to quote.
Every error has the same body: { error: { code, message, requestId } }.
From the OpenAPI document, version 2026-08-26. Raw OpenAPI