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

# Get Redemption

> Fetches a single redemption by ID. Returns 404 while the redemption is at the internal quoted state.

## Overview

Returns the redemption record for a given `redemption_id`. Partner-scoped.

<Note>
  While the redemption is still at the internal `quoted` status (i.e., before the user's transaction has been confirmed on-chain and picked up by the indexer), this endpoint returns `404 redemption_not_found`. The record becomes visible once status advances to `submitted`.
</Note>

## Headers

<ParamField header="x-api-key" type="string" required>
  A valid `PARTNER` scope key.
</ParamField>

## Path Parameters

<ParamField path="id" type="string" required>
  Redemption identifier (prefixed `red_`).
</ParamField>

## Response

<ResponseField name="redemption_id" type="string">
  Redemption identifier.
</ResponseField>

<ResponseField name="status" type="string">
  Current status. One of: `submitted`, `preparing`, `ready`, `collected`, `cancellation_requested`, `cancelled`, `failed`.
</ResponseField>

<ResponseField name="denomination" type="string">
  Denomination label, e.g., `"1 Tola"`.
</ResponseField>

<ResponseField name="weight_g" type="number">
  Weight of the denomination in grams.
</ResponseField>

<ResponseField name="city" type="string">
  City of pickup.
</ResponseField>

<ResponseField name="quote" type="object">
  <Expandable title="properties">
    <ResponseField name="spot_price_usd" type="number">Gold spot price at quote time.</ResponseField>
    <ResponseField name="gold_value_usd" type="number">USD value of the gold at spot.</ResponseField>
    <ResponseField name="fee_usd" type="number">Partner redemption fee in USD.</ResponseField>
    <ResponseField name="total_usd" type="number">`gold_value_usd + fee_usd`.</ResponseField>
    <ResponseField name="tokens_required" type="string">`$GOLD` tokens required, formatted to 6 decimal places.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="submitted_tx_hash" type="string | null">
  Solana transaction signature (base58) of the on-chain GOLD transfer, or `null`.
</ResponseField>

<ResponseField name="cancellation_reason" type="string | null">
  If the redemption was cancelled, the reason supplied at cancel time; otherwise `null`.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO-8601 timestamp of row creation.
</ResponseField>

<ResponseField name="updated_at" type="string">
  ISO-8601 timestamp of most recent status update.
</ResponseField>

## Status lifecycle

```
quoted (internal)
  └─► submitted  ← indexer writes after on-chain confirmation
        ├─► preparing ── ready ── collected  (ORO admin advances)
        └─► cancellation_requested ── cancelled
```

`quoted` is never exposed. `collected` and `cancelled` are terminal.

## Errors

| HTTP | `error`                | When                                                 |
| ---- | ---------------------- | ---------------------------------------------------- |
| 401  | `unauthorized`         | Missing or invalid `x-api-key`                       |
| 403  | `partner_mismatch`     | Redemption belongs to a different partner            |
| 404  | `redemption_not_found` | No redemption row at or past `submitted` for this id |

<RequestExample>
  ```bash cURL theme={null}
  curl https://grail-stack-dev.onrender.com/v1/redemptions/red_a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d \
    -H "x-api-key: grail_partner_<hex>"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "redemption_id": "red_a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
    "status": "submitted",
    "denomination": "1 Tola",
    "weight_g": 11.664,
    "city": "karachi",
    "quote": {
      "spot_price_usd": 4872.84,
      "gold_value_usd": 1827.34,
      "fee_usd": 0,
      "total_usd": 1827.34,
      "tokens_required": "0.375006"
    },
    "submitted_tx_hash": "4ABC...base58",
    "cancellation_reason": null,
    "created_at": "2026-04-17T11:00:00.000Z",
    "updated_at": "2026-04-17T11:00:15.000Z"
  }
  ```
</ResponseExample>
