const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/routes', {
method: 'POST',
headers: {
'content-type': 'application/json',
Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,
"Idempotency-Key": "example-request-1",
},
body: JSON.stringify({
"routeId": "lp-primary",
"name": "Primary LP",
"mode": "external",
"connectionId": "00000000-0000-0000-0000-000000000001",
"externalAccountId": "EXT-LP",
"collar": {
"kind": "ticks",
"maxAdverseTicks": 4
},
"feeReservePerUnit": "2.50",
"uncappedMarketAllowed": false,
"expectedRevision": null
}),
})
const data = await res.json()curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/routes' \
-H "Authorization: Bearer $TRDRS_VENUE_KEY" \
-H 'Idempotency-Key: example-request-1' \
-H 'content-type: application/json' \
-d '{"routeId":"lp-primary","name":"Primary LP","mode":"external","connectionId":"00000000-0000-0000-0000-000000000001","externalAccountId":"EXT-LP","collar":{"kind":"ticks","maxAdverseTicks":4},"feeReservePerUnit":"2.50","uncappedMarketAllowed":false,"expectedRevision":null}'import requests
url = "https://app.trdrs.co/api/partner/venues/{venueId}/routes"
payload = {
"routeId": "lp-primary",
"name": "Primary LP",
"mode": "external",
"connectionId": "00000000-0000-0000-0000-000000000001",
"externalAccountId": "EXT-LP",
"collar": {
"kind": "ticks",
"maxAdverseTicks": 4
},
"feeReservePerUnit": "2.50",
"uncappedMarketAllowed": False,
"expectedRevision": None
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.trdrs.co/api/partner/venues/{venueId}/routes",
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([
'routeId' => 'lp-primary',
'name' => 'Primary LP',
'mode' => 'external',
'connectionId' => '00000000-0000-0000-0000-000000000001',
'externalAccountId' => 'EXT-LP',
'collar' => [
'kind' => 'ticks',
'maxAdverseTicks' => 4
],
'feeReservePerUnit' => '2.50',
'uncappedMarketAllowed' => false,
'expectedRevision' => null
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-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://app.trdrs.co/api/partner/venues/{venueId}/routes"
payload := strings.NewReader("{\n \"routeId\": \"lp-primary\",\n \"name\": \"Primary LP\",\n \"mode\": \"external\",\n \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n \"externalAccountId\": \"EXT-LP\",\n \"collar\": {\n \"kind\": \"ticks\",\n \"maxAdverseTicks\": 4\n },\n \"feeReservePerUnit\": \"2.50\",\n \"uncappedMarketAllowed\": false,\n \"expectedRevision\": null\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
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://app.trdrs.co/api/partner/venues/{venueId}/routes")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"routeId\": \"lp-primary\",\n \"name\": \"Primary LP\",\n \"mode\": \"external\",\n \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n \"externalAccountId\": \"EXT-LP\",\n \"collar\": {\n \"kind\": \"ticks\",\n \"maxAdverseTicks\": 4\n },\n \"feeReservePerUnit\": \"2.50\",\n \"uncappedMarketAllowed\": false,\n \"expectedRevision\": null\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.trdrs.co/api/partner/venues/{venueId}/routes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"routeId\": \"lp-primary\",\n \"name\": \"Primary LP\",\n \"mode\": \"external\",\n \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n \"externalAccountId\": \"EXT-LP\",\n \"collar\": {\n \"kind\": \"ticks\",\n \"maxAdverseTicks\": 4\n },\n \"feeReservePerUnit\": \"2.50\",\n \"uncappedMarketAllowed\": false,\n \"expectedRevision\": null\n}"
response = http.request(request)
puts response.read_body{
"route": {
"routeId": "lp-primary",
"name": "Primary LP",
"mode": "external",
"connectionId": "00000000-0000-0000-0000-000000000001",
"externalAccountId": "EXT-LP",
"state": "offered",
"revision": 1,
"version": "lp-primary:1"
}
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}Create or update a route
Private preview, disabled unless VENUE_CONFIGURATION_ENABLED is enabled and the vault is configured. This branch has not enabled these routes in the public sandbox. Existing trdrs_sk partner/tenant keys do not authorize these routes. Requires venue:configure. Compare-and-swap on expectedRevision, null to create. An external route must name both connectionId and externalAccountId and an internal route neither, so a half-configured route is refused here rather than at the first order it swallows. Moving a route’s mode, connection or account waits for the accounts on it to be flat; a rename or a retirement does not. Retiring stops it being offered to new groups and keeps it serving the ones already on it. An omitted collar is zero adverse ticks, which is the strictest reading and not “no collar”; WIDENING one waits for quiescence like a mode change, because it changes the worst case of a trade already in flight. uncappedMarketAllowed defaults to false and is refused outright on an internal route, where there is no provider cap to defer to and the collar is the protection.
const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/routes', {
method: 'POST',
headers: {
'content-type': 'application/json',
Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,
"Idempotency-Key": "example-request-1",
},
body: JSON.stringify({
"routeId": "lp-primary",
"name": "Primary LP",
"mode": "external",
"connectionId": "00000000-0000-0000-0000-000000000001",
"externalAccountId": "EXT-LP",
"collar": {
"kind": "ticks",
"maxAdverseTicks": 4
},
"feeReservePerUnit": "2.50",
"uncappedMarketAllowed": false,
"expectedRevision": null
}),
})
const data = await res.json()curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/routes' \
-H "Authorization: Bearer $TRDRS_VENUE_KEY" \
-H 'Idempotency-Key: example-request-1' \
-H 'content-type: application/json' \
-d '{"routeId":"lp-primary","name":"Primary LP","mode":"external","connectionId":"00000000-0000-0000-0000-000000000001","externalAccountId":"EXT-LP","collar":{"kind":"ticks","maxAdverseTicks":4},"feeReservePerUnit":"2.50","uncappedMarketAllowed":false,"expectedRevision":null}'import requests
url = "https://app.trdrs.co/api/partner/venues/{venueId}/routes"
payload = {
"routeId": "lp-primary",
"name": "Primary LP",
"mode": "external",
"connectionId": "00000000-0000-0000-0000-000000000001",
"externalAccountId": "EXT-LP",
"collar": {
"kind": "ticks",
"maxAdverseTicks": 4
},
"feeReservePerUnit": "2.50",
"uncappedMarketAllowed": False,
"expectedRevision": None
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.trdrs.co/api/partner/venues/{venueId}/routes",
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([
'routeId' => 'lp-primary',
'name' => 'Primary LP',
'mode' => 'external',
'connectionId' => '00000000-0000-0000-0000-000000000001',
'externalAccountId' => 'EXT-LP',
'collar' => [
'kind' => 'ticks',
'maxAdverseTicks' => 4
],
'feeReservePerUnit' => '2.50',
'uncappedMarketAllowed' => false,
'expectedRevision' => null
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-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://app.trdrs.co/api/partner/venues/{venueId}/routes"
payload := strings.NewReader("{\n \"routeId\": \"lp-primary\",\n \"name\": \"Primary LP\",\n \"mode\": \"external\",\n \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n \"externalAccountId\": \"EXT-LP\",\n \"collar\": {\n \"kind\": \"ticks\",\n \"maxAdverseTicks\": 4\n },\n \"feeReservePerUnit\": \"2.50\",\n \"uncappedMarketAllowed\": false,\n \"expectedRevision\": null\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
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://app.trdrs.co/api/partner/venues/{venueId}/routes")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"routeId\": \"lp-primary\",\n \"name\": \"Primary LP\",\n \"mode\": \"external\",\n \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n \"externalAccountId\": \"EXT-LP\",\n \"collar\": {\n \"kind\": \"ticks\",\n \"maxAdverseTicks\": 4\n },\n \"feeReservePerUnit\": \"2.50\",\n \"uncappedMarketAllowed\": false,\n \"expectedRevision\": null\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.trdrs.co/api/partner/venues/{venueId}/routes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"routeId\": \"lp-primary\",\n \"name\": \"Primary LP\",\n \"mode\": \"external\",\n \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n \"externalAccountId\": \"EXT-LP\",\n \"collar\": {\n \"kind\": \"ticks\",\n \"maxAdverseTicks\": 4\n },\n \"feeReservePerUnit\": \"2.50\",\n \"uncappedMarketAllowed\": false,\n \"expectedRevision\": null\n}"
response = http.request(request)
puts response.read_body{
"route": {
"routeId": "lp-primary",
"name": "Primary LP",
"mode": "external",
"connectionId": "00000000-0000-0000-0000-000000000001",
"externalAccountId": "EXT-LP",
"state": "offered",
"revision": 1,
"version": "lp-primary:1"
}
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}{
"error": "invalid_instrument"
}Authorizations
Private-preview venue operator key (trdrs_vk_sandbox_… or trdrs_vk_production_…). Bound to one venue/environment and explicit scopes. Issued by a verified owner session; accepted only on documented /api/partner/venues/{venueId} routes. Existing trdrs_sk keys are not interchangeable. Never grants trader, login or key-management authority.
Headers
1 - 128Path Parameters
Body
internal, external offered, retired How far past a fresh executable quote a fill may still be accepted. A tick count means the same thing at every price level and is the only shape permitted where prices can print negative; a proportional allowance against a negative base widens as the price falls and inverts through zero.
- Option 1
- Option 2
Show child attributes
Show child attributes
Exact base-ten decimal string, at most 18 fractional digits. No exponent notation or binary floating-point conversion.
x >= 1Response
Scoped result. Cache-Control: no-store.
Where a group's orders go, and what protects an order sent there. An external route names both its connection and the dedicated account at it; an internal one names neither. version is what a command pins, so a fill can be attributed to the exact policy it was dispatched under.
Show child attributes
Show child attributes