curl --request POST \
--url https://api.privy.io/v1/wallets/{wallet_id}/swap \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--header 'privy-app-id: <privy-app-id>' \
--data '
{
"base_amount": "1000000000000000000",
"amount_type": "exact_input",
"source": {
"asset_address": "native",
"caip2": "eip155:1"
},
"destination": {
"asset_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"caip2": "eip155:1"
},
"slippage_bps": 50
}
'HttpResponse<String> response = Unirest.post("https://api.privy.io/v1/wallets/{wallet_id}/swap")
.header("privy-app-id", "<privy-app-id>")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"base_amount\": \"1000000000000000000\",\n \"amount_type\": \"exact_input\",\n \"source\": {\n \"asset_address\": \"native\",\n \"caip2\": \"eip155:1\"\n },\n \"destination\": {\n \"asset_address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"caip2\": \"eip155:1\"\n },\n \"slippage_bps\": 50\n}")
.asString();const options = {
method: 'POST',
headers: {
'privy-app-id': '<privy-app-id>',
Authorization: 'Basic <encoded-value>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
base_amount: '1000000000000000000',
amount_type: 'exact_input',
source: {asset_address: 'native', caip2: 'eip155:1'},
destination: {asset_address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', caip2: 'eip155:1'},
slippage_bps: 50
})
};
fetch('https://api.privy.io/v1/wallets/{wallet_id}/swap', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.privy.io/v1/wallets/{wallet_id}/swap",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'base_amount' => '1000000000000000000',
'amount_type' => 'exact_input',
'source' => [
'asset_address' => 'native',
'caip2' => 'eip155:1'
],
'destination' => [
'asset_address' => '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
'caip2' => 'eip155:1'
],
'slippage_bps' => 50
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: application/json",
"privy-app-id: <privy-app-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.privy.io/v1/wallets/{wallet_id}/swap"
payload := strings.NewReader("{\n \"base_amount\": \"1000000000000000000\",\n \"amount_type\": \"exact_input\",\n \"source\": {\n \"asset_address\": \"native\",\n \"caip2\": \"eip155:1\"\n },\n \"destination\": {\n \"asset_address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"caip2\": \"eip155:1\"\n },\n \"slippage_bps\": 50\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("privy-app-id", "<privy-app-id>")
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "cm7oxq1el000e11o8iwp7d0d0",
"status": "pending",
"wallet_id": "fmfdj6yqly31huorjqzq38zc",
"caip2": "eip155:1",
"input_token": "native",
"output_token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"input_amount": "1000000000000000000"
}Swap tokens
Execute a token swap within a wallet.
curl --request POST \
--url https://api.privy.io/v1/wallets/{wallet_id}/swap \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--header 'privy-app-id: <privy-app-id>' \
--data '
{
"base_amount": "1000000000000000000",
"amount_type": "exact_input",
"source": {
"asset_address": "native",
"caip2": "eip155:1"
},
"destination": {
"asset_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"caip2": "eip155:1"
},
"slippage_bps": 50
}
'HttpResponse<String> response = Unirest.post("https://api.privy.io/v1/wallets/{wallet_id}/swap")
.header("privy-app-id", "<privy-app-id>")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"base_amount\": \"1000000000000000000\",\n \"amount_type\": \"exact_input\",\n \"source\": {\n \"asset_address\": \"native\",\n \"caip2\": \"eip155:1\"\n },\n \"destination\": {\n \"asset_address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"caip2\": \"eip155:1\"\n },\n \"slippage_bps\": 50\n}")
.asString();const options = {
method: 'POST',
headers: {
'privy-app-id': '<privy-app-id>',
Authorization: 'Basic <encoded-value>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
base_amount: '1000000000000000000',
amount_type: 'exact_input',
source: {asset_address: 'native', caip2: 'eip155:1'},
destination: {asset_address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', caip2: 'eip155:1'},
slippage_bps: 50
})
};
fetch('https://api.privy.io/v1/wallets/{wallet_id}/swap', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.privy.io/v1/wallets/{wallet_id}/swap",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'base_amount' => '1000000000000000000',
'amount_type' => 'exact_input',
'source' => [
'asset_address' => 'native',
'caip2' => 'eip155:1'
],
'destination' => [
'asset_address' => '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
'caip2' => 'eip155:1'
],
'slippage_bps' => 50
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: application/json",
"privy-app-id: <privy-app-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.privy.io/v1/wallets/{wallet_id}/swap"
payload := strings.NewReader("{\n \"base_amount\": \"1000000000000000000\",\n \"amount_type\": \"exact_input\",\n \"source\": {\n \"asset_address\": \"native\",\n \"caip2\": \"eip155:1\"\n },\n \"destination\": {\n \"asset_address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"caip2\": \"eip155:1\"\n },\n \"slippage_bps\": 50\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("privy-app-id", "<privy-app-id>")
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "cm7oxq1el000e11o8iwp7d0d0",
"status": "pending",
"wallet_id": "fmfdj6yqly31huorjqzq38zc",
"caip2": "eip155:1",
"input_token": "native",
"output_token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"input_amount": "1000000000000000000"
}Prerequisites
- Swaps must be enabled in the Privy Dashboard
- Gas sponsorship must be configured for your app
pending status and can be polled for confirmation.pending immediately. Replaying the same key
returns the cached response. On a synchronous 5xx, Privy deletes the record so the same key
retries fresh. Action outcomes (rejected, failed, succeeded) arrive via
webhooks and polling. Policy violations
always allow fresh retries.Authorizations
Basic Auth header with your app ID as the username and your app secret as the password.
Headers
ID of your Privy app.
Request authorization signature. If multiple signatures are required, they should be comma separated.
Request expiry. Value is a Unix timestamp in milliseconds representing the deadline by which the request must be processed.
Idempotency keys ensure API requests are executed only once within a 24-hour window.
Path Parameters
ID of the wallet.
Body
Input for executing a token swap.
Amount in base units (e.g., wei for ETH). Must be a non-negative integer string.
1 - 78^\d+$The input side of a swap request, including token and chain.
Show child attributes
Show child attributes
The output side of a swap execution request.
Show child attributes
Show child attributes
Unique caller-generated nonce used to prevent replaying a signed wallet action request. Must be at least 24 characters (e.g. a cuid2 or UUID).
24 - 255Whether the amount refers to the input token (exact_input) or output token (exact_output).
exact_input, exact_output Maximum slippage tolerance in basis points (e.g., 50 for 0.5%).
0 <= x <= 10000Optional fee configuration for cross-chain swaps. If omitted, cross-chain swaps only charge provider fees.
Show child attributes
Show child attributes
{ "type": "total_fee_bps", "value": 50 }
Developer-provided identifier for this request. Must be unique per app.
1 - 64Response
Swap initiated successfully.
Response for a swap action.
The ID of the wallet action.
The current status of the wallet action.
pending, succeeded, rejected, failed The ID of the wallet involved in the action.
ISO 8601 timestamp of when the wallet action was created.
swap CAIP-2 chain identifier for the swap.
Token address or "native" for the token being sold.
Token address or "native" for the token being bought.
Exact base-unit amount of input token. Populated after on-chain confirmation.
Exact base-unit amount of output token. Populated after on-chain confirmation.
Developer-provided reference ID, if one was included in the request.
Top-level failure context for the wallet action. Present on rejected or failed actions when available.
Show child attributes
Show child attributes
The steps of the wallet action. Only returned if ?include=steps is provided.
A wallet action step consisting of an EVM transaction.
- EVMTransactionWalletActionStep
- EVMUserOperationWalletActionStep
- SVMTransactionWalletActionStep
- TVMTransactionWalletActionStep
- ExternalTransactionWalletActionStep
- CustodianTransactionWalletActionStep
Show child attributes
Show child attributes
Destination chain CAIP-2 identifier. Present for cross-chain swaps.
Recipient address for the swap. Present for newly created swaps; may be absent for older swap actions.
Estimated fee breakdown from the provider quote. Only present for cross-chain swaps. Populated after on-chain confirmation.
Estimated fee paid to the relayer.
- RelayerFee
- PrivyFee
- DeveloperFee
Show child attributes
Show child attributes
{
"type": "privy",
"recipient": "0x1234567890abcdef1234567890abcdef12345678",
"amount": "0.20"
}
Estimated source-chain gas cost from the provider quote. Only present for cross-chain swaps. Populated after on-chain confirmation.
Show child attributes
Show child attributes
{
"base_amount": "100000000000000",
"amount": "0.0001",
"gas_asset": "ETH"
}
Actual fees paid for the swap. Populated after on-chain confirmation. Only present for cross-chain swaps.
Estimated fee paid to the relayer.
- RelayerFee
- PrivyFee
- DeveloperFee
Show child attributes
Show child attributes
{
"type": "privy",
"recipient": "0x1234567890abcdef1234567890abcdef12345678",
"amount": "0.20"
}
Actual source-chain gas cost. Populated after on-chain confirmation. Only present for cross-chain swaps.
Show child attributes
Show child attributes
{
"base_amount": "100000000000000",
"amount": "0.0001",
"gas_asset": "ETH"
}
Was this page helpful?

