# Credits and limits

export const creditsCurl = `curl https://api.afterlib.com/v1/credits \\
  -H "Authorization: Bearer $AFTERLIB_API_KEY"`;

export const creditsJs = `const response = await fetch('https://api.afterlib.com/v1/credits', {
  headers: {Authorization: \`Bearer \${process.env.AFTERLIB_API_KEY}\`},
});

const credits = await response.json();`;

export const creditsTs = `type CreditsRequest = Record<string, never>;

const request: CreditsRequest = {};

const response = await fetch('https://api.afterlib.com/v1/credits', {
  headers: {Authorization: 'Bearer ' + process.env.AFTERLIB_API_KEY},
});

const credits = await response.json();`;

export const creditsPhp = `$response = file_get_contents('https://api.afterlib.com/v1/credits', false, stream_context_create([
  'http' => [
    'header' => 'Authorization: Bearer ' . getenv('AFTERLIB_API_KEY'),
  ],
]));

$credits = json_decode($response, true);`;

export const creditsPython = `import json
import os
import urllib.request

request = urllib.request.Request(
    'https://api.afterlib.com/v1/credits',
    headers={'Authorization': f"Bearer {os.environ['AFTERLIB_API_KEY']}"},
)

with urllib.request.urlopen(request) as response:
    credits = json.loads(response.read().decode('utf-8'))`;

The API uses the member subscription credits already available in AfterLib.

## Free requests

These requests do not charge usage credits:

- `GET /v1/whoami`
- `GET /v1/account`
- `GET /v1/credits`
- `GET /v1/collections`
- `GET /v1/websites/domains`
- `GET /v1/websites/domains/{domainId}`
- `GET /v1/websites/domains/{domainId}/pages`
- `GET /v1/websites/links`
- `GET /v1/websites/links/{linkId}`
- `GET /v1/websites/links/{linkId}/pages`
- `GET /v1/websites/links/{linkId}/ads`
- `POST /v1/collections/{collectionId}/items`

Website domain and website link collection operations are no-credit in this phase.

## Charged requests

Requests that return ad or page records charge credits for the unique items returned:

- `POST /v1/ads/search`
- `GET /v1/ads/{adId}`
- `POST /v1/pages/search`
- `GET /v1/pages/{pageId}`
- `GET /v1/collections/{collectionId}/items` when it returns ads or pages

If a request would exceed the available credits, the API returns an error response instead of partial data.

## Credit status

<ApiExampleTabs curl={creditsCurl} javascript={creditsJs} typescript={creditsTs} php={creditsPhp} python={creditsPython} />

Response:

```json
{
	"planId": "pro",
	"billingUserId": "00000000-0000-7001-8001-aa0000000001",
	"periodStart": 1779254247,
	"periodEnd": 1781932647,
	"credits": 99968,
	"creditsMax": 100000,
	"usageLimit": {
		"isLimitReached": false,
		"limitType": "none",
		"hourlyCredits": 0,
		"hourlyLimit": 5000,
		"dailyCredits": 32,
		"dailyLimit": 18000
	}
}
```

## Credit headers

Credit-gated responses include headers that show the remaining credit state when available. Use `GET /v1/credits` for the most readable current status.

`GET /v1/credits` returns `usageLimit` as an object when the account has active hourly or daily usage-limit tracking. Free-access accounts can return `usageLimit: null`.