> ## 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.

# Errors and retries

> Four error kinds, their reasons, and idempotent execute

Every v3 failure has one of four `errorCode` values. Each says what to do next. The specific cause is in `details.reason`.

```json theme={null}
{
  "error": "Your payout changed. Please review the new quote.",
  "code": 409,
  "errorCode": "requote",
  "suggestion": "Create a new quote with POST /execution/v3/sell/quotes",
  "details": { "reason": "quote_total_mismatch", "runId": "2267c318-e8ac-40b4-b522-ae216141d95b" },
  "requestId": "58506219-5893-43d4-9948-324c3c0ce362"
}
```

Branch on `errorCode`. Show `error` to the seller. Send `requestId` to support.

## Kinds

| `errorCode` | Status | What to do |
| - | - | - |
| `requote` | **409** | Create a new quote |
| `account_action_required` | **403** | Fix the account, then create a new quote |
| `try_again` | **503** | Retry the same request with backoff |
| `invalid_request` | **400** | Fix the request |

`try_again` includes `details.retryAfterSeconds` when selling is closed.

## Reasons

| `details.reason` | Kind |
| - | - |
| `checkout_expired` | `requote` |
| `checkout_not_found` | `requote` |
| `checkout_empty` | `requote` |
| `listing_unavailable` | `requote` |
| `subtotal_mismatch` | `requote` |
| `quote_total_mismatch` | `requote` |
| `optional_fee_mismatch` | `requote` |
| `optional_not_eligible` | `requote` |
| `instant_payout_insufficient_credit` | `requote` |
| `promotion_code_invalid` | `requote` |
| `promotion_code_expired` | `requote` |
| `promotion_code_not_eligible` | `requote` |
| `promotion_code_exhausted` | `requote` |
| `referral_grant_consumed` | `requote` |
| `organization_not_found` | `account_action_required` |
| `selling_disabled` | `account_action_required` |
| `vacation_mode` | `account_action_required` |
| `account_not_approved` | `account_action_required` |
| `jurisdiction_blocked` | `account_action_required` |
| `address_required` | `account_action_required` |
| `payout_method_not_ready` | `account_action_required` |
| `sell_limit_exceeded` | `account_action_required` |
| `selling_closed` | `try_again` |
| `system_error` | `try_again` |
| `invalid_input` | `invalid_request` |

New reasons can be added; handle an unknown `reason` by its kind.

An unknown, expired, or already-executed quote returns **409** `requote` with no `reason`.

## Other errors

| `errorCode` | Status | Meaning |
| - | - | - |
| `validation_error` | **400** | The body, path, or a header failed validation |
| `request_in_progress` | **409** | The same execute is still running; retry after `retry-after` seconds |
| `idempotency_unavailable` | **503** | Retry with backoff |

## Idempotent execute

Execute is idempotent. Its key is the `Idempotency-Key` header, or the `quoteId` when the header is absent.

* A repeat with the same key within **24 hours** returns the first response, with the header `idempotent-replayed: true`.
* A repeat while the first is running returns **409** `request_in_progress`.
* Keys are scoped to the quote, so the same key on another quote is a separate request.
* A **5xx** response is not stored, so a retry runs again.
* Keys are 1 to 255 characters and scoped to your organization.

On a network error or timeout, retry execute with the same key. You get the order or the error from the first attempt.

After `try_again` from execute, retry the same execute. The quote stays valid until `expiresAt`.

Quote is not idempotent. Each call creates a new quote.


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