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

# Swap lifecycle

> Understand the statuses a swap goes through from creation to completion or refund, and how to handle each one.

A swap progresses through a fixed set of statuses.

```mermaid theme={null}
%%{init: {'theme': 'base', 'themeVariables': {'background': 'transparent', 'lineColor': '#94a3b8', 'fontSize': '14px', 'edgeLabelBackground': 'transparent', 'tertiaryTextColor': '#ffffff'}}}%%
flowchart TB
    created([Swap created]) --> userPending([user_transfer_pending])
    userPending --> depositConfirmed([Deposit confirmed]) --> layerswapPending([ls_transfer_pending])
    userPending --> noDeposit([No deposit in 6h]) --> expired([expired])
    layerswapPending --> success([Success]) --> completed([completed])
    layerswapPending --> belowMinimum([Below minimum]) --> failed([failed])
    layerswapPending --> executionFailed([Execution failed]) --> hasRefundAddress{refund_address?}
    hasRefundAddress -->|Yes| pendingRefund([pending_refund])
    hasRefundAddress -.->|No| retries([Retries])
    retries -.-> layerswapPending
    pendingRefund --> confirmed([Confirmed on-chain]) --> refunded([refunded])

    classDef event fill:transparent,color:#cbd5e1,stroke:#334155,stroke-width:1px
    classDef active fill:#0891b2,color:#ffffff,stroke:#0891b2
    classDef processing fill:#ca8a04,color:#ffffff,stroke:#ca8a04
    classDef successState fill:#16a34a,color:#ffffff,stroke:#16a34a
    classDef failureState fill:#dc2626,color:#ffffff,stroke:#dc2626
    classDef refundState fill:#9333ea,color:#ffffff,stroke:#9333ea
    classDef neutralState fill:#6b7280,color:#ffffff,stroke:#6b7280
    classDef decision fill:#475569,color:#ffffff,stroke:#475569

    class created,depositConfirmed,noDeposit,success,belowMinimum,executionFailed,confirmed event
    class userPending active
    class layerswapPending processing
    class completed successState
    class failed failureState
    class pendingRefund,refunded refundState
    class expired,retries neutralState
    class hasRefundAddress decision
```

## Flow

### 1. `user_transfer_pending`

Swap is created. Layerswap is waiting for the user to complete the transaction in the source network.

* If no deposit arrives within **6 hours** → `expired`
* Once the deposit is confirmed with enough confirmations → `ls_transfer_pending`

### 2. `ls_transfer_pending`

Layerswap is processing the swap. If something goes wrong during execution:

* If deposited amount is **below the minimum** → `failed`
* If the swap cannot be completed for any other reason (e.g. price moved beyond slippage tolerance) → Layerswap **retries automatically**.
  * **With `refund_address`** → if retries are exhausted, moves to `pending_refund`
  * **Without `refund_address`** → Layerswap keeps retrying. The swap remains in `ls_transfer_pending` until resolved.
* If execution succeeds → `completed`

### 3. `completed`

Funds are delivered to the destination address.

### 4. `pending_refund` → `refunded`

Refund is sent to `refund_address` on the source chain in the source token, **minus gas fees**. If the refund amount is less than the gas fee, no refund is issued. See [Refunds](/concepts/refunds) for details.

## What can go wrong

| Scenario                                         | With refund\_address   | Without refund\_address |
| ------------------------------------------------ | ---------------------- | ----------------------- |
| Deposited less than minimum                      | failed                 | failed                  |
| No liquidity or route available across providers | Retries, then refunded | Retries                 |
| Slippage tolerance cannot be met                 | Retries, then refunded | Retries                 |
| Blockchain issue across multiple RPCs            | Retries, then refunded | Retries                 |
| DEX or DEX aggregator issue                      | Retries, then refunded | Retries                 |

## Transaction-level detail

A swap can include multiple transactions, such as the deposit, payout, refuel, or refund. Each transaction has its own `type` and `status`. Use the transaction status to track that specific on-chain operation, use the swap-level `status` to track the overall swap lifecycle.

## Filtering swaps by status

Status names used in API responses are different from those accepted by the `GET /swaps` filter. For example, a swap response uses `pending_refund`, while the corresponding filter value is `PendingRefund`.

See [Track swaps](/api/track-swaps) for the complete list of filter values.

## Observing status changes

* **API**: poll [`GET /swaps/{id}`](/api-reference/swaps/get-swap-details), or look up by funding transaction with [`GET /swaps/by_transaction_hash/{hash}`](/api-reference/swaps/get-swap-by-transaction-hash).
* **Webhooks**: receive dashboard-configured status updates — [Webhooks](/api/webhooks).
* **Widget**: use [`onSwapStatusChange`](/widget/events/on-swap-status-change) to receive `{type, swapId, path?}`.

## Next

[Build your first API swap](/api/quickstart) applies this lifecycle end to end. [Refunds](/concepts/refunds) explains refund handling, addresses, fees, and transaction data. [Track swaps](/api/track-swaps) covers polling, filters, and transaction-hash lookup.
