curl --request POST \
--url https://testnet.edel-api.xyz/v1/accounts/{accountId}/agents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"strategySource": "strategy_lab",
"strategyCode": "//@version=5\nstrategy(\"Close above open\")\nif close > open\n strategy.entry(\"L\", strategy.long)\nif close < open\n strategy.close(\"L\")\n",
"marketSelection": {
"kind": "explicit",
"marketIds": [
"BTC-USDCX-PERP"
]
},
"mode": "paper",
"parameters": {
"timeframe": "1m",
"orderSizeAtoms": "1000",
"historyBars": 300
}
}
'import requests
url = "https://testnet.edel-api.xyz/v1/accounts/{accountId}/agents"
payload = {
"strategySource": "strategy_lab",
"strategyCode": "//@version=5
strategy(\"Close above open\")
if close > open
strategy.entry(\"L\", strategy.long)
if close < open
strategy.close(\"L\")
",
"marketSelection": {
"kind": "explicit",
"marketIds": ["BTC-USDCX-PERP"]
},
"mode": "paper",
"parameters": {
"timeframe": "1m",
"orderSizeAtoms": "1000",
"historyBars": 300
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
strategySource: 'strategy_lab',
strategyCode: '//@version=5\nstrategy("Close above open")\nif close > open\n strategy.entry("L", strategy.long)\nif close < open\n strategy.close("L")\n',
marketSelection: {kind: 'explicit', marketIds: ['BTC-USDCX-PERP']},
mode: 'paper',
parameters: {timeframe: '1m', orderSizeAtoms: '1000', historyBars: 300}
})
};
fetch('https://testnet.edel-api.xyz/v1/accounts/{accountId}/agents', 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://testnet.edel-api.xyz/v1/accounts/{accountId}/agents",
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([
'strategySource' => 'strategy_lab',
'strategyCode' => '//@version=5
strategy("Close above open")
if close > open
strategy.entry("L", strategy.long)
if close < open
strategy.close("L")
',
'marketSelection' => [
'kind' => 'explicit',
'marketIds' => [
'BTC-USDCX-PERP'
]
],
'mode' => 'paper',
'parameters' => [
'timeframe' => '1m',
'orderSizeAtoms' => '1000',
'historyBars' => 300
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://testnet.edel-api.xyz/v1/accounts/{accountId}/agents"
payload := strings.NewReader("{\n \"strategySource\": \"strategy_lab\",\n \"strategyCode\": \"//@version=5\\nstrategy(\\\"Close above open\\\")\\nif close > open\\n strategy.entry(\\\"L\\\", strategy.long)\\nif close < open\\n strategy.close(\\\"L\\\")\\n\",\n \"marketSelection\": {\n \"kind\": \"explicit\",\n \"marketIds\": [\n \"BTC-USDCX-PERP\"\n ]\n },\n \"mode\": \"paper\",\n \"parameters\": {\n \"timeframe\": \"1m\",\n \"orderSizeAtoms\": \"1000\",\n \"historyBars\": 300\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://testnet.edel-api.xyz/v1/accounts/{accountId}/agents")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"strategySource\": \"strategy_lab\",\n \"strategyCode\": \"//@version=5\\nstrategy(\\\"Close above open\\\")\\nif close > open\\n strategy.entry(\\\"L\\\", strategy.long)\\nif close < open\\n strategy.close(\\\"L\\\")\\n\",\n \"marketSelection\": {\n \"kind\": \"explicit\",\n \"marketIds\": [\n \"BTC-USDCX-PERP\"\n ]\n },\n \"mode\": \"paper\",\n \"parameters\": {\n \"timeframe\": \"1m\",\n \"orderSizeAtoms\": \"1000\",\n \"historyBars\": 300\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://testnet.edel-api.xyz/v1/accounts/{accountId}/agents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"strategySource\": \"strategy_lab\",\n \"strategyCode\": \"//@version=5\\nstrategy(\\\"Close above open\\\")\\nif close > open\\n strategy.entry(\\\"L\\\", strategy.long)\\nif close < open\\n strategy.close(\\\"L\\\")\\n\",\n \"marketSelection\": {\n \"kind\": \"explicit\",\n \"marketIds\": [\n \"BTC-USDCX-PERP\"\n ]\n },\n \"mode\": \"paper\",\n \"parameters\": {\n \"timeframe\": \"1m\",\n \"orderSizeAtoms\": \"1000\",\n \"historyBars\": 300\n }\n}"
response = http.request(request)
puts response.read_body{
"deployment": {
"deploymentId": "<string>",
"ownerAccountId": "<string>",
"strategySource": "strategy_lab",
"strategyVersion": "<string>",
"marketId": "<string>",
"marketSelection": {
"kind": "explicit",
"marketIds": [
"<string>"
]
},
"selectedMarketIds": [
"<string>"
],
"selectedAtEpochMs": 123,
"marketDecisionModel": {
"modelId": "<string>",
"version": "<string>",
"dataPolicy": "in_network",
"fallbackUsed": true,
"primaryFailure": "model_unknown"
},
"marketSelectionReason": "<string>",
"agentAccountId": "<string>",
"agentTraderAccountId": "<string>",
"identityStatus": "identity_pending",
"mode": "paper",
"state": "awaiting_funding",
"pauseReason": "owner_request",
"stateVersion": 123,
"parameters": {
"orderSizeAtoms": "<string>",
"timeframe": "1m",
"historyBars": 300
},
"createdAtEpochMs": 123,
"updatedAtEpochMs": 123,
"modelId": "<string>",
"fallbackModelId": "<string>",
"agentPartyId": "<string>"
}
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}Deploy a strategy agent in paper or live mode
Deploys a deterministic Pine strategy independently on 1 to 32 listed venue markets. marketSelection accepts an explicit marketIds list or auto. Auto asks the venue’s decision model (named by GET /v1/agents/market-selection) whether the strategy suits each listed market and keeps only the markets it answers yes to with at least 90% probability; it records the model, the selected markets and the reason at deployment. When no market reaches that bar auto answers 409 command_rejected and creates nothing, so choose the markets yourself; when the decision model is unavailable it answers 503 service_degraded. The decision model chooses markets only: the strategy alone decides each action; legacy marketId selects one market. agentAccountId binds an owned, ready agent trader account to this deployment permanently, including after stop or delete. The agent decides on closed bars. In paper mode it records simulated paper fills against the public book and trades; it never places an order and never moves funds. Live mode trades from the bound agent account only, never the owner account, and only where the venue enables live agents: elsewhere it answers 400 invalid_request. A live agent with agentAccountId needs that owned, ready agent account (else 404 not_found) and a completed funding receipt on it (else 409 command_rejected), and starts pending. A live agent without agentAccountId gets its own new agent account: send an Idempotency-Key header (else 400 idempotency_key_required); the agent starts awaiting_funding with that account’s agentAccountId, agentTraderAccountId and identityStatus; once identityStatus is identity_ready it also carries agentPartyId, the agent account’s Canton Party id the owner deposits to, which is null before. A retry with the same Idempotency-Key and body answers the same agent and resumes an identity_pending setup. The same Idempotency-Key with another body answers 409 command_rejected, and one whose agent was deleted answers 404 not_found. The request waits at most 20 seconds for the account setup; past that it answers with identityStatus identity_pending while the setup continues, and activate or the same request resumes it. An account’s live creates make at most 5 new agent accounts per UTC day, stopped or deleted agents included; one more answers 409 command_rejected. Fund that agent account, then start the agent with the activate route. Its orders are market orders with a notional of at most 20 percent of the agent account equity, at most 5 open orders, at least 10 seconds apart, and reduce only once equity falls below half the funded amount; a refused order answers its closed reason. An account holds at most 3 agents that are not stopped; one more answers 409 command_rejected. An invalid strategy source or an unlisted market answers 400 invalid_request. Requires the owner’s passkey session or an API key with the agents scope, which the owner grants with a passkey on the agent connect approval page. Available on TestNet and Development only; elsewhere the route answers 503 operation_not_available.
Method and path: POST /v1/accounts//agents
Authentication: DFNS trader bearer required.
Request schema: CreateAgentDeploymentRequest.
Response schema: AgentDeploymentResponse.
Error envelope: ExternalRestError (external-rest-error/v1).
curl --request POST \
--url https://testnet.edel-api.xyz/v1/accounts/{accountId}/agents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"strategySource": "strategy_lab",
"strategyCode": "//@version=5\nstrategy(\"Close above open\")\nif close > open\n strategy.entry(\"L\", strategy.long)\nif close < open\n strategy.close(\"L\")\n",
"marketSelection": {
"kind": "explicit",
"marketIds": [
"BTC-USDCX-PERP"
]
},
"mode": "paper",
"parameters": {
"timeframe": "1m",
"orderSizeAtoms": "1000",
"historyBars": 300
}
}
'import requests
url = "https://testnet.edel-api.xyz/v1/accounts/{accountId}/agents"
payload = {
"strategySource": "strategy_lab",
"strategyCode": "//@version=5
strategy(\"Close above open\")
if close > open
strategy.entry(\"L\", strategy.long)
if close < open
strategy.close(\"L\")
",
"marketSelection": {
"kind": "explicit",
"marketIds": ["BTC-USDCX-PERP"]
},
"mode": "paper",
"parameters": {
"timeframe": "1m",
"orderSizeAtoms": "1000",
"historyBars": 300
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
strategySource: 'strategy_lab',
strategyCode: '//@version=5\nstrategy("Close above open")\nif close > open\n strategy.entry("L", strategy.long)\nif close < open\n strategy.close("L")\n',
marketSelection: {kind: 'explicit', marketIds: ['BTC-USDCX-PERP']},
mode: 'paper',
parameters: {timeframe: '1m', orderSizeAtoms: '1000', historyBars: 300}
})
};
fetch('https://testnet.edel-api.xyz/v1/accounts/{accountId}/agents', 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://testnet.edel-api.xyz/v1/accounts/{accountId}/agents",
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([
'strategySource' => 'strategy_lab',
'strategyCode' => '//@version=5
strategy("Close above open")
if close > open
strategy.entry("L", strategy.long)
if close < open
strategy.close("L")
',
'marketSelection' => [
'kind' => 'explicit',
'marketIds' => [
'BTC-USDCX-PERP'
]
],
'mode' => 'paper',
'parameters' => [
'timeframe' => '1m',
'orderSizeAtoms' => '1000',
'historyBars' => 300
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://testnet.edel-api.xyz/v1/accounts/{accountId}/agents"
payload := strings.NewReader("{\n \"strategySource\": \"strategy_lab\",\n \"strategyCode\": \"//@version=5\\nstrategy(\\\"Close above open\\\")\\nif close > open\\n strategy.entry(\\\"L\\\", strategy.long)\\nif close < open\\n strategy.close(\\\"L\\\")\\n\",\n \"marketSelection\": {\n \"kind\": \"explicit\",\n \"marketIds\": [\n \"BTC-USDCX-PERP\"\n ]\n },\n \"mode\": \"paper\",\n \"parameters\": {\n \"timeframe\": \"1m\",\n \"orderSizeAtoms\": \"1000\",\n \"historyBars\": 300\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://testnet.edel-api.xyz/v1/accounts/{accountId}/agents")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"strategySource\": \"strategy_lab\",\n \"strategyCode\": \"//@version=5\\nstrategy(\\\"Close above open\\\")\\nif close > open\\n strategy.entry(\\\"L\\\", strategy.long)\\nif close < open\\n strategy.close(\\\"L\\\")\\n\",\n \"marketSelection\": {\n \"kind\": \"explicit\",\n \"marketIds\": [\n \"BTC-USDCX-PERP\"\n ]\n },\n \"mode\": \"paper\",\n \"parameters\": {\n \"timeframe\": \"1m\",\n \"orderSizeAtoms\": \"1000\",\n \"historyBars\": 300\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://testnet.edel-api.xyz/v1/accounts/{accountId}/agents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"strategySource\": \"strategy_lab\",\n \"strategyCode\": \"//@version=5\\nstrategy(\\\"Close above open\\\")\\nif close > open\\n strategy.entry(\\\"L\\\", strategy.long)\\nif close < open\\n strategy.close(\\\"L\\\")\\n\",\n \"marketSelection\": {\n \"kind\": \"explicit\",\n \"marketIds\": [\n \"BTC-USDCX-PERP\"\n ]\n },\n \"mode\": \"paper\",\n \"parameters\": {\n \"timeframe\": \"1m\",\n \"orderSizeAtoms\": \"1000\",\n \"historyBars\": 300\n }\n}"
response = http.request(request)
puts response.read_body{
"deployment": {
"deploymentId": "<string>",
"ownerAccountId": "<string>",
"strategySource": "strategy_lab",
"strategyVersion": "<string>",
"marketId": "<string>",
"marketSelection": {
"kind": "explicit",
"marketIds": [
"<string>"
]
},
"selectedMarketIds": [
"<string>"
],
"selectedAtEpochMs": 123,
"marketDecisionModel": {
"modelId": "<string>",
"version": "<string>",
"dataPolicy": "in_network",
"fallbackUsed": true,
"primaryFailure": "model_unknown"
},
"marketSelectionReason": "<string>",
"agentAccountId": "<string>",
"agentTraderAccountId": "<string>",
"identityStatus": "identity_pending",
"mode": "paper",
"state": "awaiting_funding",
"pauseReason": "owner_request",
"stateVersion": 123,
"parameters": {
"orderSizeAtoms": "<string>",
"timeframe": "1m",
"historyBars": 300
},
"createdAtEpochMs": 123,
"updatedAtEpochMs": 123,
"modelId": "<string>",
"fallbackModelId": "<string>",
"agentPartyId": "<string>"
}
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "invalid_request",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "amount_atoms_invalid",
"withdrawalFailure": "requested",
"dependency": "dfns"
}Authorizations
The authorization field takes the session bearer returned by sign-in, or an API key where the route allows keys. Paste the token itself into the authorization field.
Path Parameters
1Body
strategy_lab 1 - 20000paper, live Show child attributes
Show child attributes
1 - 64- Option 1
- Option 2
Show child attributes
Show child attributes
^aga_[0-9a-f]{32}$Show child attributes
Show child attributes
Response
Created
Show child attributes
Show child attributes