> For the complete documentation index, see [llms.txt](https://docs.swapkit.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.swapkit.dev/get-started/quickstart.md).

# Quickstart: your first swap

Go from zero to a tracked cross-chain swap: get an API key, request a quote, build the transaction, sign it, and track it to completion.

This walks through one complete swap, selling ETH on Ethereum for BTC, using plain HTTP. Every SwapKit swap follows the same four calls: **quote → swap → sign and broadcast → track**. Once this works, every other pair and chain is a change of parameters.

SwapKit is non-custodial: the API builds transactions, but your user signs and broadcasts them with their own wallet. SwapKit never holds keys or funds.

### 1. Get an API key

1. Sign in to the [SwapKit dashboard](https://dashboard.swapkit.dev/).
2. Click **Create app**.
3. Open the app and copy its **API Key**.

Send it in the `x-api-key` header on every request. A new key allows 10 requests per minute on each service and trades of up to $1,000; both can be raised. See [Authentication and API keys](/get-started/authentication-and-api-keys.md).

```bash
export SWAPKIT_API_KEY="YOUR_API_KEY"
```

### 2. Request a quote

[`/v3/quote`](/api-reference/v3-quote-request-a-swap-quote.md) prices the swap across every provider. No addresses are needed yet.

```bash
curl -X POST "https://api.swapkit.dev/v3/quote" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $SWAPKIT_API_KEY" \
  -d '{
    "sellAsset": "ETH.ETH",
    "buyAsset": "BTC.BTC",
    "sellAmount": "0.05",
    "slippage": 3
  }'
```

Assets are identified as `CHAIN.TICKER`, or `CHAIN.TICKER-contractAddress` for tokens, for example `ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`. Look identifiers up with [`/tokens`](/api-reference/tokens-list-and-search-supported-tokens.md). `sellAmount` is in whole units, so `"0.05"` is 0.05 ETH.

The response holds one entry in `routes` per provider that can fill the trade. The fields you need first:

| Field                        | Use                                                            |
| ---------------------------- | -------------------------------------------------------------- |
| `routes[].routeId`           | Identifies the route. You pass it to `/v3/swap`.               |
| `routes[].expectedBuyAmount` | What the user should receive, to show them before they commit. |
| `routes[].meta.tags`         | `RECOMMENDED`, `FASTEST` or `CHEAPEST`, to help pick a route.  |
| `routes[].providers`         | Which provider or providers execute the route.                 |

To list routes side by side:

```bash
curl -s -X POST "https://api.swapkit.dev/v3/quote" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $SWAPKIT_API_KEY" \
  -d '{"sellAsset":"ETH.ETH","buyAsset":"BTC.BTC","sellAmount":"0.05","slippage":3}' \
  | jq '.routes[] | {routeId, providers, expectedBuyAmount, tags: .meta.tags}'
```

A quote is valid for 5 minutes.

### 3. Build the transaction

When the user accepts a route, call [`/v3/swap`](/api-reference/v3-swap-obtain-swap-transaction-details.md) with its `routeId` and the user's addresses: `sourceAddress` on the sell chain (Ethereum) and `destinationAddress` on the buy chain (Bitcoin).

```bash
curl -X POST "https://api.swapkit.dev/v3/swap" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $SWAPKIT_API_KEY" \
  -d '{
    "routeId": "ROUTE_ID_FROM_STEP_2",
    "sourceAddress": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "destinationAddress": "357a3So9CbsNfBBgFYACGvxxS6tMaDoa1P"
  }'
```

SwapKit checks that `sourceAddress` holds enough to cover `sellAmount`, screens both addresses, and returns the route with a ready-to-sign transaction:

* `tx` is the transaction to sign. Its format depends on the sell chain.
* `meta.txType` names that format, here `EVM`.
* `targetAddress` is where the funds go: a deposit address or a contract.

Use an address you control with real funds. An unfunded `sourceAddress` returns `insufficientBalance`.

### 4. Sign and broadcast

Sign `tx` with the user's wallet and broadcast it like any other transaction on that chain. For an `EVM` route, `tx` carries `to`, `from`, `data`, `value`, `gas` and `gasPrice` as hex strings. With [viem](https://viem.sh):

```ts
const hash = await walletClient.sendTransaction({
  to: tx.to,
  data: tx.data,
  value: BigInt(tx.value),
  gas: BigInt(tx.gas),
  gasPrice: BigInt(tx.gasPrice),
});
```

Each chain returns its own format, such as a PSBT for Bitcoin or a serialized transaction for Solana. [Transaction Formats by txType](/api-reference/transaction-formats-by-txtype.md) shows an example response for each one.

### 5. Track the swap

Pass the transaction hash and the sell chain's ID to [`/track`](/api-reference/track-request-the-status-of-a-swap.md). Ethereum is `"1"`; the other chain IDs are in the [`/providers` page](/api-reference/providers-providers-status-and-identifiers-mapping.md#chain-ids-and-corresponding-names).

```bash
curl -X POST "https://api.swapkit.dev/track" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $SWAPKIT_API_KEY" \
  -d '{
    "hash": "0xYOUR_TRANSACTION_HASH",
    "chainId": "1",
    "routeId": "ROUTE_ID_FROM_STEP_2"
  }'
```

Poll `status` until it reads `completed`, `refunded` or `failed`. Users can follow the same swap at `https://track.swapkit.dev/?hash=0xYOUR_TRANSACTION_HASH`.

### Next steps

* [How a swap works](/get-started/quote-and-swap-implementation-flow.md): the full flow, the errors to handle at each step, and rate limits.
* [Monetization](/get-started/monetization.md): set an affiliate fee and earn on every swap.
* [SwapKit Widget](/swapkit-widget/introduction.md): a drop-in swap UI if you don't want to build one.
* [Using these docs with AI agents](/get-started/using-these-docs-with-ai-agents.md): `llms.txt`, Markdown pages, the docs MCP server and the OpenAPI spec.
