# Pricing (/docs/api/operational/pricing)



Every paid operation on the Partner API debits a single credit wallet on your Layers organization. Ingest is free today; generation costs credits; overage is handled by top-up or opt-in auto-topup.

**Credit dollar-rates are set by your plan, not this page.** The per-credit price you pay, your monthly included credits, and top-up rates are all surfaced in the [Layers dashboard](https://app.layers.com/billing) under your subscription. Enterprise pricing is negotiated — contact [sales@layers.com](mailto:sales@layers.com).

For the programmatic wallet check used before a generate call, see [`GET /v1/credits`](/docs/api/reference/credits/get-credits).

## Format cost table (in credits) [#format-cost-table-in-credits]

Credits per operation are the same on every plan — what varies is the $/credit your plan charges. The numbers below match `estimatedCreditsPerFormat` returned by [`GET /v1/credits`](/docs/api/reference/credits/get-credits). They are defaults — a specific layer template can override its per-workflow credit cost in its default config, and the override wins.

| Format            | Credits |
| ----------------- | ------- |
| `video_remix`     | 120     |
| `slideshow_remix` | 50      |
| `ugc_remix`       | 120     |
| `auto`            | 120     |

`auto` resolves to one of the specific formats at render time based on asset availability. If it resolves to a slideshow, the 50-credit rate applies; any video output charges the 120 default.

## Ingest costs [#ingest-costs]

Ingest calls are free today. The [`GET /v1/credits`](/docs/api/reference/credits/get-credits) response reflects this on the `ingestCostsBilled` object — all three flags are `false`.

| Ingest                                  | Billed today? | Underlying cost (Layers-absorbed)                |
| --------------------------------------- | ------------- | ------------------------------------------------ |
| `POST /v1/projects/:id/ingest/github`   | No (`false`)  | Sandboxed agent minutes + GitHub App token usage |
| `POST /v1/projects/:id/ingest/website`  | No (`false`)  | Website scrape spend                             |
| `POST /v1/projects/:id/ingest/appstore` | No (`false`)  | App Store + Play Store scrape                    |

If Layers ever flips one of these to billed, we commit to **30-day advance notice** via the [Changelog](/docs/api/operational/changelog), a notice in the partner-tier Slack channel, and an updated row in this page's change log (below) listing the exact per-call credit deduction. The `ingestCostsBilled` flag on `/v1/credits` will flip to `true` on the same date, so partners who gate programmatically will see it before a single bill posts.

## Overage & exhaustion [#overage--exhaustion]

At balance zero, every credit-spending call returns `402 BILLING_EXHAUSTED`:

```json
{
  "code": "BILLING_EXHAUSTED",
  "message": "Credit balance exhausted. Top up to resume.",
  "details": {
    "topUpUrl": "https://app.layers.com/billing/top-up",
    "balance": 0,
    "requiredCredits": 10
  }
}
```

Calls that do not spend credits (reads, whoami, job polling, webhook receipt) continue to work — the plan gate only blocks credit-spending operations.

**Auto-topup** is off by default. Enable it in the dashboard at `https://app.layers.com/billing/auto-topup`:

* Set a trigger threshold (e.g. balance ≤ 100 credits).
* Set a top-up amount (e.g. purchase 2,000 credits).
* Auto-topup uses the default payment method on file.
* Failures of the top-up charge surface as a `billing.topup_failed` event in the [audit log](/docs/api/reference/audit-log/list) and a webhook if you've registered `billing.*`.

Without auto-topup, you top up manually via the dashboard or via your Layers contact for Enterprise invoicing.

## Forecasting spend [#forecasting-spend]

Use `estimatedCreditsPerFormat` from [`GET /v1/credits`](/docs/api/reference/credits/get-credits) as the pre-flight check before firing a generate call. The response also carries `usedThisPeriod` and `includedRemaining` — everything you need to render a "you've used X of Y this period" bar in your own dashboard.

```ts
const wallet = await fetch("https://api.layers.com/v1/credits", {
  headers: { "X-Api-Key": process.env.LAYERS_API_KEY! },
}).then((r) => r.json());

const cost = wallet.estimatedCreditsPerFormat.video_remix;
if (wallet.balance < cost) {
  // 402 will fire if we proceed; warn the user and link to top-up.
  throw new Error(`Low balance: ${wallet.balance} < ${cost}`);
}
```

## Changelog (pricing-specific) [#changelog-pricing-specific]

Material changes to credit-per-operation rates or ingest billing land here with a date. Non-material changes (copy edits, clarifications) are not logged. Subscription-tier $/credit changes are plan-level and do not appear here.

| Date       | Change                                                                                                                                  |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 2026-04-20 | Initial publication of the credit-cost table and ingest-billing policy. No changes to credits-per-operation vs prior implicit defaults. |

## See also [#see-also]

* [`GET /v1/credits`](/docs/api/reference/credits/get-credits) — programmatic wallet check
* [Errors](/docs/api/operational/errors) — `BILLING_EXHAUSTED` (402) semantics
* [Rate limits](/docs/api/operational/rate-limits) — per-tier rate ceilings
