# Créditos

> O que consome créditos, quando a cobrança acontece, como saber o preço antes e como conferir o extrato.

Créditos são o saldo do workspace. Toda rota que cobra diz o preço antes de cobrar, e todo débito aparece no extrato com o id do que o causou.

## O que cobra

| Ação | Quando cobra | Como saber o preço antes |
|---|---|---|
| Clipagem (`POST /clips`) | na criação da submissão | `credits_cost` em `POST /clips/info` |
| Tradução da legenda (`translate_to`) | junto com a clipagem | `credits_charged` na resposta de `POST /clips` |
| Transcrição (`POST /transcriptions`) | na criação, por minuto de áudio, mais um adicional com `speaker_labels` | `credits_charged` na resposta |
| Monitoramento de live | a cada bloco de 10 minutos que gerou clipes, só com o monitor ligado | |
| Geração de imagem, vídeo e voz | na criação, pelo preço que você mandou | `GET /generations/models` |
| Persona: foto e vídeo | na criação | `GET /personas/catalog` e `GET /personas/swap/quote` |

Ler, listar, analisar, renderizar e publicar não cobram.

## Confira o preço antes

`POST /clips/info` não cobra nada e devolve o custo exato da clipagem:

```json title="200 OK"
{
  "id": "7412908365112823",
  "duration": 213,
  "credits_cost": 4,
  "credits_original": 5,
  "discount_percent": 20,
  "current_balance": 120,
  "credits_unlimited": false
}
```

`credits_original` e `discount_percent` mostram o desconto aplicado, quando houver.

## Saldo

```bash
curl https://api.cut.pro/api/v1/balance \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

```json title="200 OK"
{ "balance": 120, "unlimited": false, "unlimited_until": null }
```

## Saldo insuficiente

A rota responde `402` antes de criar o job, e nada é cobrado:

```json title="402 Payment Required"
{
  "code": "INSUFFICIENT_CREDITS",
  "extra": { "credits_needed": 121, "current_balance": 40, "is_owner": true }
}
```

- `credits_needed` e `current_balance` dizem quanto falta.
- `is_owner` diz se o dono da chave pode comprar créditos para este workspace.
- Em geração e persona, `extra.top_up_url` é a página onde se compram créditos. Mostre para a pessoa.

## Extrato

`GET /balance/history` lista cada movimento, do mais novo para o mais antigo:

```bash
curl "https://api.cut.pro/api/v1/balance/history?type=debit&limit=20" \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

```json title="200 OK"
{
  "transactions": [
    {
      "id": "7412908372201188",
      "type": "debit",
      "amount": -4,
      "balance_after": 116,
      "reference_type": "usage",
      "reference_id": "7412908371004912",
      "description": null,
      "waived": false,
      "expires_at": null,
      "created_at": "2026-10-29T18:01:12.000Z"
    }
  ],
  "pagination": { "current_page": 1, "total_pages": 1, "total_count": 1, "has_next_page": false, "has_previous_page": false, "limit": 20 }
}
```

`amount` é negativo no débito e positivo no crédito. `reference_id` aponta para o que causou o movimento (a submissão, a assinatura, o reembolso). `expires_at` só vem preenchido em créditos que vencem. Filtre por `type` e `reference_type`.

## Devoluções

- **Clipagem cancelada:** `DELETE` numa submissão ainda em processamento cancela e devolve os créditos.
- **Geração que falhou:** volta sozinha. Geração pronta que saiu errada pode ter o reembolso pedido em `POST /generations/{id}/refund`, antes de baixar ou postar, e a equipe decide.
- **Transcrição repetida ou sem fala:** áudio já transcrito volta do cache com `credits_charged: 0`, e áudio sem fala termina em `no_speech` sem cobrança.
- **Tradução desnecessária:** se o vídeo já está no idioma de `translate_to`, o adicional da tradução volta.

## Uso gratuito

Um workspace pode estar em uso gratuito. Enquanto durar, os jobs rodam sem consumir créditos e nunca são recusados por saldo.

- `GET /balance` mostra `unlimited: true` e `unlimited_until` (`null` é sem data para acabar).
- `GET /workspace` traz o mesmo em `credits_unlimited` e `credits_unlimited_until`.
- `POST /clips/info` traz `credits_unlimited` junto do `credits_cost`.

O extrato continua registrando tudo: cada job aparece com o valor que teria custado e `waived: true`, e `balance_after` não muda. Campos de cobrança real, como `credits_charged`, vêm `0`.

> Geração com IA e personas sempre consomem créditos, mesmo em uso gratuito.
