> ## Documentation Index
> Fetch the complete documentation index at: https://docs.collectpure.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Execution v3

> Quote a sale, then execute it by quote id

Execution v3 sells into offers in two calls: create a quote, then execute it by its `quoteId`. The quote holds the price for **60 seconds**, so execute sends no body.

> [!NOTE]
>
> Both routes require an **Admin** API key (`stytch_admin`). See [Authentication](https://docs.collectpure.com/api-reference/authentication.md).

> [!TIP]
>
> Build against sandbox first: `https://sandbox.api.collectpure.com` with a sandbox API key. Sandbox orders are not real.

## How it works

```mermaid theme={null}
sequenceDiagram
    participant You
    participant API as Pure API

    You->>API: POST /execution/v3/sell/quotes
    API-->>You: quoteId, payout, expiresAt (60s)

    You->>API: POST /execution/v3/sell/quotes/{quoteId}/execute
    API->>API: Re-price, then check the quoted payout
    API-->>You: orderId, or 409 requote
```

1. `POST /execution/v3/sell/quotes` prices your items and returns a `quoteId`.
2. `POST /execution/v3/sell/quotes/{quoteId}/execute` places the sale at the quoted payout or better.
3. A quote executes once. After it executes, fails, or expires, create a new quote.

## Quote

```bash theme={null}
curl -X POST https://api.collectpure.com/execution/v3/sell/quotes \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [{ "offerId": "OFFER_UUID", "quantity": 1 }],
    "optionals": ["overnight_label"]
  }'
```

```json theme={null}
{
  "quoteId": "2f1d48ff-1903-4531-9e28-4557ba549370",
  "expiresAt": "2026-11-05T00:35:49.457Z",
  "payout": 3257,
  "items": [
    {
      "offerId": "OFFER_UUID",
      "productId": "PRODUCT_UUID",
      "variantId": "VARIANT_UUID",
      "quantity": 1,
      "unitPrice": 3278
    }
  ],
  "breakdown": {
    "subtotal": 3278,
    "fees": [{ "label": "Processing fee", "amount": -21 }],
    "promotions": []
  },
  "optionals": [],
  "issues": []
}
```

Amounts are in **cents**. `payout` is what you are paid. `issues` lists what blocks execute or what the quote left out. Field details: [Sell](https://docs.collectpure.com/execution-v3/sell.md).

## Execute

```bash theme={null}
curl -X POST https://api.collectpure.com/execution/v3/sell/quotes/QUOTE_ID/execute \
  -H "x-api-key: YOUR_API_KEY"
```

```json theme={null}
{
  "status": "placed",
  "orderId": 989,
  "counterpartyOrderIds": [978],
  "payout": 4066
}
```

`orderId` is a **purchase order**, because Pure is buying from you. Fetch it at `GET /orders/get-purchase-order/v1?id={orderId}`.

## Retries

Execute is idempotent by quote id. A repeated execute returns the first response, so retrying never places a second order.

A quote places at most one order. Executing it again, even with a new `Idempotency-Key`, returns that order. Details: [Errors and retries](https://docs.collectpure.com/execution-v3/errors.md).

## Changes from v2

| v2 | v3 |
| - | - |
| Execute sends `expectedTotal` and `expectedOptionalFees` | Execute sends nothing; the quote holds both |
| Optionals by `selectedOptionalIds` | Optionals by `optionals` on the quote |
| `promotionCode` on execute | `promotionCode` on the quote |
| `adjustListings` / `confirmListingMismatch` | Not needed; execute does not check your listings |
| Many `errorCode` values | Four `errorCode` values; the cause is in `details.reason` |

## Endpoints

| Method | Path | Role |
| - | - | - |
| `POST` | `/execution/v3/sell/quotes` | `stytch_admin` |
| `POST` | `/execution/v3/sell/quotes/{quoteId}/execute` | `stytch_admin` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.