Skip to main content
Copy trading lets your users copy the traders in their Trade Feed. Whenever a copied trader buys or sells, CabalSpy ID sends your app a copy instruction for each user who copies them: which token, on which chain, buy or sell, how much, and the price limit. Your app executes the instruction with the user’s wallet and reports back whether it was executed, failed or skipped.
CabalSpy ID never holds keys and never executes trades. It only tells your app what to do. Your platform executes every trade with the user’s own wallet, under your own rules, and stays responsible for it.
Copy trading is available to every instance on every plan, there is nothing to switch on. A key only reaches the copy settings and instructions of its own instance.

Who can copy

Copying always happens in the name of one of your users:
  • a platform user, by external_id or csid_id,
  • or a person who signed in to your app with CabalSpy ID and granted the scope trade_feed, by csid_id.
The user must be within your plan’s user limit. Users without the scope get 403 consent_required. Platform users always have it. A user can copy any trader they can add to their Trade Feed: a CabalSpy ID user whose trading is public, or another of your own platform users. Copy settings are stored per user and trader, and switching copying on adds the trader to the user’s Trade Feed if they are not there yet.

How it works

1

The user switches copying on

Your backend calls POST /v1/copy-trading/settings with the user, the trader and how much to copy. From now on your instance copies this trader for this user.
2

The trader trades

CabalSpy ID sees the trade on one of the trader’s verified wallets, the same moment it reaches the Trade Feed.
3

CabalSpy ID sends an instruction

For each user who copies the trader, CabalSpy ID sizes the trade by the user’s settings and sends a copy instruction as the copy_trade.instruction webhook and on the copy trading stream. You can also poll GET /v1/copy-trading/instructions.
4

Your app executes it

Within 120 seconds, your app swaps with the user’s wallet, respecting max_price_usd (buys) or min_price_usd (sells).
5

Your app reports the result

Call POST /v1/copy-trading/instructions/status with executed, failed or skipped, and the transaction signature when there is one. The result decides whether later sells of that token are copied.

One platform at a time

A user can use several platforms with CabalSpy ID, but each trader is copied by one platform at a time, so a user is never copied twice. The platform that switches copying on for a trader receives that trader’s instructions for that user, and nobody else does. While your platform copies a trader for a user, another platform cannot switch copying on for the same trader and gets 409 copy_managed_elsewhere. It sees managed_by_other_platform: true in GET /v1/copy-trading/settings. Once the first platform switches copying off, another platform can take over.

Sizing

Each user has their own settings per trader. See Copy settings for all fields and limits. Buys. The amount in USD comes from mode: max_usd, if set, caps every buy. Buys that come out below $1 are not sent. The instruction carries the amount in USD (amount_usd) and, where the price of the chain’s native coin is known, in the native coin (amount_native, for example SOL). Sells. With sides: "both" (default), sells are copied as a share of the user’s copied position, not as an amount:
  • The trader sold part of their position: sell the same share. A trader who sold 50 % of their tokens sends sell_percent: 50.
  • The trader closed their position: sell_percent: 100.
  • A sell is only sent when the user has a copied buy in that token from that trader that you did not report as failed or skipped. A user who never copied the entry does not get the exit.
  • Sells whose entry is unknown, for example of tokens the trader bought before CabalSpy ID tracked their wallet, are not copied.
With sides: "buys", only buys are copied and the user decides when to sell. Price limit. Every instruction carries the trader’s price (price_usd) and the user’s slippage (slippage_bps, default 300 = 3 %). For a buy, max_price_usd is the trader’s price plus the slippage, for a sell min_price_usd is the trader’s price minus the slippage. Do not execute beyond that limit; report skipped instead. Example. A user copies with mode: "fixed_usd", amount_usd: 25 and max_usd: 20. The trader buys 1,000 tokens for 1 SOL ($150), so at $0.15 per token. The user’s instruction: buy for **$20** (capped), 0.133333333 SOL, at most $0.1545 per token (+3 %). Copying does not depend on the user’s alert filters. A trader the user muted in their Trade Feed, or with buy or sell alerts off or a minimum trade size, is still copied in full.

The instruction

One instruction per user and trade. The same trade is never sent twice for the same user: the id is fixed per user and trade, so deduplicate on it.
copy_trade.instruction
A copied sell looks the same, with "side": "sell", sell_percent set, amount_usd and amount_native null and min_price_usd instead of max_price_usd:
action of a sell
string
The instruction id, fixed per user and trade. Deduplicate on it.
string
Always copy_instruction.
string
pending, executed, failed, skipped or expired. See Statuses.
string
When the instruction was made, and until when it is meant to be executed: 120 seconds later.
string
The user who copies.
string
Your own id of the user when they are a platform user, otherwise null. Only in the webhook and on the stream; look the user up by csid_id in REST responses.
object
The trader who traded: csid_id, username, name, image_url, kol and profile_url. username and profile_url are null for platform users.
object
What to execute.
object
The trader’s own trade, the same trade object as in the Trade Feed: side, label (new, add, partial, close), sold_percent, amounts in the native coin and USD, token amount, price, realized PnL of a sell, the trader’s wallet and the transaction with explorer links.
object
The user’s copy settings for this trader at the time of the instruction.
token (the token page), terminal (the CabalSpy Terminal on Solana and BNB Chain, otherwise null) and profile (the trader’s profile).
string
What your app reported, see Report the result. Null until then.
string
When the instruction was made or last reported.

Statuses

executed, failed and skipped are final. A copied buy reported as failed or skipped means later sells of that token are not copied for that user. A buy still pending or expired counts as a position.

Quickstart

1

Switch copying on

Copy @MazeCCC for one of your platform users with $25 per buy, at most $20:
2

Receive instructions

Subscribe your webhook to copy_trade.instruction on the instance’s Webhooks tab, or connect to the copy trading stream. Verify the signature as described in Webhooks and answer 2xx right away.
3

Execute

Look up the user by external_id or csid_id, check expires_at, and swap with their wallet within the price limit. For sells, sell sell_percent % of what the user holds from their copied buys of this token.
4

Report

Report every instruction, also the ones you did not execute.
If your app was down, list what is still open with GET /v1/copy-trading/instructions?status=pending and decide whether to execute or skip each one.

Stopping

Copying of a trader stops for a user when:
  • you switch it off with "enabled": false in POST /v1/copy-trading/settings,
  • the trader is removed from the user’s Trade Feed,
  • the user revokes your app’s access or the scope trade_feed, or falls outside your plan’s user limit,
  • the trader makes their trading private.
Instructions already sent stay readable and can still be reported.

Dashboard

The instance’s Copy trading tab shows how many users copy how many traders, the instructions of the last 24 hours by status, the executed volume and the newest instructions.

Endpoints