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

# Cost and usage

> Forecast credit cost, check your balance, monitor usage by voice or time bucket, and set up anomaly alerts.

The Supertone API uses a **credit-based** billing model that is shared with [Supertone Play](https://play.supertone.ai). This page covers how credits work, how to forecast cost before generating, and the endpoints you should integrate into your observability stack.

## How credits work

* Credits are deducted **per second** of generated audio.
* Credits are **shared with Supertone Play** — the same balance applies to both. Credits charged in Play are immediately available to the API and vice versa.
* Both preset voices and custom voices deduct from the same balance.
* **`predict_duration` is free.** No credits are deducted — use it for cost preview and pre-flighting.

Pricing tiers are listed on the [Play subscription page](https://play.supertone.ai/subscription). For higher limits and dedicated capacity, see [enterprise plans](https://docs.google.com/forms/d/1YexQpjpK0ZEou12blTytkZLqvrV-Uv95GbhxoOQ54R8/edit).

## Endpoints you should integrate

| Endpoint                               | Purpose                                                                                |
| -------------------------------------- | -------------------------------------------------------------------------------------- |
| `POST /v1/predict-duration/{voice_id}` | Forecast audio length (and therefore credit cost) before generating.                   |
| `GET /v1/credits`                      | Current credit balance — alert when it's low.                                          |
| `GET /v1/voice-usage`                  | Minutes generated per voice / style / language / model, by day (max 30 days).          |
| `GET /v1/usage`                        | Bucketed analytics with breakdowns by `voice_id`, `voice_name`, `api_key`, or `model`. |

## Predict duration

`predict_duration` returns the **expected length** of generated speech for a given text, without producing audio. Use it to:

* Show users a "this will take \~12 seconds" estimate before generation.
* Forecast credit cost (no credits are deducted by this endpoint).
* Decide whether a sentence fits a UI slot or budget.

<Note>
  `predict_duration` does **not** auto-chunk — the same 300-character limit applies. For longer scripts, split yourself and sum the predicted durations.
</Note>

<Tabs>
  <Tab title="Python">
    ```python theme={"dark"}
    import os
    from supertone import Supertone

    VOICE_ID = "20160a4c5ba38967330c84"  # replace with your voice ID

    with Supertone(api_key=os.environ["SUPERTONE_API_KEY"]) as client:
        response = client.text_to_speech.predict_duration(
            voice_id=VOICE_ID,
            text="This is a sentence to estimate.",
            language="en",
        )

    print(f"Estimated duration: {response.duration:.2f}s")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"dark"}
    import { Supertone } from "@supertone/supertone";

    const VOICE_ID = "20160a4c5ba38967330c84"; // replace with your voice ID

    const client = new Supertone({ apiKey: process.env.SUPERTONE_API_KEY });

    const response = await client.textToSpeech.predictDuration({
      voiceId: VOICE_ID,
      predictTTSDurationRequest: {
        text: "This is a sentence to estimate.",
        language: "en",
      },
    });

    console.log(`Estimated duration: ${response.duration?.toFixed(2)}s`);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"dark"}
    VOICE_ID="20160a4c5ba38967330c84"

    curl -X POST "https://supertoneapi.com/v1/predict-duration/$VOICE_ID" \
      -H "x-sup-api-key: $SUPERTONE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "text": "This is a sentence to estimate.",
        "language": "en"
      }'
    ```

    Response:

    ```json theme={"dark"}
    { "duration": 2.18 }
    ```
  </Tab>
</Tabs>

The request body is the same shape as [Create speech](/en/docs/text-to-speech/create-speech) — `text`, `language`, `style`, `model`, `voice_settings` — minus `output_format`, `include_phonemes`, and `normalized_text` (none of which affect the predicted length).

**Tips for accurate forecasts:**

* **Speed changes the result.** `voice_settings.speed` multiplies the duration. If you preview at one speed and generate at another, the actual length will differ. Use the same speed in both calls.
* **Match the model.** `predict_duration` accepts the same `model` field as `create_speech`. If your generation will use a specific model, predict against it.

For pre-flighting **batch jobs** or **per-user budgets**, call `predict_duration` first and sum the durations to decide whether to proceed.

## Daily balance check

A simple cron job that posts to your monitoring tool when the balance drops below a threshold gives you days of warning before a `402 Payment Required` outage.

<Tabs>
  <Tab title="Python">
    ```python theme={"dark"}
    import os
    from supertone import Supertone

    LOW_THRESHOLD_USD = 50.0

    with Supertone(api_key=os.environ["SUPERTONE_API_KEY"]) as client:
        balance = client.usage.get_credit_balance()
        if balance.credit_balance < LOW_THRESHOLD_USD:
            notify_oncall(
                f"Supertone credit balance low: ${balance.credit_balance:.2f}"
            )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"dark"}
    import { Supertone } from "@supertone/supertone";

    const LOW_THRESHOLD = 50;

    const client = new Supertone({ apiKey: process.env.SUPERTONE_API_KEY });
    const { creditBalance } = await client.usage.getCreditBalance();

    if (creditBalance !== undefined && creditBalance < LOW_THRESHOLD) {
      await notifyOncall(`Supertone credit balance low: $${creditBalance.toFixed(2)}`);
    }
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"dark"}
    curl https://supertoneapi.com/v1/credits \
      -H "x-sup-api-key: $SUPERTONE_API_KEY"
    ```
  </Tab>
</Tabs>

You can also view the live balance in the console dashboard or the Play subscription page.

## Weekly per-voice report

Useful when you want to know which voices drive the most cost, or to flag a runaway integration. Maximum query window is 30 days; dates are UTC+0.

<Tabs>
  <Tab title="Python">
    ```python theme={"dark"}
    from supertone import Supertone

    with Supertone(api_key=API_KEY) as client:
        usage = client.usage.get_voice_usage(
            start_date="2025-05-01",
            end_date="2025-05-31",
        )

        by_voice = {}
        for row in usage.usages or []:
            by_voice[row.name] = by_voice.get(row.name, 0) + row.total_minutes_used

        for name, minutes in sorted(by_voice.items(), key=lambda x: -x[1]):
            print(f"{name:30s} {minutes:>8.2f} min")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"dark"}
    const usage = await client.usage.getVoiceUsage({
      startDate: "2025-05-01",
      endDate: "2025-05-31",
    });

    const byVoice = new Map<string, number>();
    for (const row of usage.usages ?? []) {
      byVoice.set(row.name, (byVoice.get(row.name) ?? 0) + row.totalMinutesUsed);
    }

    for (const [name, minutes] of [...byVoice.entries()].sort((a, b) => b[1] - a[1])) {
      console.log(`${name.padEnd(30)} ${minutes.toFixed(2)} min`);
    }
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"dark"}
    curl "https://supertoneapi.com/v1/voice-usage?start_date=2025-05-01&end_date=2025-05-31" \
      -H "x-sup-api-key: $SUPERTONE_API_KEY"
    ```
  </Tab>
</Tabs>

## Bucketed analytics for dashboards

`GET /v1/usage` supports hourly or daily buckets with multiple breakdowns. Use it to populate a dashboard panel or send rows to your metrics backend.

<Tabs>
  <Tab title="Python">
    ```python theme={"dark"}
    from supertone import Supertone

    with Supertone(api_key=API_KEY) as client:
        page = client.usage.get_usage(
            start_time="2025-05-01T00:00:00+00:00",
            end_time="2025-05-31T23:59:59+00:00",
            bucket_width="day",
            breakdown_type=["api_key", "model"],
            page_size=20,
        )

        for row in page.items or []:
            emit_metric("supertone.minutes_generated", value=row.total_minutes_used, tags={
                "api_key": row.api_key,
                "model": row.model,
                "bucket_start": row.bucket_start,
            })
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"dark"}
    import { Supertone } from "@supertone/supertone";

    const client = new Supertone({ apiKey: API_KEY });

    const page = await client.usage.getUsage({
      startTime: "2025-05-01T00:00:00+00:00",
      endTime: "2025-05-31T23:59:59+00:00",
      bucketWidth: "day",
      breakdownType: ["api_key", "model"],
      pageSize: 20,
    });

    for (const row of page.items ?? []) {
      emitMetric("supertone.minutes_generated", row.totalMinutesUsed, {
        api_key: row.apiKey,
        model: row.model,
        bucket_start: row.bucketStart,
      });
    }
    ```
  </Tab>
</Tabs>

Restrictions:

* You can't combine `voice_id` and `voice_name` in the same `breakdown_type`.
* If `start_time` and `end_time` have different UTC offsets, the API ignores `end_time`'s offset.
* Page size is 1–20; paginate via `next_page_token`.

## Anomaly alerts

Two cheap, useful alerts:

1. **Spend spike** — compare today's minutes-generated to the rolling 7-day median. Alert if today is more than (say) 3× the median.
2. **New voice in production** — if a voice not in your expected set appears in `get_voice_usage`, flag it. This catches accidental hard-coded test voices in production code.

## Per-user attribution

The Supertone API itself doesn't track end-user identities — your backend does. The pattern is:

1. Have your backend record each TTS call with `user_id`, `voice_id`, predicted/actual duration, timestamp.
2. Roll up internally for billing or anti-abuse.
3. Cross-check periodically against `get_voice_usage` to make sure your records align with Supertone's count.

## Related

<CardGroup cols={2}>
  <Card title="Create speech" icon="comment" href="/en/docs/text-to-speech/create-speech">
    Generate audio once you've forecasted the cost.
  </Card>

  <Card title="Rate limits" icon="gauge" href="/en/docs/production/rate-limits">
    Per-minute request limits by tier.
  </Card>
</CardGroup>
