# Credits


An organization billed in credits pays for its runs in credits: each audience
build, each scheduled refresh cycle, and each lookalike. The price of a run is
known before it starts, and the run is charged when it is accepted. A run that
fails, is cancelled, or completes with no results gets its credits back.
Activations, cohorts, and size estimates carry no credits.

**Credits answer only for an organization billed in credits.** For any other
organization every endpoint on this page, and the two quotes on
[Audiences](/api/v2/audiences#post-apiv2analysesaudiencesquote), returns `403`
with the message `Credits are not enabled for your organization.` (see
[Errors](/concepts/errors#403-forbidden)), and `credits_charged` on an audience
is `null`. Ask your Account Manager about credits for your organization.

What reads credits:

- [Get Credits](#get-apiv2credits) returns the balance of the current period.
- [Get Credits Statement](#get-apiv2creditsstatement) lists what added credits
  and what used them in that period.
- [Quote Audience](/api/v2/audiences#post-apiv2analysesaudiencesquote) and
  [Quote Lookalike](/api/v2/audiences#post-apiv2analysesaudiencesquote-lookalike)
  return the price of a run before you create it. Each takes the same body as
  its create. It creates nothing and is free.
- Every audience carries `credits_charged`, the credits its run was charged
  after any refund, on [Get Audience](/api/v2/audiences#get-apiv2analysesaudiencesid),
  [List Audiences](/api/v2/audiences#get-apiv2analysesaudiencesindex), the
  create responses, and the [`audience.*` webhooks](/api/v2/webhooks#audience-events).
- [Get Usage](/api/v2/usage) carries the same balance in its `credits` block.

The balance and the statement require additional permissions which need to be
approved by your Account Manager, the same as [Usage](/api/v2/usage). A quote
needs only what its create needs.

The endpoints are authenticated and JSON-only. Send `Authorization: Bearer
<token>` and `Accept: application/json` on every call. They use the read rate
bucket (120 requests/min per caller).

## The period

Credits are counted over a period: your contract term while today falls in it,
otherwise the calendar month. `used` is what the period's runs were charged,
net of refunds, and `available` is what you can still spend now, including
credits carried in from before the period (a pilot, for example). The share
used is `used / (used + available)`, rounded down to one decimal, so it reads
`100` only when nothing is left.

`state` follows the share used:

| `state` | When |
| --- | --- |
| `ok` | Under 70% used. |
| `low` | 70% or more used. |
| `critical` | 90% or more used. |
| `out` | Nothing left. |

## Get Credits {#get-apiv2credits}

`GET /api/v2/credits`

Returns your organization's credits for the current period: the balance, the
share used, the pace and the day the balance runs out at that pace, what
expires next, and the credits used per run type and per user.

**Auth:** bearer token + `Accept: application/json`. Rate limit: read bucket
(120 requests/min).

{{< tabs >}}

  {{< tab name="cURL" >}}
  ```bash
  curl "https://console.intuizi.com/api/v2/credits" \
    -H "Authorization: Bearer <YOUR_TOKEN>" \
    -H "Accept: application/json"
  ```
  {{< /tab >}}

  {{< tab name="Python" >}}
  ```python
  import requests

  res = requests.get(
      "https://console.intuizi.com/api/v2/credits",
      headers={
          "Authorization": "Bearer <YOUR_TOKEN>",
          "Accept": "application/json",
      },
  )
  credits = res.json()["data"]
  ```
  {{< /tab >}}

  {{< tab name="JavaScript" >}}
  ```javascript
  const res = await fetch("https://console.intuizi.com/api/v2/credits", {
    headers: {
      Authorization: "Bearer <YOUR_TOKEN>",
      Accept: "application/json",
    },
  });
  const credits = (await res.json()).data;
  ```
  {{< /tab >}}

  {{< tab name="PHP" >}}
  ```php
  $res = Http::withToken('<YOUR_TOKEN>')->acceptJson()
      ->get('https://console.intuizi.com/api/v2/credits');
  $credits = $res->json('data');
  ```
  {{< /tab >}}

{{< /tabs >}}

### Response

```json
{
  "status": "success",
  "code": 200,
  "message": "Resource fetched successfully.",
  "data": {
    "plan": "access",
    "period": {
      "type": "term",
      "from": "2026-10-01",
      "to": "2027-09-30",
      "days": 365,
      "days_elapsed": 33,
      "percent_elapsed": 9
    },
    "available": 876,
    "used": 124,
    "percent_used": 12.4,
    "state": "ok",
    "threshold": null,
    "expiring_next": null,
    "expired": 0,
    "pace": {
      "credits_per_day": 3.8,
      "runs_out_on": "2027-06-23",
      "lasts_the_period": false
    },
    "by_operation": [
      { "operation_type": "lookalike", "label": "Lookalike", "credits": 120 },
      { "operation_type": "audience_build", "label": "Audience Build", "credits": 4 }
    ],
    "by_user": [
      { "name": "Jane Doe", "credits": 124 }
    ]
  }
}
```

### Response fields

| Field | Type | Description |
| --- | --- | --- |
| `plan` | string or null | Your plan, for example `access`. `null` when none is recorded. |
| `period.type` | string | `term` while today falls in your contract term, otherwise `month`. |
| `period.from` | string | First day of the period, as `YYYY-MM-DD`. |
| `period.to` | string | Last day of the period, as `YYYY-MM-DD`. |
| `period.days` | integer | Days in the period. |
| `period.days_elapsed` | integer | Days of the period gone, today included. |
| `period.percent_elapsed` | number | Share of the period gone, in percent, rounded to one decimal. |
| `available` | integer | Credits you can spend now. |
| `used` | integer | Credits the period's runs were charged, net of refunds. |
| `percent_used` | number | `used / (used + available)` in percent, rounded down to one decimal. `100` only when nothing is left. |
| `state` | string | `ok`, `low`, `critical`, or `out`, from the share used (see [The period](#the-period)). |
| `threshold` | integer or null | The highest alert level the share used reached: `70`, `90`, or `100`. `null` under 70%. |
| `expiring_next` | object or null | The next credits to expire: `credits` and `expires_at` (`YYYY-MM-DD HH:MM:SS`). `null` when nothing is due to expire. |
| `expired` | integer | Credits that expired unused in the period. |
| `pace.credits_per_day` | number | Credits used per day of the period so far. |
| `pace.runs_out_on` | string or null | The day the balance runs out at that pace, as `YYYY-MM-DD`. `null` before any credits are used, or when nothing is left. |
| `pace.lasts_the_period` | boolean | Whether the balance lasts to the end of the period at that pace. |
| `by_operation` | array | Credits used per run type, most first: `operation_type` (`audience_build`, `audience_refresh`, or `lookalike`), its `label`, and `credits`. A run type with no credits is left out. |
| `by_user` | array | Credits used per user of your organization, most first: `name` and `credits`. A user who has left your organization is listed as `Former user`. |

## Get Credits Statement {#get-apiv2creditsstatement}

`GET /api/v2/credits/statement`

Lists the current period's entries, newest first: credits added (your plan, a
top-up, credits from Intuizi), runs charged, refunds, and credits that expired.
A run paid from two blocks of credits is one entry.

**Auth:** bearer token + `Accept: application/json`. Rate limit: read bucket
(120 requests/min).

### Query parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `search` | string | No | Optional free-text filter: entries whose audience name or entry label contains it (case-insensitive). |
| `page` | integer | No | Page number. Defaults to `1`. |
| `per_page` | integer | No | Entries per page, `1` to `100`. Defaults to `25`. |

{{< tabs >}}

  {{< tab name="cURL" >}}
  ```bash
  curl "https://console.intuizi.com/api/v2/credits/statement?search=refund" \
    -H "Authorization: Bearer <YOUR_TOKEN>" \
    -H "Accept: application/json"
  ```
  {{< /tab >}}

  {{< tab name="Python" >}}
  ```python
  import requests

  res = requests.get(
      "https://console.intuizi.com/api/v2/credits/statement",
      params={"search": "refund"},
      headers={
          "Authorization": "Bearer <YOUR_TOKEN>",
          "Accept": "application/json",
      },
  )
  entries = res.json()["data"]["items"]
  ```
  {{< /tab >}}

  {{< tab name="JavaScript" >}}
  ```javascript
  const res = await fetch("https://console.intuizi.com/api/v2/credits/statement?search=refund", {
    headers: {
      Authorization: "Bearer <YOUR_TOKEN>",
      Accept: "application/json",
    },
  });
  const entries = (await res.json()).data.items;
  ```
  {{< /tab >}}

  {{< tab name="PHP" >}}
  ```php
  $res = Http::withToken('<YOUR_TOKEN>')->acceptJson()
      ->get('https://console.intuizi.com/api/v2/credits/statement', ['search' => 'refund']);
  $entries = $res->json('data.items');
  ```
  {{< /tab >}}

{{< /tabs >}}

### Response

```json
{
  "status": "success",
  "code": 200,
  "message": "Resources fetched successfully.",
  "data": {
    "period": { "from": "2026-10-01", "to": "2027-09-30" },
    "items": [
      {
        "id": 4,
        "occurred_at": "2026-11-02T12:00:00+00:00",
        "entry_type": "refund",
        "entry": "Refund",
        "audience": { "id": 90, "name": "Tea Drinkers" },
        "user": "Jane Doe",
        "credits": 4,
        "note": "Run failed (status 403)"
      },
      {
        "id": 3,
        "occurred_at": "2026-11-02T11:00:00+00:00",
        "entry_type": "debit",
        "entry": "Audience Build",
        "audience": { "id": 90, "name": "Tea Drinkers" },
        "user": "Jane Doe",
        "credits": -4,
        "note": null
      },
      {
        "id": 1,
        "occurred_at": "2026-10-01T00:00:00+00:00",
        "entry_type": "grant",
        "entry": "Plan credits",
        "audience": null,
        "user": null,
        "credits": 1000,
        "note": null
      }
    ],
    "pagination": {
      "current_page": 1,
      "per_page": 25,
      "total": 3,
      "last_page": 1
    }
  }
}
```

### Response fields

| Field | Type | Description |
| --- | --- | --- |
| `period.from` | string | First day of the period the statement covers, as `YYYY-MM-DD`. |
| `period.to` | string | Last day of that period, as `YYYY-MM-DD`. |
| `items[].id` | integer | The entry id. |
| `items[].occurred_at` | string | When the entry was written, in ISO 8601 (UTC). |
| `items[].entry_type` | string | `grant` (credits added), `debit` (a run charged), `refund`, `expiry` (credits that expired), or `adjustment`. |
| `items[].entry` | string | What the entry is, as the console labels it, for example `Plan credits`, `Top-up`, `Audience Build`, `Scheduled Refresh`, `Lookalike`, `Refund`, or `Expired`. |
| `items[].audience` | object or null | The audience of a run: `id` and `name`. `null` for entries that are not a run. |
| `items[].user` | string or null | The user of your organization the entry belongs to, or `Former user` for one who has left it. `null` for an entry with no user, such as credits added. |
| `items[].credits` | integer | The signed credits: positive when credits were added or given back, negative when used. |
| `items[].note` | string or null | Why a refund was given, for example `Run failed (status 403)` or `Completed with zero results`. `null` on other entries. |
| `pagination` | object | `current_page`, `per_page`, `total`, and `last_page`. |
