# Credits, billing & usage tracking

> How the Nyne.ai API charges credits: fixed per-call vs dynamic per-result pricing, feature surcharges, pre-flight checks and deduction, the monthly quota, and how to track usage without double-counting.

HTML version: https://api.nyne.ai/documentation/credits

Every call to the Nyne.ai API is priced in credits. Most endpoints charge a fixed amount per call; a few price dynamically by the number of results you request.

## The credit model

Most endpoints cost a **fixed** number of credits per call. **Search** and company **employees** are **dynamic**: the charge is `credits x requested_limit`, so asking for more results costs proportionally more. These are the documented default costs - your workspace may have negotiated overrides, and the live figures load from your account into the endpoint pages.

### Person

| Action | Credits | Notes |
| --- | --- | --- |
| person_search | 1 (x limit) | Dynamic: per result requested. |
| person_enrichment | 2 | Standard full-profile enrichment. |
| person_lookup_fields | 1 | Only the fields you ask for. |
| person_email | 1 | Single best work email. |
| person_phone | 1 | Single best phone. |
| person_newsfeed | 1 | ceil(limit / 10) units; by-URL lookup bills 1. |
| person_ask | 10 | AI-powered profile Q&A. |
| person_interests | 5 | Interest analysis. |
| person_leads | 1 | Lead search. |
| person_discover | 10 | Discovery. |
| person_deep_research | 100 | Long-running deep research. |
| social_account_validation | 10 | Validate a social account. |

### Company

| Action | Credits | Notes |
| --- | --- | --- |
| company_search | 1 (x limit) | Dynamic: per result requested. |
| company_enrichment | 1 | Full company profile. |
| company_employees | 1 (x limit) | Dynamic: per result requested. |
| company_intent | 10 | Buyer-intent signals. |
| company_competitor_engagements | 5 | Per engagement result. |
| company_needs | 1 | Company needs. |
| company_funding | 1 | Funding history. |

A few specifics worth knowing:

- `person_ask` costs 10 credits per call - it runs an AI analysis over the profile.
- Newsfeed quantity is `ceil(limit / 10)` units, so a larger feed costs more units; a single by-URL newsfeed lookup bills 1.
- Standard `person_enrichment` is the everyday tier. The higher-tier `person_enrich` forces a full newsfeed and costs more - see [Request depth](https://api.nyne.ai/documentation/request-depth.md) for when to reach for it.

## Feature surcharges

On search endpoints, feature toggles change the price. The more you turn on, the more each result costs: `show_emails`, `show_phone_numbers`, `insights`, `profile_scoring`, `high_freshness`, `require_emails`, `require_phone_numbers`, `require_phones_or_emails`.

The billing action key is a function of the feature **combination** - deduped and canonically ordered - so the same set of toggles always maps to the same key. For example, a search with emails and phones on bills under `person_search:show_emails:show_phone_numbers`. See [Request depth](https://api.nyne.ai/documentation/request-depth.md).

## Pre-flight checks & deduction

Credits are handled in two moments. Before any work starts, the request runs a **pre-flight allowance check**: if the workspace cannot cover the estimated cost, the call fails immediately with `402 insufficient_credits` and nothing is spent. Credits are only **deducted on completion**, after a meaningful result. Async endpoints reserve at submit and debit in the worker once the result lands. Every charge carries a `billing_action_key` naming exactly what was billed:

```json
{
  "success": true,
  "data": {
    "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271",
    "status": "completed",
    "billing_action_key": "person_search:show_emails:show_phone_numbers",
    "credits_charged": 20,
    "requested_limit": 10
  },
  "timestamp": "2026-05-28T18:04:45"
}
```

**Empty results do not burn credits.** A no-match or empty result is not billed. You pay only when the API returns a meaningful result.

When the pre-flight check fails, the shape is the standard error envelope - branch on `error.code`:

```json
{
  "success": false,
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits to complete this request."
  },
  "timestamp": "2026-05-28T18:04:45"
}
```

## The monthly quota

On **top** of per-request credits, your plan has a monthly request quota - a cap on how many calls you can make in a billing month, independent of credit balance. Exceeding it returns `monthly_limit_exceeded` with HTTP `429`:

```json
{
  "success": false,
  "error": {
    "code": "monthly_limit_exceeded",
    "message": "Monthly request quota exceeded."
  },
  "timestamp": "2026-05-28T18:04:45"
}
```

Every response carries the quota state in headers:

| Header | Meaning |
| --- | --- |
| X-Quota-Limit | Requests allowed this month. |
| X-Quota-Used | Requests already spent this month. |
| X-Quota-Remaining | Requests left before the cap. |
| X-Quota-Reset | When the quota window resets. |

The quota is distinct from per-minute and per-hour throttling. For those, see [Rate limits](https://api.nyne.ai/documentation/rate-limits.md).

## Usage tracking & analytics

You can see per-call spend and history through the Usage Analytics API, which reports credits grouped by `billing_action_key`:

```json
{
  "success": true,
  "data": {
    "period": "2026-05",
    "total_credits": 142,
    "by_action": [
      { "billing_action_key": "person_search", "credits": 40, "calls": 40 },
      { "billing_action_key": "person_search:show_emails", "credits": 60, "calls": 30 },
      { "billing_action_key": "person_enrichment", "credits": 42, "calls": 21 }
    ]
  },
  "timestamp": "2026-05-28T18:04:45"
}
```

**Two ledgers - do not double-count.** Usage lives in two distinct tables:

| Table | Role | Reconcile with |
| --- | --- | --- |
| api_requests | Request ledger. One row per call; its credits column is 0. | Count calls, inspect status and timing. |
| credit_tracker | Credits / billing ledger. One row per charge, keyed by billing_action_key. | SUM credits for authoritative billing. |

Reconcile spend by SUMming `credit_tracker` grouped by `billing_action_key`, never by adding up request rows.

## What isn't billed yet

Some newer or observability-only pricing is **computed but not yet debited**. For instance, a general-search backend path calculates a cost without charging it. You may see a computed cost that never shows up on the bill - that is expected, not a discrepancy. Treat `credit_tracker` as the source of truth for what you were actually charged.

## What's next

- [Rate limits](https://api.nyne.ai/documentation/rate-limits.md) - per-minute and per-hour throttling, and how the monthly quota fits in.
- [Request depth](https://api.nyne.ai/documentation/request-depth.md) - the feature toggles and enrichment tiers that move the price.
- [Effective requests](https://api.nyne.ai/documentation/effective-requests.md) - shaping calls to get the results you need for the fewest credits.
- [Responses](https://api.nyne.ai/documentation/responses.md) - the envelope, error codes, and status fields you branch on.
