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

# Starting credits

> Redeem a code, then call the API until the credits run out.

Redeeming a credit code puts a pool of credits on your account, and those credits pay for your
calls. You need no card while credits remain, and your keys work normally.

## Redeem your code

1. Sign in at [cue.vibeset.ai](https://cue.vibeset.ai). Your account is created on the first visit.
2. Open [Developer](https://cue.vibeset.ai/developer), find the **Credits** row of the Billing
   card, paste the code into the box (its placeholder reads `CUE-XXXXX-XXXXX`), and press
   **Redeem**.
3. Create an API key under **API keys**. It works immediately.

Case, spaces and dashes do not matter. The server strips every non-alphanumeric character and
upper-cases the rest before it looks the code up.

An account may redeem one code. A second one is refused with a `409`, so the box does not come
back once you have redeemed. In its place the row shows your balance and expiry.

## What a credit is worth

One credit is \$0.001 of list-price usage. Credits are a denomination of the ordinary price list,
not a second price table, so nothing is priced differently while you are on credits.

| Call                                                               | Credits               |
| ------------------------------------------------------------------ | --------------------- |
| Analysis, per minute of video, charged when you add it             | 60 per minute         |
| Match (`POST /v1/match`)                                           | 5 per call            |
| Underscore (`POST /v1/underscore`)                                 | 50 per call           |
| Beat mapping (`POST /v1/beats`)                                    | 8 per minute of audio |
| Sync (`POST /v1/align`), first call for a video and track together | 10 per call           |
| Sync (`POST /v1/align`), any later call for that same pair         | 1 per call            |
| Loop (`POST /v1/loop`), first call for a video and track together  | 14 per call           |
| Loop (`POST /v1/loop`), any later call for that same pair          | 1 per call            |

Video and audio minutes both round up, with a one-minute floor.

A call that errors bills nothing, and so does a loop that comes back `applicable: false`.

## The high rate is not "once per track"

This is the number most integrations get wrong when they size a grant.

**Loop is strictly per pair.** `/v1/loop` reads its plan cache on `(video_id, track_source,
track_key)` and has no track-level fallback. Looping one track over ten videos is ten calls at 14
credits, not one at 14 and nine at 1. Budget the high rate for every new pairing, however many
times you have used that track before.

**Sync is per pair with one escape hatch.** `/v1/align` is warm when Cue already holds sync points
for that exact pair, and also when it holds both profiles it would need to score them in memory:
the video's sync profile and the track's audio profile. The audio profile is built the first time
you align that track against anything, and the video's profile is warmed in the background after
ingest.

That background warm is best-effort and swallows its own failures, so the video's profile can be
missing. When it is, the call is cold and bills 10 credits, even for a track you have aligned many
times before. Do not budget sync as one cold call per track.

Within one pairing the second call is warm either way. The first is not, and there is no way to
pre-warm a pairing from the API.

## Watching the balance

Three headers carry your position, and none of them is unconditional:

```http theme={null}
X-Cue-Credits-Remaining: 98420
X-Cue-Credits-Total: 100000
X-Cue-Credits-Expires: 2026-09-14T00:00:00+00:00
```

They are stamped on a `/v1` response only when the request got past the key check and the account
carries a grant. A `401` for a missing or invalid key carries none of them, and neither does any
non-`/v1` route. `X-Cue-Credits-Expires` needs one more condition: the grant must have an expiry.
A grant minted with no expiry never sends that header, and its credits do not lapse.

An unhandled `500` carries none of the three either, because the middleware that stamps them runs
after the handler returns and never runs when the handler raises.

Do not treat a missing header as a zero balance. The **Credits** row in the portal shows the same
numbers, and the usage chart above it keeps working throughout a trial, because credit-funded
calls are metered to the ledger at full list price. They are just not charged to a card.

## When credits run out

Calls fail with `402` and a machine-readable prefix on the message:

```json theme={null}
{ "error": { "message": "credits_exhausted: your 100,000 Cue credits are used up. Add a card in the developer portal to keep calling." } }
```

| Prefix              | Meaning                    |
| ------------------- | -------------------------- |
| `credits_exhausted` | The pool is spent.         |
| `credits_expired`   | The grant's window closed. |

If the ledger cannot be read, the call fails with `503` and `Retry-After: 5` instead, and the
message reads "Credit balance temporarily unavailable". Retry it.

Adding a video is refused before any analysis runs, so a video we did not process never costs you
anything. The refusal lands on the video row rather than on the request, which returns `202` as
usual. Poll `GET /v1/videos/{video_id}`:

```json theme={null}
{ "video_id": "vid_123", "status": "failed", "reason": "insufficient_credits" }
```

`reason` is one of `insufficient_credits`, `credits_expired`, `video_too_long_for_credits` when
the clip runs past the per-video ceiling on your grant (30 minutes unless we set it otherwise), or
`credits_unavailable` when we could not read your balance. Only the last one is worth an immediate
retry.

## The monthly spend cap applies to credit-funded calls too

Credit-funded calls write their list price to the same usage ledger a paid call writes to, and the
monthly spend cap reads that ledger. Accounts are provisioned with a $100 cap. Spending a $100
grant inside one calendar month therefore also spends the cap, and the next call fails with a
`402` naming the cap rather than the credits.

Raise the cap under Billing in the developer console before a large batch.

## Moving to paid

Add a card in Billing. Same keys, same endpoints, no re-integration.

<Note>
  Credits are used first. Adding a card while credits remain does not start charging you. Calls
  keep drawing on the grant and are not reported to Stripe until the credits are gone.
</Note>

## How many API keys you can hold

An account without an active payment method can hold **two live API keys**. Adding a card in
Billing raises that to **ten live API keys**, and the change takes effect immediately — there is
nothing to wait for and nobody to ask.

A request past your limit is refused with a `409` naming the limit and how many keys you hold.
Revoking a key frees its slot.

<Note>
  A key you rotated out stops counting as soon as its grace window closes. Rotating does not
  consume a slot.
</Note>

Credits are not transferable between accounts, do not roll over, and are not refundable for cash.
They stop when they are spent or when the window closes.
