X-Trader copy-trade config fields reference
A copy-trade body has remark, target_wallet, linked_wallets and config (all required on create) plus an optional risk_label_id. Inside config, buy size and execution fees live in buy_config_universal or in market-cap tiers under buy_config_tiers, selected by buy_config_mode. The rest of config holds the DEX selection, once-only switches, dev-launch and dev-sell modes, an address blacklist, trade-size filters and the three sell-side objects. All amounts, fees and percentages are decimal strings.
Primary source: X-Trader API reference. This page is an independent explanation of X-Trader Public API v1.0.0; it is not affiliated with X-Trader.
Where these fields are used
Section titled “Where these fields are used”| Operation | Schema | Body rules |
|---|---|---|
POST /copy-trade/configs |
CopyTradeCreate |
remark, target_wallet, linked_wallets, config required. Needs Idempotency-Key. Created with is_active=false. |
PATCH /copy-trade/configs/{id} |
CopyTradePatch |
Accepts remark, linked_wallets, risk_label_id, config; at least one. Needs If-Match. |
Every object is strict (additionalProperties: false): unknown keys return validation_error. Create also rejects user_id, version and template. General write rules are on write rules; lifecycle calls on copy-trade.
Top-level body fields
Section titled “Top-level body fields”| Field | Type | Create | Patch | Limits and notes |
|---|---|---|---|---|
remark |
string | required (default "") |
optional | Max 64 characters, trimmed. Free-text note. |
target_wallet |
string | required | not allowed | Solana address, 32-44 characters. The wallet whose trades are copied. Immutable after creation. |
linked_wallets |
array of strings | required (default []) |
optional | Up to 20 unique Solana addresses (max 44 characters each; the PATCH schema also states min 32) tied to the same target. In PATCH it replaces the whole array and requires the task to be paused. |
risk_label_id |
string (UUID) or null |
optional | optional | Label owned by the same account (labels). null unassigns. A foreign label returns 404 not_found. |
config |
object | required | optional | Full strategy object. In PATCH it replaces the stored config and requires the task to be paused. |
Linked wallets matter for skip_dev_launch, dev_sell_only and dev_sell_all_only, which check whether the creator is the target or a linked wallet.
There is no template reference field. Templates are managed separately (templates); to use one, read its config and send it as config.
Buy mode
Section titled “Buy mode”| Field | Type | Required | Allowed values | Meaning |
|---|---|---|---|---|
buy_config_mode |
string enum | yes | universal, tiered |
Which buy parameter set is active. |
buy_config_universal |
object | yes | strict object | One parameter set for all followed buys. |
buy_config_tiers |
array of objects | yes | max 20 items | Market-cap-specific parameter sets. |
Both buy_config_universal and buy_config_tiers must be present whatever the mode. Only the active side needs a real amount_sol; the inactive side may keep an empty string (universal) or an empty array (tiers).
| Mode | Active side | Requirements |
|---|---|---|
universal |
buy_config_universal |
Its amount_sol must be > 0 and <= 1,000,000. buy_config_tiers may be []. |
tiered |
buy_config_tiers |
At least one tier, each with a valid amount_sol. buy_config_universal must still be sent; its amount_sol may be "". |
Buy parameter set (universal object and each tier)
Section titled “Buy parameter set (universal object and each tier)”buy_config_universal and every element of buy_config_tiers share exactly the same fields. Unlike the sniper config, copy-trade has no jito_mode / priority_mode objects: the two execution channels are encoded as prefixed flat fields.
| Field | Type | Required | Limits | Meaning |
|---|---|---|---|---|
market_cap_min |
decimal string | yes | max length 32 | Lower market-cap bound. "" means no lower bound. |
market_cap_max |
decimal string | yes | must not be below market_cap_min |
Upper market-cap bound. "" means no upper bound. |
amount_sol |
decimal string | yes | > 0 and <= 1,000,000 on the active side; "" allowed on the unused side |
SOL spent per copied buy. |
jito_tip |
decimal string | yes | 0 to 1,000 SOL | Jito channel tip. |
jito_priority_fee |
decimal string | yes | 0 to 1,000 SOL | Jito channel priority fee. |
jito_slippage |
decimal string | yes | 0 to 100 (percent) | Jito channel slippage. Ignored when jito_bundle_amount is positive on a DEX that supports bundle pool advancement. |
jito_bundle_amount |
decimal string | no | max length 32 | Jito-only bundle pressure in SOL. Empty or omitted means percentage slippage is used. |
priority_fee |
decimal string | yes | 0 to 1,000 SOL | Direct/leader channel priority fee. |
priority_tip |
decimal string | yes | 0 to 1,000 SOL | Direct/leader channel tip. |
priority_slippage |
decimal string | yes | 0 to 100 (percent) | Direct/leader channel slippage. Ignored when priority_bundle_amount is positive on a DEX that supports bundle pool advancement. |
priority_bundle_amount |
decimal string | no | max length 32 | Direct/leader-only bundle pressure in SOL. Empty or omitted means percentage slippage. |
selected_dexes |
array of strings | no | max 7, same enum as config-level list | Tier scope (see below). Unrelated to the config-level DEX setting. |
sol_slippage_mode |
boolean | yes | default false |
Legacy shared SOL-slippage flag, kept for old configs. Prefer the two per-channel flags. |
jito_sol_slippage_mode |
boolean | no | When true, the Jito channel uses SOL slippage and ignores jito_slippage. |
|
priority_sol_slippage_mode |
boolean | no | Same for the direct/leader channel, independent of the Jito flag. |
Mapping to the sniper names, for readers coming from the sniper config reference:
Sniper (jito_mode.* / priority_mode.*) |
Copy-trade Jito channel | Copy-trade direct channel |
|---|---|---|
tip_amount |
jito_tip |
priority_tip |
priority_fee |
jito_priority_fee |
priority_fee |
slippage |
jito_slippage |
priority_slippage |
bundle_amount |
jito_bundle_amount |
priority_bundle_amount |
sol_slippage_mode |
jito_sol_slippage_mode |
priority_sol_slippage_mode |
The spec does not document which channel a particular copied trade uses.
How market-cap tiers work
Section titled “How market-cap tiers work”| Rule | Source in spec |
|---|---|
| Up to 20 tiers. | buy_config_tiers maxItems: 20 |
Each tier is a range market_cap_min to market_cap_max; an empty bound is open. |
field descriptions |
market_cap_max must not be below market_cap_min. |
field description |
selected_dexes inside a tier narrows that tier to the listed DEXes; omitted or [] applies the tier to all DEXes. |
selected_dexes description |
In tiered mode at least one tier is required. |
buy_config_mode description |
The spec does not document the market-cap unit (SOL or USD), the order in which tiers are evaluated, how overlapping ranges are resolved, or what happens when a token’s market cap matches no tier. Non-overlapping ranges avoid the ambiguity; an open-ended tier ("" on one side) covers the edges.
DEX selection
Section titled “DEX selection”| Field | Type | Required | Allowed values | Meaning |
|---|---|---|---|---|
selected_dexes |
array of strings | yes | 1 to 7 of pump-fun, pump-amm, launchlab, meteora-dynamic-bc, meteora-damm-v2, raydium-amm, raydium-cpmm |
DEXes on which the target’s trades are followed. |
dex_source |
string enum | yes (default global) |
global, config |
global: the account’s enabled global DEX list, falling back to selected_dexes when that list is unavailable. config: always selected_dexes. |
dev_sell_only and dev_sell_all_only require pump-fun in selected_dexes.
Once-only switches
Section titled “Once-only switches”| Field | Type | Required | Default | Scope | Meaning |
|---|---|---|---|---|---|
buy_token_once |
boolean | yes | none | per token | Each token is bought at most once by this config. An attempted buy counts even if execution fails. |
first_buy_only |
boolean | yes | none | per target | The task reacts only once for the target address. Filtered, failed and successful normal signals all count. In dev_sell_only mode, the first successfully submitted dev-sell buy blocks later dev sells from triggering. |
buy_once |
boolean | yes | none | whole task | The task deactivates after its first triggered trade. |
reentry_after_flat |
boolean | yes | false |
Deprecated. true is treated as first_buy_only=true and stored as false. Send false and use first_buy_only. |
Creator (dev) modes
Section titled “Creator (dev) modes”| Field | Type | Required | Default | Meaning |
|---|---|---|---|---|
skip_dev_launch |
boolean | yes | false |
Skip Pump, Launchpad and DBC bonding-curve tokens whose creator is the target or a linked wallet. Historical tokens without creator data are not skipped. |
dev_sell_only |
boolean | yes | false |
Normal buys are not followed. A buy is triggered only when the target or a linked wallet is the creator and sells a Pump bonding-curve token. |
dev_sell_all_only |
boolean | yes | false |
Normal buys are not followed. A buy is triggered only when the creator’s Pump sell leaves its source token account at zero. |
Documented side effects and limits:
| Mode | Notes |
|---|---|
dev_sell_only |
pump-fun must be selected. min_trade_amount, max_trade_amount, Anti-PVP and skip_dev_launch are ignored. Address-index changes can take up to 10 seconds. Historical pools without creator data are skipped. |
dev_sell_all_only |
pump-fun must be selected. Can be combined with dev_sell_only. One exit transaction triggers only one buy. If the post-trade balance cannot be verified, the signal is skipped. |
Address blacklist
Section titled “Address blacklist”| Field | Type | Required | Default | Limits | Meaning |
|---|---|---|---|---|---|
address_blacklist |
object | yes | {"enabled": false, "wallets": []} |
strict object | Copy-trade only filter. |
address_blacklist.enabled |
boolean | yes | false |
When true, a followed buy is skipped if any listed wallet bought the same mint earlier, within 24 hours of observation. |
|
address_blacklist.wallets |
array of strings | yes | [] |
max 50, unique, valid Solana addresses (32-44 characters) | Wallets to check against. |
The spec notes that observation covers all configured wallets regardless of enabled, so wallets in a disabled list are still tracked.
Trade-size filter
Section titled “Trade-size filter”| Field | Type | Required | Limits | Meaning |
|---|---|---|---|---|
min_trade_amount |
decimal string | yes | max length 32 | Minimum size of the target’s transaction to follow. "" disables the lower bound. Ignored by dev_sell_only. |
max_trade_amount |
decimal string | yes | must not be below min_trade_amount unless dev_sell_only is on |
Maximum size of the target’s transaction to follow. "" disables the upper bound. |
These filter the target’s trade, not your buy size. The spec does not state the unit; the other amounts in the config are in SOL.
Legacy field
Section titled “Legacy field”| Field | Type | Required | Meaning |
|---|---|---|---|
bundle_amount |
decimal string | no | Legacy top-level bundle pressure fallback for old configs. Use jito_bundle_amount and priority_bundle_amount in the buy parameter sets. |
Sell-side objects
Section titled “Sell-side objects”| Field | Summary | Reference |
|---|---|---|
auto_sell |
Take-profit and stop-loss orders, trailing take-profit, follow-sell and proportional-sell, with an expiry in minutes (0 keeps it active). |
auto-sell |
auto_strategy |
Extra exit rules: migration clear, timed sell, position and price-stagnation clears, profit and SL protection, phased SL, Anti-PVP and sell-fee override. | auto-strategy |
timed_strategy |
Staged time-based sell orders, maximum 20. | timed-strategy |
All three are required. Minimum accepted shapes: auto_sell with enabled, expiry_time, tp_orders, sl_orders, follow_sell, proportional_sell; auto_strategy with migration_clear, timed_sell, sell_delay; timed_strategy with enabled and orders.
What differs in CopyTradePatch
Section titled “What differs in CopyTradePatch”| Aspect | CopyTradeCreate | CopyTradePatch |
|---|---|---|
| Required top-level fields | remark, target_wallet, linked_wallets, config |
at least one of remark, linked_wallets, risk_label_id, config |
target_wallet |
required | not accepted |
linked_wallets |
required, default [] |
optional; replaces the whole array; task must be paused |
config |
full object | full object again; replaces the stored config; task must be paused |
| Active task | n/a (created paused) | only remark and risk_label_id may change |
| Headers | Idempotency-Key |
If-Match with the latest ETag |
The nested config schema is identical in both operations.
Minimal valid create body
Section titled “Minimal valid create body”Universal mode, no filters, sell-side features off:
{ "remark": "", "target_wallet": "11111111111111111111111111111111", "linked_wallets": [], "config": { "buy_config_mode": "universal", "buy_config_universal": { "market_cap_min": "", "market_cap_max": "", "amount_sol": "0.1", "jito_tip": "0.01", "jito_priority_fee": "0.0005", "jito_slippage": "15", "priority_fee": "0.005", "priority_tip": "0.001", "priority_slippage": "15", "sol_slippage_mode": false }, "buy_config_tiers": [], "selected_dexes": ["pump-fun"], "dex_source": "global", "buy_token_once": false, "first_buy_only": false, "reentry_after_flat": false, "buy_once": false, "skip_dev_launch": false, "dev_sell_only": false, "dev_sell_all_only": false, "address_blacklist": { "enabled": false, "wallets": [] }, "min_trade_amount": "", "max_trade_amount": "", "auto_sell": { "enabled": false, "expiry_time": "0", "tp_orders": [], "sl_orders": [], "follow_sell": false, "proportional_sell": false }, "auto_strategy": { "migration_clear": false, "timed_sell": false, "sell_delay": "30" }, "timed_strategy": { "enabled": false, "orders": [] } }}Fuller example: tiered mode with filters
Section titled “Fuller example: tiered mode with filters”Two market-cap tiers, a linked wallet, buy each token once, skip the target’s own launches, a blacklist and a trade-size window. Addresses are placeholders.
{ "remark": "Tiered copy, main target", "target_wallet": "11111111111111111111111111111111", "linked_wallets": ["So11111111111111111111111111111111111111112"], "risk_label_id": "3f2c1a9e-8b7d-4c6e-9a1b-2d3e4f5a6b7c", "config": { "buy_config_mode": "tiered", "buy_config_universal": { "market_cap_min": "", "market_cap_max": "", "amount_sol": "", "jito_tip": "0", "jito_priority_fee": "0", "jito_slippage": "0", "priority_fee": "0", "priority_tip": "0", "priority_slippage": "0", "sol_slippage_mode": false }, "buy_config_tiers": [ { "market_cap_min": "", "market_cap_max": "50000", "amount_sol": "0.2", "jito_tip": "0.01", "jito_priority_fee": "0.0005", "jito_slippage": "25", "jito_bundle_amount": "", "priority_fee": "0.005", "priority_tip": "0.001", "priority_slippage": "25", "priority_bundle_amount": "", "selected_dexes": [], "sol_slippage_mode": false, "jito_sol_slippage_mode": false, "priority_sol_slippage_mode": false }, { "market_cap_min": "50000", "market_cap_max": "", "amount_sol": "0.05", "jito_tip": "0.005", "jito_priority_fee": "0.0005", "jito_slippage": "10", "priority_fee": "0.003", "priority_tip": "0.001", "priority_slippage": "10", "selected_dexes": ["pump-amm", "raydium-cpmm"], "sol_slippage_mode": false } ], "selected_dexes": ["pump-fun", "pump-amm", "raydium-cpmm"], "dex_source": "config", "buy_token_once": true, "first_buy_only": false, "reentry_after_flat": false, "buy_once": false, "skip_dev_launch": true, "dev_sell_only": false, "dev_sell_all_only": false, "address_blacklist": { "enabled": true, "wallets": ["11111111111111111111111111111112"] }, "min_trade_amount": "0.5", "max_trade_amount": "20", "auto_sell": { "enabled": true, "tab": "tpsl", "expiry_time": "120", "tp_orders": [{ "trigger": "90", "sell": "100" }], "sl_orders": [], "follow_sell": true, "proportional_sell": false, "trailing_take_profit": { "enabled": false, "tiers": [] } }, "auto_strategy": { "migration_clear": false, "timed_sell": false, "sell_delay": "30" }, "timed_strategy": { "enabled": false, "orders": [] } }}The inactive buy_config_universal keeps amount_sol empty, as the spec allows. Its fee fields are still required; this example fills them with "0", which is inside the documented 0 to 1,000 and 0 to 100 ranges. The second tier relies on market_cap_min equal to the first tier’s market_cap_max; since boundary handling is not documented, leave a gap or accept that one value may match either tier.
Sending the body
Section titled “Sending the body”curl --request POST 'https://x-trader.ai/api/v1/copy-trade/configs' \ --header "Authorization: Bearer $X_TRADER_API_TOKEN" \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: create-copy-20261016-001' \ --data @copy-config.jsonimport jsonimport os
import requests
BASE = "https://x-trader.ai/api/v1"auth = {"Authorization": f"Bearer {os.environ['X_TRADER_API_TOKEN']}"}
with open("copy-config.json") as f: body = json.load(f)
resp = requests.post( f"{BASE}/copy-trade/configs", json=body, headers={**auth, "Idempotency-Key": "create-copy-20261016-001"}, timeout=30,)resp.raise_for_status()config_id = resp.json()["data"]["id"]etag = resp.headers["ETag"]Replacing linked_wallets on a paused task:
curl --request PATCH "https://x-trader.ai/api/v1/copy-trade/configs/$CONFIG_ID" \ --header "Authorization: Bearer $X_TRADER_API_TOKEN" \ --header 'Content-Type: application/json' \ --header 'If-Match: "v1"' \ --data '{"linked_wallets":["So11111111111111111111111111111111111111112"]}'resp = requests.patch( f"{BASE}/copy-trade/configs/{config_id}", json={"linked_wallets": ["So11111111111111111111111111111111111111112"]}, headers={**auth, "If-Match": etag}, timeout=30,)resp.raise_for_status()What is the difference between universal and tiered buy_config_mode?
Section titled “What is the difference between universal and tiered buy_config_mode?”universal applies the single buy_config_universal parameter set to every followed buy. tiered uses buy_config_tiers, a list of up to 20 market-cap ranges each with its own amount, fees and slippage, and requires at least one tier.
Do I have to send buy_config_tiers in universal mode?
Section titled “Do I have to send buy_config_tiers in universal mode?”Yes. Both buy_config_universal and buy_config_tiers are required keys in every config. In universal mode send an empty tiers array; in tiered mode the universal object stays but its amount_sol may be an empty string.
What is the difference between buy_token_once, first_buy_only and buy_once?
Section titled “What is the difference between buy_token_once, first_buy_only and buy_once?”buy_token_once buys each token at most once for the task. first_buy_only makes the task react only once for the target address. buy_once deactivates the whole task after its first triggered trade.
Can I create a copy-trade config from a template through the API?
Section titled “Can I create a copy-trade config from a template through the API?”No template reference is accepted in the create body. The create endpoint rejects a template field together with user_id, version and unknown fields, so send the full config.
What is required for dev_sell_only to work?
Section titled “What is required for dev_sell_only to work?”pump-fun must be in selected_dexes. The task then ignores normal buys and triggers only when the target or a linked wallet is the token creator and sells a Pump bonding-curve token.