Sponsor gas and set the venue's required allowances on a wallet
The one-time onboarding step behind “enable trading”: tops the wallet up with sponsored gas if it needs it, then sets every token allowance the venue’s contracts require. Both legs are signed custodially with the user’s delegated key.
wait_for_confirmation defaults to true. The call then blocks until the work completes and the response reports what actually happened. Passing false returns immediately with confirmation_pending: true, success: true, gas_sponsored: false and allowances_set: 0 — success: true there means “accepted”, not “done”, and a background failure is only logged, never surfaced. Poll the RPC query exchange.getAllowances to find out whether it worked.
The three identity fields are mandatory but are validated against the authenticated caller and the wallets it owns; they can confirm authority, never grant it.
Self-custody callers on the external-signing lane should use POST /v2/onchain/intent with op: "approvals" instead and pay their own gas.
Auth & scope. Requires trade:execute, the mutation gate (this endpoint spends gas-station funds, so a stolen JWT alone must not reach it), wallet ownership, and a current Turnkey policy version.
curl --request POST \
--url https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--header 'X-Api-Secret: <api-key>' \
--header 'X-Client-Id: <api-key>' \
--data '
{
"user_id": "<string>",
"turnkey_org_id": "<string>",
"wallet_address": "<string>",
"wait_for_confirmation": true
}
'import requests
url = "https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet"
payload = {
"user_id": "<string>",
"turnkey_org_id": "<string>",
"wallet_address": "<string>",
"wait_for_confirmation": True
}
headers = {
"X-Client-Id": "<api-key>",
"X-Api-Key": "<api-key>",
"X-Api-Secret": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Client-Id': '<api-key>',
'X-Api-Key': '<api-key>',
'X-Api-Secret': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_id: '<string>',
turnkey_org_id: '<string>',
wallet_address: '<string>',
wait_for_confirmation: true
})
};
fetch('https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet', 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://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet",
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([
'user_id' => '<string>',
'turnkey_org_id' => '<string>',
'wallet_address' => '<string>',
'wait_for_confirmation' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>",
"X-Api-Secret: <api-key>",
"X-Client-Id: <api-key>"
],
]);
$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://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet"
payload := strings.NewReader("{\n \"user_id\": \"<string>\",\n \"turnkey_org_id\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"wait_for_confirmation\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Client-Id", "<api-key>")
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("X-Api-Secret", "<api-key>")
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))
}HttpResponse<String> response = Unirest.post("https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet")
.header("X-Client-Id", "<api-key>")
.header("X-Api-Key", "<api-key>")
.header("X-Api-Secret", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"user_id\": \"<string>\",\n \"turnkey_org_id\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"wait_for_confirmation\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Client-Id"] = '<api-key>'
request["X-Api-Key"] = '<api-key>'
request["X-Api-Secret"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"user_id\": \"<string>\",\n \"turnkey_org_id\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"wait_for_confirmation\": true\n}"
response = http.request(request)
puts response.read_body{
"gas_sponsored": true,
"allowances_set": 123,
"confirmation_pending": true,
"success": true,
"gas_tx_hash": "<string>",
"gas_amount": "<string>"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}{
"error": "Unauthorized"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}Authorizations
Credential client id (kairos_ck_...). Must be sent together with X-Api-Key and X-Api-Secret.
64-char hex API key.
64-char hex API secret.
Path Parameters
"polymarket"
Body
Body for POST /exchanges/{exchange_id}/prepare-wallet. All three identity fields are mandatory and are VALIDATED against the authenticated caller — they can confirm authority, never grant it.
Must be a wallet owned by the authenticated caller.
Defaults to true — the call blocks until gas sponsorship and allowances are confirmed. Pass false to fire-and-forget: the response returns immediately with confirmation_pending: true, success: true and zeroed result fields, and a background task does the work. A background failure is only logged; the caller is never told.
Response
Wallet prepared, or — when wait_for_confirmation was sent as false — preparation accepted and running in the background.
Response for POST /exchanges/{exchange_id}/prepare-wallet.
Always false when confirmation_pending is true — the work had not run yet.
Number of allowances set. Always 0 when confirmation_pending is true.
true when the caller passed wait_for_confirmation: false and the preparation is still running in the background.
Always true on a 200, INCLUDING the fire-and-forget path where nothing has been attempted yet. It is not evidence the wallet is ready.
Present only when gas was actually sponsored.
Was this page helpful?
curl --request POST \
--url https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--header 'X-Api-Secret: <api-key>' \
--header 'X-Client-Id: <api-key>' \
--data '
{
"user_id": "<string>",
"turnkey_org_id": "<string>",
"wallet_address": "<string>",
"wait_for_confirmation": true
}
'import requests
url = "https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet"
payload = {
"user_id": "<string>",
"turnkey_org_id": "<string>",
"wallet_address": "<string>",
"wait_for_confirmation": True
}
headers = {
"X-Client-Id": "<api-key>",
"X-Api-Key": "<api-key>",
"X-Api-Secret": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Client-Id': '<api-key>',
'X-Api-Key': '<api-key>',
'X-Api-Secret': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_id: '<string>',
turnkey_org_id: '<string>',
wallet_address: '<string>',
wait_for_confirmation: true
})
};
fetch('https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet', 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://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet",
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([
'user_id' => '<string>',
'turnkey_org_id' => '<string>',
'wallet_address' => '<string>',
'wait_for_confirmation' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>",
"X-Api-Secret: <api-key>",
"X-Client-Id: <api-key>"
],
]);
$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://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet"
payload := strings.NewReader("{\n \"user_id\": \"<string>\",\n \"turnkey_org_id\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"wait_for_confirmation\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Client-Id", "<api-key>")
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("X-Api-Secret", "<api-key>")
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))
}HttpResponse<String> response = Unirest.post("https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet")
.header("X-Client-Id", "<api-key>")
.header("X-Api-Key", "<api-key>")
.header("X-Api-Secret", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"user_id\": \"<string>\",\n \"turnkey_org_id\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"wait_for_confirmation\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://execution.kairos.trade/exchanges/{exchange_id}/prepare-wallet")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Client-Id"] = '<api-key>'
request["X-Api-Key"] = '<api-key>'
request["X-Api-Secret"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"user_id\": \"<string>\",\n \"turnkey_org_id\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"wait_for_confirmation\": true\n}"
response = http.request(request)
puts response.read_body{
"gas_sponsored": true,
"allowances_set": 123,
"confirmation_pending": true,
"success": true,
"gas_tx_hash": "<string>",
"gas_amount": "<string>"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}{
"error": "Unauthorized"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}{
"error": "<string>",
"error_details": {
"code": "FUNDS_INSUFFICIENT_USDC",
"message": "<string>",
"actions": [
{
"action": "enable_trading",
"label": "Add Funds",
"primary": true,
"url": "<string>"
}
],
"details": "<string>",
"metadata": {}
},
"code": "<string>"
}
