# Credits and quotes (https://docs.propertypixel.app/credits-and-quotes)

How spending works, what things cost, and how to confirm a spend.



Agents and scripts spend the connected workspace's credits, at the same prices as the web app. Nothing is ever spent without a quote that was confirmed, or an explicit `auto_confirm` in a REST call.

## Prices [#prices]

| Operation               | Cost                                                  |
| ----------------------- | ----------------------------------------------------- |
| `enhance_photos`        | 100 credits per photo, all enhancement types combined |
| `stage_photos`          | 100 credits per variation per photo                   |
| Ultra HD add-on         | +100 credits per result                               |
| `create_video`          | 400 credits per photo                                 |
| `get_recommendations`   | Free                                                  |
| `apply_recommendations` | 100 credits per photo                                 |

`list_edit_options` (`GET /v1/edit-options`) returns the current prices as `credit_costs`. Jobs that fail are refunded automatically.

## The quote → confirm flow [#the-quote--confirm-flow]

1. Call a spending operation **without** `quote_id`. You get a **quote**: what will run, the credit cost, your balance before and after, and warnings such as a trial watermark. Nothing is spent.
2. Show the quote to the user.
3. Call the **same operation with the same arguments** plus `quote_id`. The work runs and you get job IDs.

A quote:

* lasts **10 minutes**,
* can be used **once**,
* is bound to the connection and to the exact request. Change any argument and you get `409 quote_mismatch`; request a new quote.
* with `all_photos: true`, covers the photos in the project when it was quoted. If photos are added or removed before you confirm, or the price goes up, confirming fails with `409 quote_mismatch`.

Over MCP, the first call returns the quote as the tool result. ChatGPT shows it as a card with a **Run** button; other clients tell you the cost and wait for your yes.

Over REST, the first call returns `409` with code `quote_required` and the quote in the `quote` field. You can also price a request explicitly with `POST /v1/quotes`:

```bash
curl -s -X POST "$PP_API/quotes" \
  -H "Authorization: Bearer $PP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operation": "stage_photos",
       "input": {"photo_ids": ["…"], "design_style": "modern", "variations": 2}}'
```

## `auto_confirm` (REST only) [#auto_confirm-rest-only]

Scripts that already know what they will spend can send `"auto_confirm": true` and skip the quote:

```json
{ "photo_ids": ["…"], "enhancement_types": ["improve_lighting"], "auto_confirm": true }
```

Use it only in code you control. It works only with a personal API key: app (OAuth) connections and MCP always get a quote.

## Not enough credits [#not-enough-credits]

If the balance can't cover a request, the quote says so (`sufficient: false`) and confirming it fails with `402 insufficient_credits`. Add credits or change plan at [propertypixel.app/settings/billing](https://propertypixel.app/settings/billing). Inside ChatGPT, PropertyPixel only tells you to manage your plan at propertypixel.app.

## Trial accounts [#trial-accounts]

New accounts start with a free trial of 500 credits. Trial accounts can use every operation, but results carry a PropertyPixel watermark (`watermarked: true` on the quote and on each job), and some enhancement types need a paid plan. `GET /v1/account` shows the plan and whether results are watermarked.
