Skip to main content
POST
/
v1
/
intents
/
wallets
/
{wallet_id}
/
transfer
Create transfer intent
curl --request POST \
  --url https://api.privy.io/v1/intents/wallets/{wallet_id}/transfer \
  --header 'Authorization: Basic <encoded-value>' \
  --header 'Content-Type: application/json' \
  --header 'privy-app-id: <privy-app-id>' \
  --data '
{
  "amount": "10.5",
  "source": {
    "asset": "usdc",
    "amount": "10.5",
    "chain": "base"
  },
  "destination": {
    "address": "0xB00F0759DbeeF5E543Cc3E3B07A6442F5f3928a2"
  }
}
'
HttpResponse<String> response = Unirest.post("https://api.privy.io/v1/intents/wallets/{wallet_id}/transfer")
  .header("privy-app-id", "<privy-app-id>")
  .header("Authorization", "Basic <encoded-value>")
  .header("Content-Type", "application/json")
  .body("{\n  \"amount\": \"10.5\",\n  \"source\": {\n    \"asset\": \"usdc\",\n    \"amount\": \"10.5\",\n    \"chain\": \"base\"\n  },\n  \"destination\": {\n    \"address\": \"0xB00F0759DbeeF5E543Cc3E3B07A6442F5f3928a2\"\n  }\n}")
  .asString();
const options = {
  method: 'POST',
  headers: {
    'privy-app-id': '<privy-app-id>',
    Authorization: 'Basic <encoded-value>',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: '10.5',
    source: {asset: 'usdc', amount: '10.5', chain: 'base'},
    destination: {address: '0xB00F0759DbeeF5E543Cc3E3B07A6442F5f3928a2'}
  })
};

fetch('https://api.privy.io/v1/intents/wallets/{wallet_id}/transfer', 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/intents/wallets/{wallet_id}/transfer",
  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([
    'amount' => '10.5',
    'source' => [
        'asset' => 'usdc',
        'amount' => '10.5',
        'chain' => 'base'
    ],
    'destination' => [
        'address' => '0xB00F0759DbeeF5E543Cc3E3B07A6442F5f3928a2'
    ]
  ]),
  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/intents/wallets/{wallet_id}/transfer"

	payload := strings.NewReader("{\n  \"amount\": \"10.5\",\n  \"source\": {\n    \"asset\": \"usdc\",\n    \"amount\": \"10.5\",\n    \"chain\": \"base\"\n  },\n  \"destination\": {\n    \"address\": \"0xB00F0759DbeeF5E543Cc3E3B07A6442F5f3928a2\"\n  }\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))

}
{
  "intent_id": "<string>",
  "created_by_display_name": "<string>",
  "created_at": 123,
  "resource_id": "<string>",
  "authorization_details": [
    {
      "members": [
        {
          "type": "user",
          "user_id": "<string>",
          "signed_at": 123
        }
      ],
      "threshold": 123,
      "display_name": "<string>"
    }
  ],
  "custom_expiry": true,
  "expires_at": 123,
  "intent_type": "TRANSFER",
  "request_details": {
    "method": "POST",
    "url": "<string>",
    "body": {
      "amount": "10.5",
      "source": {
        "asset": "usdc",
        "amount": "10.5",
        "chain": "base"
      },
      "destination": {
        "address": "0xB00F0759DbeeF5E543Cc3E3B07A6442F5f3928a2"
      }
    }
  },
  "created_by_id": "<string>",
  "rejected_at": 123,
  "dismissed_at": 123,
  "dismissal_reason": "<string>",
  "current_resource_data": {
    "id": "id2tptkqrxd39qo9j423etij",
    "address": "0xF1DBff66C993EE895C8cb176c30b07A559d76496",
    "display_name": "Treasury",
    "external_id": "my-order-123",
    "chain_type": "ethereum",
    "policy_ids": [],
    "additional_signers": [],
    "owner_id": "rkiz0ivz254drv1xw982v3jq",
    "created_at": 1741834854578,
    "exported_at": null,
    "imported_at": null,
    "archived_at": null
  },
  "action_result": {
    "status_code": 123,
    "executed_at": 123,
    "response_body": {
      "id": "<string>",
      "wallet_id": "<string>",
      "created_at": "2023-11-07T05:31:56Z",
      "type": "transfer",
      "source_chain": "<string>",
      "destination_address": "<string>",
      "destination_amount": "<string>",
      "failure_reason": {
        "message": "<string>",
        "details": "<unknown>"
      },
      "steps": [
        {
          "type": "evm_transaction",
          "caip2": "<string>",
          "transaction_hash": "<string>",
          "failure_reason": {
            "message": "<string>",
            "details": "<unknown>"
          },
          "finalized": true
        }
      ],
      "source_asset": "<string>",
      "source_asset_address": "<string>",
      "source_asset_decimals": 123,
      "source_amount": "<string>",
      "destination_asset": "<string>",
      "destination_chain": "<string>",
      "estimated_fees": [
        {
          "type": "privy",
          "recipient": "0x1234567890abcdef1234567890abcdef12345678",
          "amount": "0.20"
        }
      ],
      "estimated_gas": {
        "base_amount": "100000000000000",
        "amount": "0.0001",
        "gas_asset": "ETH"
      },
      "fees": [
        {
          "type": "privy",
          "recipient": "0x1234567890abcdef1234567890abcdef12345678",
          "amount": "0.20"
        }
      ],
      "gas": {
        "base_amount": "100000000000000",
        "amount": "0.0001",
        "gas_asset": "ETH"
      }
    },
    "authorized_by_display_name": "<string>",
    "authorized_by_id": "<string>"
  }
}

Authorizations

Authorization
string
header
required

Basic Auth header with your app ID as the username and your app secret as the password.

Headers

privy-app-id
string
required

ID of your Privy app.

privy-request-expiry
string

Request expiry. Value is a Unix timestamp in milliseconds representing the deadline by which the request must be processed.

Path Parameters

wallet_id
string
required

ID of the wallet.

Body

application/json

Request body for initiating a sponsored token transfer from an embedded wallet.

source
NamedTokenTransferSource · object
required

Source for a transfer identified by a named asset (e.g. "usdc", "eth"). Use this variant for first-class assets maintained by Privy.

Example:
{
  "asset": "usdc",
  "amount": "10.5",
  "chain": "base"
}
destination
TokenTransferDestination · object
required

The destination address for a token transfer. Optionally specify a different asset or chain for cross-asset or cross-chain transfers.

Example:
{
  "address": "0xB00F0759DbeeF5E543Cc3E3B07A6442F5f3928a2"
}
amount
string

Amount as a decimal string in the token's standard unit (e.g. "1.5" for 1.5 USDC). For exact_input, the amount to send. For exact_output, the exact amount to receive. Takes precedence over source.amount when both are provided.

Maximum string length: 100
amount_type
enum<string>

Whether the amount refers to the input token or output token.

Available options:
exact_input,
exact_output
slippage_bps
integer

Maximum allowed slippage in basis points (1 bps = 0.01%). Only applicable for cross-chain or cross-asset transfers; omit to use the provider default.

Required range: 0 <= x <= 10000
fee_configuration
FeeConfiguration · object

Optional fee configuration for the transfer. If omitted, cross-chain transfers will not charge additional fees.

Example:
{ "type": "total_fee_bps", "value": 50 }

Response

200 - application/json

Created transfer intent.

Response for a transfer intent

intent_id
string
required

Unique ID for the intent

created_by_display_name
string
required

Display name of the user who created the intent

created_at
number
required

Unix timestamp when the intent was created

resource_id
string
required

ID of the resource being modified (wallet_id, policy_id, etc)

authorization_details
IntentAuthorization · object[]
required

Detailed authorization information including key quorum members, thresholds, and signature status

status
enum<string>
required

Current status of an intent.

Available options:
pending,
processing,
executed,
failed,
expired,
rejected,
dismissed
custom_expiry
boolean
required

Whether this intent has a custom expiry time set by the client. If false, the intent expires after a default duration.

expires_at
number
required

Unix timestamp when the intent expires

intent_type
enum<string>
required
Available options:
TRANSFER
request_details
object
required

The original transfer request that would be sent to the wallet transfer endpoint

created_by_id
string

ID of the user who created the intent. If undefined, the intent was created using the app secret

rejected_at
number

Unix timestamp when the intent was rejected, present when status is 'rejected'

dismissed_at
number

Unix timestamp when the intent was dismissed, present when status is 'dismissed'

dismissal_reason
string

Human-readable reason for dismissal, present when status is 'dismissed'

current_resource_data
Wallet · object

Current state of the wallet before any changes. If undefined, the resource was deleted and no longer exists

Example:
{
  "id": "id2tptkqrxd39qo9j423etij",
  "address": "0xF1DBff66C993EE895C8cb176c30b07A559d76496",
  "display_name": "Treasury",
  "external_id": "my-order-123",
  "chain_type": "ethereum",
  "policy_ids": [],
  "additional_signers": [],
  "owner_id": "rkiz0ivz254drv1xw982v3jq",
  "created_at": 1741834854578,
  "exported_at": null,
  "imported_at": null,
  "archived_at": null
}
action_result
BaseActionResult · object

Result of transfer execution (only present if intent status is 'executed' or 'failed')