<!-- tempo-docs-context -->
> Source: [/docs/routes/transfers](https://tempo.xyz/developers/docs/routes/transfers.md)
> Section: [Routes](https://tempo.xyz/developers/docs/routes.md). Move stablecoins between Tempo and other networks: try a route, set up API access, choose a supported route, quote it, accept deposits or make a transfer, and track delivery. Routes is in beta; see the introduction for access.
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

# Make a transfer

Move stablecoins between networks when your application can sign the source transaction through a wallet or its own signer.

[Tempo Routes](https://tempo.xyz/developers/docs/routes) moves stablecoins between Tempo and supported networks. A route connects a source network and token to a destination network and token. For a transfer, Routes prepares the source-chain calls that send the funds; your application signs them and tracks delivery.

<span id="set-up-routes-api-access" />

## Prepare a transfer route

Before you start, have:

* A Tempo API key on your backend, created in [Set up API access](https://tempo.xyz/developers/docs/routes/api-setup). `routes:read` covers quotes and status reads; `routes:write` covers creating transfers and registering source transactions.
* A route with transfer support from [Supported routes](https://tempo.xyz/developers/docs/routes/networks). This guide sets the quote's `mode` to `exactSource`, which fixes the amount sent; `exactDestination` fixes the amount received instead ([Quotes and fees](https://tempo.xyz/developers/docs/routes/quotes#choose-which-amount-to-fix)). Check that the route lists `exactSource`.
* A signer for the sender account on the source network, such as a connected wallet or your own signing service. The API key doesn't sign transactions.

Each step in the transfer flow has a request builder that generates cURL and TypeScript. To see the flow first, [try a route](https://tempo.xyz/developers/docs/routes/test). The [cURL example](https://tempo.xyz/developers/docs/routes/examples/transfers) runs every step from a terminal.

<span id="submit-and-track-a-transfer" />

## Transfer funds

:::steps
### Get a quote

<span id="quote-the-transfer" />

`GET /v1/routes/transfers/quote`

Quote transfer

[API reference](https://tempo.xyz/developers/docs/api/routes/transfers#quoteroutestransfer) — request parameters, authentication, and response schema. The examples below use editable sample values.

Requires a [Tempo API key](https://tempo.xyz/developers/docs/api/console/api-keys). Replace `YOUR_API_KEY` before running this request.

**cURL**

```bash
curl 'https://api.tempo.xyz/v1/routes/transfers/quote?amount=1000000&destinationChain=base&destinationToken=usdc&mode=exactSource&recipient=0x1111111111111111111111111111111111111111&sender=0x2222222222222222222222222222222222222222&sourceChain=tempo&sourceToken=usdce' \
  --header 'tempo-api-key: YOUR_API_KEY'
```

**TypeScript**

```ts
fetch('https://api.tempo.xyz/v1/routes/transfers/quote?amount=1000000&destinationChain=base&destinationToken=usdc&mode=exactSource&recipient=0x1111111111111111111111111111111111111111&sender=0x2222222222222222222222222222222222222222&sourceChain=tempo&sourceToken=usdce', {
  headers: {
    'tempo-api-key': 'YOUR_API_KEY'
  }
})
```

<span id="review-fees" />

Show the source amount, destination amount, minimum destination amount, and fees as described in [Quotes and fees](https://tempo.xyz/developers/docs/routes/quotes). The minimum destination amount is what a transfer created now guarantees the recipient. Request a new quote when the response's `quote.expiresAt` time passes.

### Create the transfer

Send an [idempotency key](https://tempo.xyz/developers/docs/routes/api-setup#set-idempotency-keys) in the `idempotency-key` header. Create one key for this payment and store it with the payment record before the request, so a retry returns the same transfer instead of creating another.

`POST /v1/routes/transfers`

Create transfer

[API reference](https://tempo.xyz/developers/docs/api/routes/transfers#createroutestransfer) — request parameters, authentication, and response schema. The examples below use editable sample values.

Requires a [Tempo API key](https://tempo.xyz/developers/docs/api/console/api-keys). Replace `YOUR_API_KEY` before running this request.

**cURL**

```bash
curl https://api.tempo.xyz/v1/routes/transfers \
  --request POST \
  --header 'idempotency-key: routes_01k1c5j8q8p0be6j5v9m6d1e4r' \
  --header 'tempo-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "amount": "1000000",
  "destinationToken": "usdc",
  "mode": "exactSource",
  "recipient": "0x1111111111111111111111111111111111111111",
  "sender": "0x2222222222222222222222222222222222222222",
  "sourceToken": "usdce"
}'
```

**TypeScript**

```ts
fetch('https://api.tempo.xyz/v1/routes/transfers', {
  method: 'POST',
  headers: {
    'idempotency-key': 'routes_01k1c5j8q8p0be6j5v9m6d1e4r',
    'tempo-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: '1000000',
    destinationToken: 'usdc',
    mode: 'exactSource',
    recipient: '0x1111111111111111111111111111111111111111',
    sender: '0x2222222222222222222222222222222222222222',
    sourceToken: 'usdce'
  })
})
```

Save the returned transfer `id` (`rtr_…`) and keep its `action`, the unsigned source-chain calls the sender signs. Review the returned terms before requesting a signature. Only this create response includes `action`; later transfer reads don't return it.

<span id="sign-and-submit-the-source-calls" />

### Sign and submit

Use the source account's signer to submit the calls in `action` in order. Calls can include token approvals, and each call can be its own transaction. `action.type` names the call format, such as `evm:calls`. Handle it using the [EVM or Tron action format](https://tempo.xyz/developers/docs/api/routes/transfers).

For an `evm:calls` action, pass each call's `to`, `data`, and `value` to your source-chain wallet client. Wait for successful execution before the next call, and retain all hashes as `transactionHashes`. If submission stops partway through, inspect the transactions already sent before resuming.

When the source network is Tempo, [Tempo Wallet](https://tempo.xyz/developers/docs/accounts/wallets#connect-tempo-wallet) instead submits every call as one atomic transaction, so the sender signs once. [Try a route](https://tempo.xyz/developers/docs/routes/test) to compare one-call-at-a-time and atomic submission.

### Register the source transactions

Send the transfer `id` from creation, and the hashes your signer produced in the request body's `transactionHashes` array (up to 10). For a single source transaction, send the `transactionHash` string field instead.

`POST /v1/routes/transfers/{id}/source-transactions`

Register source transaction

[API reference](https://tempo.xyz/developers/docs/api/routes/transfers#registerroutestransfersourcetransaction) — request parameters, authentication, and response schema. The examples below use editable sample values.

Requires a [Tempo API key](https://tempo.xyz/developers/docs/api/console/api-keys). Replace `YOUR_API_KEY` before running this request.

**cURL**

```bash
curl https://api.tempo.xyz/v1/routes/transfers/rtr_001785729600000_2ZPE2gvateYEQ0dQslgvkhjx/source-transactions \
  --request POST \
  --header 'tempo-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "transactionHash": "0x5151515151515151515151515151515151515151515151515151515151515151"
}'
```

**TypeScript**

```ts
fetch('https://api.tempo.xyz/v1/routes/transfers/rtr_001785729600000_2ZPE2gvateYEQ0dQslgvkhjx/source-transactions', {
  method: 'POST',
  headers: {
    'tempo-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    transactionHash: '0x5151515151515151515151515151515151515151515151515151515151515151'
  })
})
```

The API verifies the transactions onchain and links them to the transfer. Until you register them, the transfer stays in `awaiting-source`.

<span id="track-destination-delivery" />

### Confirm the transfer

`GET /v1/routes/transfers/{id}`

Get transfer

[API reference](https://tempo.xyz/developers/docs/api/routes/transfers#getroutestransfer) — request parameters, authentication, and response schema. The examples below use editable sample values.

Requires a [Tempo API key](https://tempo.xyz/developers/docs/api/console/api-keys). Replace `YOUR_API_KEY` before running this request.

**cURL**

```bash
curl https://api.tempo.xyz/v1/routes/transfers/rtr_001785729600000_2ZPE2gvateYEQ0dQslgvkhjx \
  --header 'tempo-api-key: YOUR_API_KEY'
```

**TypeScript**

```ts
fetch('https://api.tempo.xyz/v1/routes/transfers/rtr_001785729600000_2ZPE2gvateYEQ0dQslgvkhjx', {
  headers: {
    'tempo-api-key': 'YOUR_API_KEY'
  }
})
```

Keep the payment pending until `status` is `completed`. Other statuses are `awaiting-source`, `processing`, `action-required`, `expired`, `refunding`, and `refunded`. Once completed, reconcile `destinationAmount` and the destination transactions in `destinationTransactionHashes`.
:::

Continue with [Track delivery](https://tempo.xyz/developers/docs/routes/delivery) for every status, failures, and refunds.
