# Credits and billing (/en/api/credits)

Paid jobs use prepaid credit in EUR. The credit belongs to the customer, and all projects of the customer use it. The billing endpoints need a `USER` key and the `OWNER` or the `ADMIN` role in the customer.

## How a job uses credit [#how-a-job-uses-credit]

1. **Approval.** The API holds the `cap` of the job estimate from your credit. If the spendable credit is less than the `cap`, the approval answers `402 INSUFFICIENT_FUNDS`.
2. **Run.** The hold stays while the job runs. You cannot spend the held credit on other jobs.
3. **Settlement.** The API charges the actual cost of the job, never more than the `cap`. It releases the rest of the hold at the same time.

A failed job costs nothing. Its hold goes back to your spendable credit.

A paid website analysis has no quote and no approval. The API holds its price when it creates the setup job. See [Add a website](/en/api/add-website.md#before-you-start).

## Read the balance [#read-the-balance]

Send [`GET /customers/{customer_id}/billing/balance`](/en/api/reference/billing/get-balance.md):

```bash
curl https://api.deepscout.ai/v1/customers/$CUSTOMER_ID/billing/balance \
  -H "Authorization: Bearer $SCOUT_API_KEY"
```

```json title="Response"
{ "currency": "EUR", "balance": "25.00", "held": "7.20", "spendable": "17.80" }
```

| Field | Description |
| --- | --- |
| `balance` | All your credit. |
| `held` | The credit that approved jobs hold until their settlement. |
| `spendable` | The credit that you can use for a new approval: `balance` − `held`. |

## Top up the credit [#top-up-the-credit]

A top-up is a card payment through Stripe Checkout. A person must complete the payment in a browser.

<Steps>
<Step>

### Create the checkout [#create-the-checkout]

Send [`POST /customers/{customer_id}/billing/topup`](/en/api/reference/billing/create-topup.md) with the amount in EUR. The amount must be from 5 to 5,000 EUR, with not more than two decimal places.

```bash
curl https://api.deepscout.ai/v1/customers/$CUSTOMER_ID/billing/topup \
  -H "Authorization: Bearer $SCOUT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": "50.00", "currency": "EUR"}'
```

```json title="Response (201 Created)"
{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_...",
  "session_id": "cs_live_a1B2c3D4e5F6"
}
```

If the approval of a job failed with `INSUFFICIENT_FUNDS`, you can send its `job_id` with the top-up. This only connects the payment to the job. It does not approve the job.

</Step>
<Step>

### Pay [#pay]

Open the `checkout_url` in a browser and pay by card. Stripe adds the VAT to the amount. Your credit is the amount without VAT. If you are a business in the EU, add your VAT ID in the checkout. Then the reverse charge applies.

</Step>
<Step>

### Wait for the credit [#wait-for-the-credit]

Read [`GET /customers/{customer_id}/billing/topups/{session_id}`](/en/api/reference/billing/get-topup-status.md) every few seconds. When `fulfilled` is `true`, the credit is in your balance.

```json title="Response"
{ "session_id": "cs_live_a1B2c3D4e5F6", "fulfilled": true }
```

</Step>
<Step>

### Approve the job again [#approve-the-job-again]

If you topped up for a job, approve it again. See [Approve the quote](/en/api/full-scrape.md#3-approve-the-quote).

</Step>
</Steps>

## Invoices [#invoices]

You get one invoice for each top-up, after the payment.

- [`GET /customers/{customer_id}/billing/invoices`](/en/api/reference/billing/list-topup-invoices.md) lists the invoices, newest first.
- [`GET /customers/{customer_id}/billing/invoices/{invoice_id}/pdf`](/en/api/reference/billing/download-topup-invoice.md) downloads the PDF.

```json title="GET /customers/{customer_id}/billing/invoices"
{
  "items": [
    {
      "invoice_id": "4821",
      "invoice_code": "FV-2026-0001",
      "created_at": "2026-10-13T09:30:00.000Z",
      "currency": "EUR",
      "total": "60.50"
    }
  ]
}
```

The job charges have no invoices. They use credit that you already paid.

## Usage [#usage]

[`GET /customers/{customer_id}/billing/usage`](/en/api/reference/billing/get-usage.md) lists the charges of one calendar month, newest first. Set the month with `month=YYYY-MM`. Without it, you get the current month. The months use the Europe/Prague time zone.

```json title="Response"
{
  "month": "2026-10",
  "currency": "EUR",
  "total": "257.57",
  "items": [
    {
      "job_id": "jobreq_01k7d0f1g2h3j4k5m6n7p8q9r0",
      "job_type": "FULL_SCRAPE",
      "project_id": "proj_01k7c2r9v8e3s0b1x6m4q5n2tz",
      "website_id": "example-shop.cz",
      "quantity": 17950,
      "amount": "12.57",
      "capped": false,
      "settled_at": "2026-10-13T15:40:00.000Z"
    }
  ]
}
```

A failed paid job shows with the amount `0.00`. A free matching sample does not show.

## Monthly spend limit [#monthly-spend-limit]

Each customer has a monthly spend limit. The default is 5,000 EUR. The API adds the charges of the month, the current holds and the `cap` of the new job. If the sum is more than the limit, the approval answers `403 MONTHLY_LIMIT_REACHED`:

```json title="403 MONTHLY_LIMIT_REACHED"
{
  "code": "MONTHLY_LIMIT_REACHED",
  "detail": "Monthly spend limit is reached",
  "currency": "EUR",
  "monthly_limit": "5000.00"
}
```

A top-up does not help. Wait until running jobs settle and release their holds, or until the next month starts. You can also write to [support@deepscout.ai](mailto:support@deepscout.ai) to change the limit.

<Callout title="Managed customers">
If DeepScout manages your account, the billing endpoints answer `403 MANAGED_CUSTOMER`. DeepScout sends you invoices separately.
</Callout>
