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

# Credits

> Understand balances, charging, and safe retry behavior.

Developer API requests use the same credit wallet as the Porn Factory AI web
generator. Check the current balance before submitting large batches:

```bash theme={"system"}
curl --request GET \
  --url 'https://pornfactoryai.com/api/v1/credits' \
  --header 'Authorization: Bearer pfai_YOUR_KEY'
```

The response returns only the balance fields needed to budget requests:

```json theme={"system"}
{
  "object": "credit_balance",
  "available_credits": 240,
  "bonus_credits": 0,
  "total_credits": 240
}
```

Generation responses include `credits.charged`. If the wallet cannot cover a
request, the API returns `402 insufficient_credits` with the required and
available amounts when available.

Use an idempotency key for every generation. A safe retry with the same key and
body returns the existing request instead of creating another charge.

## Budget a batch

Read the current balance once before a batch, compare it with the catalog's
`credit_estimate`, and still handle `402` on submission because another request
can use credits in the meantime.

```javascript theme={"system"}
const response = await fetch("https://pornfactoryai.com/api/v1/credits", {
  headers: { Authorization: `Bearer ${process.env.PFAI_API_KEY}` },
});

if (!response.ok) throw new Error(`Credit lookup failed: ${response.status}`);

const balance = await response.json();
const estimatedBatchCost = selectedModel.credit_estimate * batchSize;

if (balance.total_credits < estimatedBatchCost) {
  throw new Error("Not enough credits for this batch");
}
```

Credits are charged once for an accepted generation. If that generation ends
in `FAILED`, its generation charge is restored. Poll the request or consume its
webhook before reconciling a final batch cost.

<Note>
  `credit_estimate` helps with planning, while `credits.charged` on the request
  is the authoritative amount for that generation.
</Note>
