X-Trader sniper and copy-trade templates API
X-Trader templates are reusable, named strategy snapshots owned by the current user: a template holds a name and a complete config in the same shape as a sniper or copy-trade task config. The API exposes them at /sniper/templates and /copy-trade/templates with list, create, get, patch and delete operations, guarded by the sniper:* and copytrade:* scopes respectively. Both kinds share a limit of 1,000 templates, and changing or deleting a template never rewrites the config stored in existing tasks.
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.
Operations
Section titled “Operations”| Method and path | Scope | Required headers | Success |
|---|---|---|---|
GET /sniper/templates |
sniper:read |
Authorization |
200 list envelope |
POST /sniper/templates |
sniper:write |
Authorization, Idempotency-Key |
201 resource envelope |
GET /sniper/templates/{id} |
sniper:read |
Authorization |
200 resource envelope |
PATCH /sniper/templates/{id} |
sniper:write |
Authorization, If-Match |
200 resource envelope |
DELETE /sniper/templates/{id} |
sniper:delete |
Authorization, If-Match |
204 no body |
GET /copy-trade/templates |
copytrade:read |
Authorization |
200 list envelope |
POST /copy-trade/templates |
copytrade:write |
Authorization, Idempotency-Key |
201 resource envelope |
GET /copy-trade/templates/{id} |
copytrade:read |
Authorization |
200 resource envelope |
PATCH /copy-trade/templates/{id} |
copytrade:write |
Authorization, If-Match |
200 resource envelope |
DELETE /copy-trade/templates/{id} |
copytrade:delete |
Authorization, If-Match |
204 no body |
Base URL https://x-trader.ai/api/v1. All operations also list 400, 401, 403, 404, 409, 429, 500 and 503. There are no pause or resume operations for templates (a template does not execute), and there are no transfer-snipe templates.
Headers
Section titled “Headers”| Header | Where | Rule |
|---|---|---|
Authorization |
All | Bearer xt_live_<id>.<secret> |
Idempotency-Key |
POST create | 8-128 chars from A-Z a-z 0-9 . _ : -, retained 24 hours; same key with another body gives idempotency_conflict |
If-Match |
PATCH, DELETE | Latest ETag such as "v3"; stale gives version_conflict |
ETag (response) |
201/200 single-template responses | Version for the next write |
X-Request-Id (response) |
Single-template and delete responses | Support correlation |
Fields
Section titled “Fields”Create body (SniperTemplateCreate, CopyTradeTemplateCreate)
Section titled “Create body (SniperTemplateCreate, CopyTradeTemplateCreate)”| Field | Type | Required | Rule |
|---|---|---|---|
name |
string | yes | 1-64 characters, leading and trailing spaces removed |
config |
object | yes | Complete strategy object. Sniper templates use the sniper config schema (/xtrader/config-sniper/); copy-trade templates use the copy-trade config schema (/xtrader/config-copy-trade/). |
Rejected on create: user_id, version, risk_label_id, and any unknown property. Templates never accept or return risk_label_id, so labels apply to tasks only (see /xtrader/labels/). Task-level fields such as remark, target_wallet and linked_wallets are not part of the template schemas.
Patch body (SniperTemplatePatch, CopyTradeTemplatePatch)
Section titled “Patch body (SniperTemplatePatch, CopyTradeTemplatePatch)”At least one of name and config. config, when present, is a complete replacement that must pass the full schema; it is not merged into the stored config.
Resource (SniperTemplateResource, CopyTradeTemplateResource)
Section titled “Resource (SniperTemplateResource, CopyTradeTemplateResource)”| Field | Type | Meaning |
|---|---|---|
id |
UUID | Server-generated template ID |
name |
string | Display name |
version |
integer | Concurrency version, also returned as ETag |
created_at |
string | ISO 8601 with UTC offset |
updated_at |
string | ISO 8601 with UTC offset |
config |
object | Stored strategy snapshot |
GET /sniper/templates and GET /copy-trade/templates return only the caller’s templates.
| Query parameter | Type | Rule |
|---|---|---|
limit |
integer | 1-100, default 20 |
cursor |
string | Max 2048; opaque next_cursor, bound to the token and the search query |
q |
string | Max 64; searches template names only |
There are no status or label_id filters on template lists. Response: data.items, data.next_cursor (string or null), meta.request_id. See /xtrader/pagination/.
Create
Section titled “Create”curl --request POST 'https://x-trader.ai/api/v1/sniper/templates' \ --header "Authorization: Bearer $X_TRADER_API_TOKEN" \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: template-create-001' \ --data '{ "name": "Pump launch defaults", "config": { "buy_amount": "0.1", "jito_mode": {"tip_amount": "0.01", "priority_fee": "0.0005", "slippage": "15", "bundle_amount": ""}, "priority_mode": {"tip_amount": "0.001", "priority_fee": "0.005", "slippage": "15", "bundle_amount": ""}, "selected_dexes": ["pump-fun"], "dex_source": "global", "dev_min_amount": "", "dev_max_amount": "", "buy_once": false, "sol_slippage_mode": false, "snipe_external": false, "auto_sell": { "enabled": false, "tab": "tpsl", "expiry_time": "10", "tp_orders": [{"trigger": "90", "sell": "100"}], "sl_orders": [], "follow_sell": false, "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": []} } }'Response 201 Created (headers ETag, X-Request-Id; IDs and timestamps illustrative):
{ "data": { "id": "5b9d3e1a-2c7f-4a8b-9e6d-4f1a0c3b7d92", "name": "Pump launch defaults", "version": 1, "created_at": "2026-10-16T09:00:00Z", "updated_at": "2026-10-16T09:00:00Z", "config": { "buy_amount": "0.1", "...": "stored config as sent" } }, "meta": { "request_id": "req_0123456789abcdef", "persistence": "committed" }}A copy-trade template is created the same way at /copy-trade/templates, with a copy-trade config (starting with buy_config_mode, buy_config_universal, buy_config_tiers and so on).
Patch semantics
Section titled “Patch semantics”PATCH /{kind}/templates/{id} can rename the template, replace its full config, or both. The spec states explicitly that existing tasks are not rewritten automatically: a task keeps the config snapshot it was created or last patched with. To roll a template change out to tasks, pause each task, PATCH its config with the new template config, and resume it.
curl --request PATCH 'https://x-trader.ai/api/v1/sniper/templates/5b9d3e1a-2c7f-4a8b-9e6d-4f1a0c3b7d92' \ --header "Authorization: Bearer $X_TRADER_API_TOKEN" \ --header 'Content-Type: application/json' \ --header 'If-Match: "v1"' \ --data '{"name": "Updated defaults"}'Delete semantics
Section titled “Delete semantics”DELETE /{kind}/templates/{id} removes the template and detaches linked tasks (the link is cleared with ON DELETE SET NULL). Tasks are not deleted, and their stored config snapshots are not changed. Templates need no pause before delete. Success is 204 with no body.
Name conflicts and the 1,000 limit
Section titled “Name conflicts and the 1,000 limit”template_name_existsis the error code for a name clash. The spec does not state the uniqueness scope (per kind or across both kinds); treat names as unique per account and pick a differentnameor rename the existing template.- Sniper and copy-trade templates share one limit of 1,000 templates in total. The spec does not name the error code returned at the limit;
quota_exceededis the only quota code in the error enum. - Templates are separate from the task configuration quota reported by
GET /me, which covers sniper, copy-trade and transfer-snipe tasks.
How a task relates to a template
Section titled “How a task relates to a template”The spec mentions linked tasks (delete detaches them) but the public API exposes no field to set or read that link: SniperCreate and CopyTradeCreate explicitly reject a template property, and task resources return no template ID. Through the API, a template therefore works as a copy source:
import osimport uuidimport requests
BASE = "https://x-trader.ai/api/v1"H = {"Authorization": f"Bearer {os.environ['X_TRADER_API_TOKEN']}"}
tpl = requests.get(f"{BASE}/copy-trade/templates/5b9d3e1a-2c7f-4a8b-9e6d-4f1a0c3b7d92", headers=H)tpl.raise_for_status()config = tpl.json()["data"]["config"]
task = requests.post( f"{BASE}/copy-trade/configs", json={ "remark": "From template", "target_wallet": "11111111111111111111111111111111", "linked_wallets": [], "config": config, }, headers={**H, "Idempotency-Key": f"copy-{uuid.uuid4()}"},)task.raise_for_status()print(task.json()["data"]["id"], task.headers["ETag"]) # created pausedBecause template list and get return the stored snapshot as is, an older template may contain legacy fields that the current task schema rejects; in that case the create fails with validation_error and error.fields points to the offending paths. Task endpoints: /xtrader/sniper/, /xtrader/copy-trade/.
Errors
Section titled “Errors”| Code | Typical cause on template endpoints |
|---|---|
validation_error |
Empty or too long name, unknown field, risk_label_id in body, config not matching the schema, empty PATCH |
template_name_exists |
Name already used |
quota_exceeded |
Likely code at the shared 1,000-template limit (not stated in the spec) |
insufficient_scope |
Missing sniper:* or copytrade:* scope for the operation |
not_found |
Unknown template ID or one owned by another user |
version_conflict |
Stale If-Match on PATCH or DELETE |
idempotency_required / idempotency_conflict |
Missing key on create, or key reused with another body |
rate_limit_exceeded, service_unavailable |
429 / 503 with Retry-After |
Error body shape and handling: /xtrader/errors/.
Does updating a template change tasks created from it?
Section titled “Does updating a template change tasks created from it?”No. A template PATCH replaces the template’s own name or config only; existing task config snapshots are not rewritten.
What happens to tasks when I delete a template?
Section titled “What happens to tasks when I delete a template?”Linked tasks are detached from the template, not deleted, and their stored config snapshots stay as they were.
How many templates can an account have?
Section titled “How many templates can an account have?”Sniper and copy-trade templates share one limit of 1,000 templates in total.
How do I create a task from a template through the API?
Section titled “How do I create a task from a template through the API?”The public task schemas have no template reference field and reject a template property. GET the template, copy its config into the task create body, and POST it as a normal sniper or copy-trade create.
Which scopes do templates need?
Section titled “Which scopes do templates need?”Sniper templates use sniper:read, sniper:write and sniper:delete. Copy-trade templates use copytrade:read, copytrade:write and copytrade:delete.