# Retrieve a swap

`GET /v1/swaps/:swapId`

Returns a swap that your app [created](/reference/swaps), with its current status and the transaction that ran each step. After the swap completes, it also gives what the account actually spent and received.

Circuitry checks the account's transactions on the swap's chain every 2 seconds while the quote is live. The swap's status changes even if you report nothing. To change it immediately, [report each transaction](/reference/swap-steps) when you send it.

## Request

```bash
curl https://api.circuitry.company/v1/swaps/k17aervc9b9sq4ja60esj941ps8gb1r2 \
  -H "Authorization: Bearer $CIRCUITRY_API_KEY"
```

## Response

The same object that [Create a swap](/reference/swaps#response) returns, with its status and steps kept current. A completed swap:

```json
{
  "id": "k17aervc9b9sq4ja60esj941ps8gb1r2",
  "object": "swap",
  "status": "completed",
  "createdAt": "2026-10-15T01:38:19.122Z",
  "expiresAt": "2026-10-15T01:39:19.053Z",
  "account": "0x1111111111111111111111111111111111111111",
  "chain": "base",
  "chainId": 8453,
  "input": {
    "asset": { "type": "fx", "currency": "USD", "token": { "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "symbol": "USDC", "name": "USD Coin", "decimals": 6 } },
    "amount": { "value": "20", "raw": "20000000" },
    "maximum": { "value": "20", "raw": "20000000" },
    "spent": { "value": "20", "raw": "20000000" }
  },
  "output": {
    "asset": { "type": "crypto", "symbol": "ETH", "token": { "address": null, "symbol": "ETH", "name": "Ether", "decimals": 18 } },
    "amount": { "value": "0.008265758119362246", "raw": "8265758119362246" },
    "minimum": { "value": "0.008224429328765434", "raw": "8224429328765434" },
    "received": { "value": "0.008266010447861539", "raw": "8266010447861539" }
  },
  "fees": [
    {
      "type": "network",
      "estimated": true,
      "amount": { "value": "0.00000148086", "raw": "1480860000000" }
    }
  ],
  "route": { "venues": ["uniswap"] },
  "warnings": [],
  "steps": [
    {
      "id": "approve",
      "kind": "transaction",
      "status": "confirmed",
      "transactionHash": "0x5c50…",
      "description": "Allow Permit2 to spend 20 USDC",
      "transaction": { "chainId": "0x2105", "from": "0x1111…", "to": "0x8335…", "data": "0x095ea7b3…", "value": "0x0", "gas": "0x13575" }
    },
    {
      "id": "permit2",
      "kind": "transaction",
      "status": "confirmed",
      "transactionHash": "0x9a1e…",
      "description": "Allow Uniswap's Universal Router to spend 20 USDC through Permit2",
      "transaction": { "chainId": "0x2105", "from": "0x1111…", "to": "0x0000…", "data": "0x87517c45…", "value": "0x0", "gas": "0x10f6f" }
    },
    {
      "id": "swap",
      "kind": "transaction",
      "status": "confirmed",
      "transactionHash": "0x3f07…",
      "description": "Swap 20 USDC for at least 0.008224429328765434 ETH",
      "transaction": { "chainId": "0x2105", "from": "0x1111…", "to": "0xd614…", "data": "0x3593564c…", "value": "0x0", "gas": "0x2e56b" }
    }
  ]
}
```

These fields change after Circuitry creates the swap:

| Field | Meaning |
| --- | --- |
| `status` | The swap's status. See [Statuses](#statuses) |
| `input.spent` | What the account actually spent. Only on a completed swap |
| `output.received` | What the account actually received. Only on a completed swap. A fill better than the quote shows here |
| `steps[].status` | The step's status. See [Step statuses](#step-statuses) |
| `steps[].transactionHash` | The transaction that ran the step, once Circuitry knows it |

`fees` keeps the estimate from when Circuitry created the swap.

### Statuses

| Status | Meaning |
| --- | --- |
| `quoted` | Circuitry knows of no transaction for the swap |
| `pending` | You reported a transaction for a step, or Circuitry found one, and the swap step didn't run yet |
| `completed` | The swap step ran, and `input.spent` and `output.received` give the actual amounts |
| `failed` | A transaction for a step reverted. If another transaction runs the swap step before `expiresAt`, the swap still completes |
| `expired` | The quote expired, and the swap step never ran. Approvals that ran stay on the chain, each for at most `input.maximum` |

Circuitry stops its checks of the chain 15 seconds after `expiresAt`. A transaction that you report after that still updates the swap. For example, a swap transaction sent after `expiresAt` reverts. A report of that transaction changes an `expired` swap to `failed`.

Circuitry deletes a swap 30 days after it expires, if its swap step never ran. After that, this endpoint returns `swap_not_found` for it.

### Step statuses

| Status | Meaning |
| --- | --- |
| `ready` | Circuitry knows of no transaction for the step |
| `submitted` | You reported a transaction that isn't in a block yet. Circuitry checks it when it is |
| `confirmed` | The step's transaction succeeded |
| `failed` | The step's transaction reverted |

Circuitry drops a submitted transaction that doesn't run the step, or that isn't in a block when the quote expires. Its step becomes `ready` again.

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| 404 | `swap_not_found` | No swap with this ID belongs to the API key's app |

This endpoint can also return the errors in [Failed authentication](/authentication#failed-authentication), `rate_limited`, and `internal_error`.
