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

# GET /status

> Normalized swap status.

Poll the progress of a swap. The `ref` depends on the execution type:

| Execution type | `ref` |
| - | - |
| `DEPOSIT` | The `statusRef` returned by [`/execute`](/api-reference/execute) |
| `SIGNATURE` | The `statusRef` returned by [`/submit-signature`](/api-reference/submit-signature) |
| `TRANSACTION` | The `statusRef` returned by [`/execute`](/api-reference/execute) when present, otherwise the hash of the transaction you broadcast |

Available as `GET` with query parameters or `POST` with the same two fields in a JSON body.
Prefer `POST`: a large `quoteToken` in a query string can exceed header limits and fail with
`431`.

## Request

<ParamField query="quoteToken" type="string" required>The `quoteToken` returned by [`/execute`](/api-reference/execute), not the one from `/quote`.</ParamField>
<ParamField query="ref" type="string" required>The `statusRef` or transaction hash for this swap.</ParamField>

No API key required (see [Authentication](/authentication) for the optional higher-limit tiers).

```bash theme={null}
curl -s -X POST https://app.ravn.exchange/api/v1/status \
  -H 'content-type: application/json' \
  -d '{ "quoteToken": "<from /execute>", "ref": "<statusRef or tx hash>" }'
```

## Response

<ResponseField name="status" type="string">The normalized lifecycle state.</ResponseField>
<ResponseField name="venue" type="string">The venue handling the swap.</ResponseField>
<ResponseField name="venueStatus" type="string">The raw, venue-native status string behind the normalized `status`, for debugging. Present once a venue has been polled.</ResponseField>
<ResponseField name="tracking" type="string">Present as `"unavailable"` only when the venue is not yet wired for tracking (`status` is `unknown`). Absent otherwise.</ResponseField>
<ResponseField name="deliveredAmount" type="string">The actual delivered output, in the output token's smallest unit, when the venue exposes it. Null or absent otherwise, this is best-effort per venue, not every venue reports it.</ResponseField>
<ResponseField name="txHash" type="string">The destination-chain transaction that paid the user out, when the venue names one. Only populated once `status` is terminal, not while a swap is still in flight.</ResponseField>

| `status` | Meaning |
| - | - |
| `pending` | Awaiting the deposit, or not yet observed |
| `processing` | Funds received, solver filling |
| `success` | Delivered |
| `expired` | The fill deadline passed without a fill; a refund is due but has not yet been issued |
| `refunded` | Returned to sender |
| `failed` | Terminal failure |
| `not_found` | The `ref` is unknown to the venue |
| `unknown` | The venue is not yet wired for tracking |

```json theme={null}
{ "data": { "status": "processing", "venue": "near_intents" } }
```

Once terminal, a venue that reports it adds the delivery fields:

```json theme={null}
{
  "data": {
    "status": "success",
    "venue": "near_intents",
    "deliveredAmount": "18921340",
    "txHash": "0x9f2c...b71a"
  }
}
```

<Note>
  Status tracking is live for every venue on [`/health`](/api-reference/health). Cross-chain and
  orderbook venues (CoW, 0x Gasless, Bebop, NEAR Intents, Relay, Across, Mayan, Eco Routes,
  Chainflip, THORChain, Layerswap, Rift, Houdini Swap) are resolved against the venue's own
  tracker. Same-chain venues (0x Swap, 0x Solana, Nordstern, Fly Trade, KyberSwap, OKX DEX, Jupiter, Mayan
  same-chain) are resolved
  against the chain itself, see below.
</Note>

<Note>
  If `quoteToken` came from a [sandbox](/sandbox-mode) quote, this always returns an immediate
  synthetic `success` with the quoted output as `deliveredAmount`. `ref` isn't validated in that
  case, so any placeholder string works. Sandbox swaps are never metered and never earn a payout.
</Note>

## Settlement

Polling this endpoint is not just for your UI. It is how a swap reaches `settled` in RAVN's
ledger, and `settled` is the only state a fee payout is ever made on (see
[Pricing](/pricing#getting-paid)).

RAVN runs a server-side backstop every few minutes, but it can only resolve swaps whose `ref`
RAVN already knew at `/execute` time: a NEAR Intents deposit address, a Relay request, a
Chainflip deposit channel, a Rift or Houdini Swap order. **For every other venue, your terminal poll is what settles the
swap.** That covers every `TRANSACTION` swap without a `statusRef`: the origin hash only exists once you broadcast
it, and RAVN only learns it when you report it here. On a same-chain venue (0x Swap, 0x Solana, Nordstern,
Fly Trade, KyberSwap, OKX DEX, Jupiter, Mayan same-chain) that transaction *is* the settlement, so RAVN
checks the chain, not your word, before marking the swap settled:

1. the transaction at `ref` is mined on the quote's chain and did not revert;
2. it moved the quote's full input amount of the quote's input token;
3. when the quote carried a fee in an ERC-20, that fee actually arrived in a RAVN fee recipient.
   The on-chain amount is what gets booked, not the quote-time estimate.

Anything short of that leaves the swap non-terminal and nothing is owed. **A same-chain swap
you never report via this endpoint never becomes payable**, so call it once for every
`TRANSACTION` swap after the hash confirms, even if your integration has no other use for the
answer. `executeAndTrack` in the [JS SDK](/sdks/core#executeandtrack) already does this.

Two more rules that follow from the same design:

* One `ref` settles exactly one swap. A hash or deposit that already settled another quote is
  rejected, and a `ref` that `/execute` already pinned to a swap (a deposit address, an order
  id) can't be swapped for a different one.
* A swap belongs to the key that requested the quote. That identity is signed into the
  `quoteToken`, so `/execute` and `/status` credit it to you even when the process calling them
  doesn't hold your key. A second report on an already-terminal swap is a no-op.

<Warning>
  **Keep polling on `expired`.** It is **not** a terminal state. It means the deal lapsed and a
  refund is owed but has not landed yet. On Across, the deposit is returned to the sender on the
  origin chain in a later settlement bundle, which per Across's own docs can take several hours,
  at which point the status becomes `refunded`. Treat only `success`, `refunded`, and `failed` as
  terminal; stopping at `expired` will miss the refund.
</Warning>


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