> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crovver.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Credit Balance

> Fetch the current credit balance for all pools on a tenant's active subscription.

Returns a breakdown of base (plan-included) and add-on credits remaining per pool, along with expiry and limit info. Returns an empty object `{}` if the tenant has no active subscription.

## Query Parameters

<ParamField query="tenantId" type="string" required>
  The external tenant ID from your application
</ParamField>

<ParamField query="productSlug" type="string">
  Scope the lookup to the tenant's active subscription for this product (e.g. `ats`). A tenant holds at most one active subscription per product, so this is the recommended way to disambiguate multi-product tenants. Without it, the most recently created active subscription is used.
</ParamField>

<ParamField query="subscriptionId" type="string">
  Scope the lookup to an exact subscription ID. Takes effect together with `productSlug` if both are passed (they must refer to the same subscription).
</ParamField>

<ParamField query="publicKey" type="string">
  Your public key (`pk_live_...`). Alternative to the `Authorization` bearer header — use one or the other.
</ParamField>

## Authentication

Requires one of:

* **Bearer header** — `Authorization: Bearer sk_live_...` (secret key, server-side)
* **Query param** — `?publicKey=pk_live_...` (public key, client-side)

## Response

Returns an object keyed by `pool_key`.

<ResponseField name="data.[poolKey].poolKey" type="string">
  The pool key (e.g. `api_calls`, `ai_tokens`)
</ResponseField>

<ResponseField name="data.[poolKey].displayName" type="string">
  Human-readable pool name
</ResponseField>

<ResponseField name="data.[poolKey].baseRemaining" type="integer">
  Credits remaining from the plan's base allocation
</ResponseField>

<ResponseField name="data.[poolKey].addonRemaining" type="integer">
  Credits remaining from add-on purchases
</ResponseField>

<ResponseField name="data.[poolKey].total" type="integer">
  Total remaining credits (`baseRemaining + addonRemaining`)
</ResponseField>

<ResponseField name="data.[poolKey].limit" type="integer">
  The pool's `limit_per_period` as defined on the plan
</ResponseField>

<ResponseField name="data.[poolKey].limitBehavior" type="string">
  `hard` or `soft` — whether the pool blocks consumption at zero or allows overage
</ResponseField>

<ResponseField name="data.[poolKey].nextExpiry" type="string | null">
  ISO timestamp of the earliest upcoming credit expiry, or `null` if none
</ResponseField>

<ResponseField name="data.[poolKey].usagePercent" type="integer">
  Percentage of credits consumed so far (`0–100`)
</ResponseField>

<RequestExample>
  ```bash cURL (public key) theme={null}
  curl "https://app.crovver.com/api/public/credits/balance?tenantId=workspace_123&publicKey=pk_live_..."
  ```

  ```bash cURL (secret key) theme={null}
  curl "https://app.crovver.com/api/public/credits/balance?tenantId=workspace_123" \
    -H "Authorization: Bearer sk_live_..."
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "data": {
      "api_calls": {
        "poolKey": "api_calls",
        "displayName": "API Calls",
        "baseRemaining": 850,
        "addonRemaining": 500,
        "total": 1350,
        "limit": 1000,
        "limitBehavior": "soft",
        "nextExpiry": "2025-02-01T00:00:00Z",
        "usagePercent": 15
      }
    }
  }
  ```

  ```json 200 No active subscription theme={null}
  {
    "success": true,
    "data": {}
  }
  ```
</ResponseExample>
