curl --request POST \
--url https://api.chicago.global/v1/portfolio/validate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"portfolio": [
{
"date": "2024-01-01",
"symbol": "AAPL",
"weight": 0.25
}
],
"base_currency": "USD",
"initial_value": 10000,
"benchmark": "ACWI.OQ",
"include_transaction_costs": false,
"transaction_cost_config": {
"Singapore": {
"buy": 0.14,
"sell": 0.14
}
}
}
'import requests
url = "https://api.chicago.global/v1/portfolio/validate"
payload = {
"portfolio": [
{
"date": "2024-01-01",
"symbol": "AAPL",
"weight": 0.25
}
],
"base_currency": "USD",
"initial_value": 10000,
"benchmark": "ACWI.OQ",
"include_transaction_costs": False,
"transaction_cost_config": { "Singapore": {
"buy": 0.14,
"sell": 0.14
} }
}
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({
portfolio: [{date: '2024-01-01', symbol: 'AAPL', weight: 0.25}],
base_currency: 'USD',
initial_value: 10000,
benchmark: 'ACWI.OQ',
include_transaction_costs: false,
transaction_cost_config: {Singapore: {buy: 0.14, sell: 0.14}}
})
};
fetch('https://api.chicago.global/v1/portfolio/validate', 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://api.chicago.global/v1/portfolio/validate",
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([
'portfolio' => [
[
'date' => '2024-01-01',
'symbol' => 'AAPL',
'weight' => 0.25
]
],
'base_currency' => 'USD',
'initial_value' => 10000,
'benchmark' => 'ACWI.OQ',
'include_transaction_costs' => false,
'transaction_cost_config' => [
'Singapore' => [
'buy' => 0.14,
'sell' => 0.14
]
]
]),
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://api.chicago.global/v1/portfolio/validate"
payload := strings.NewReader("{\n \"portfolio\": [\n {\n \"date\": \"2024-01-01\",\n \"symbol\": \"AAPL\",\n \"weight\": 0.25\n }\n ],\n \"base_currency\": \"USD\",\n \"initial_value\": 10000,\n \"benchmark\": \"ACWI.OQ\",\n \"include_transaction_costs\": false,\n \"transaction_cost_config\": {\n \"Singapore\": {\n \"buy\": 0.14,\n \"sell\": 0.14\n }\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://api.chicago.global/v1/portfolio/validate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"portfolio\": [\n {\n \"date\": \"2024-01-01\",\n \"symbol\": \"AAPL\",\n \"weight\": 0.25\n }\n ],\n \"base_currency\": \"USD\",\n \"initial_value\": 10000,\n \"benchmark\": \"ACWI.OQ\",\n \"include_transaction_costs\": false,\n \"transaction_cost_config\": {\n \"Singapore\": {\n \"buy\": 0.14,\n \"sell\": 0.14\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chicago.global/v1/portfolio/validate")
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 \"portfolio\": [\n {\n \"date\": \"2024-01-01\",\n \"symbol\": \"AAPL\",\n \"weight\": 0.25\n }\n ],\n \"base_currency\": \"USD\",\n \"initial_value\": 10000,\n \"benchmark\": \"ACWI.OQ\",\n \"include_transaction_costs\": false,\n \"transaction_cost_config\": {\n \"Singapore\": {\n \"buy\": 0.14,\n \"sell\": 0.14\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"valid": true,
"error_count": 123,
"warning_count": 123,
"errors": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
],
"warnings": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
],
"normalized": {}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Validate Portfolio
Dry-run validation for a new portfolio definition (same body as /track).
Returns every validation error and warning without persisting anything. Use this client-side before calling /track to fix all issues in one pass.
curl --request POST \
--url https://api.chicago.global/v1/portfolio/validate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"portfolio": [
{
"date": "2024-01-01",
"symbol": "AAPL",
"weight": 0.25
}
],
"base_currency": "USD",
"initial_value": 10000,
"benchmark": "ACWI.OQ",
"include_transaction_costs": false,
"transaction_cost_config": {
"Singapore": {
"buy": 0.14,
"sell": 0.14
}
}
}
'import requests
url = "https://api.chicago.global/v1/portfolio/validate"
payload = {
"portfolio": [
{
"date": "2024-01-01",
"symbol": "AAPL",
"weight": 0.25
}
],
"base_currency": "USD",
"initial_value": 10000,
"benchmark": "ACWI.OQ",
"include_transaction_costs": False,
"transaction_cost_config": { "Singapore": {
"buy": 0.14,
"sell": 0.14
} }
}
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({
portfolio: [{date: '2024-01-01', symbol: 'AAPL', weight: 0.25}],
base_currency: 'USD',
initial_value: 10000,
benchmark: 'ACWI.OQ',
include_transaction_costs: false,
transaction_cost_config: {Singapore: {buy: 0.14, sell: 0.14}}
})
};
fetch('https://api.chicago.global/v1/portfolio/validate', 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://api.chicago.global/v1/portfolio/validate",
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([
'portfolio' => [
[
'date' => '2024-01-01',
'symbol' => 'AAPL',
'weight' => 0.25
]
],
'base_currency' => 'USD',
'initial_value' => 10000,
'benchmark' => 'ACWI.OQ',
'include_transaction_costs' => false,
'transaction_cost_config' => [
'Singapore' => [
'buy' => 0.14,
'sell' => 0.14
]
]
]),
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://api.chicago.global/v1/portfolio/validate"
payload := strings.NewReader("{\n \"portfolio\": [\n {\n \"date\": \"2024-01-01\",\n \"symbol\": \"AAPL\",\n \"weight\": 0.25\n }\n ],\n \"base_currency\": \"USD\",\n \"initial_value\": 10000,\n \"benchmark\": \"ACWI.OQ\",\n \"include_transaction_costs\": false,\n \"transaction_cost_config\": {\n \"Singapore\": {\n \"buy\": 0.14,\n \"sell\": 0.14\n }\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://api.chicago.global/v1/portfolio/validate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"portfolio\": [\n {\n \"date\": \"2024-01-01\",\n \"symbol\": \"AAPL\",\n \"weight\": 0.25\n }\n ],\n \"base_currency\": \"USD\",\n \"initial_value\": 10000,\n \"benchmark\": \"ACWI.OQ\",\n \"include_transaction_costs\": false,\n \"transaction_cost_config\": {\n \"Singapore\": {\n \"buy\": 0.14,\n \"sell\": 0.14\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chicago.global/v1/portfolio/validate")
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 \"portfolio\": [\n {\n \"date\": \"2024-01-01\",\n \"symbol\": \"AAPL\",\n \"weight\": 0.25\n }\n ],\n \"base_currency\": \"USD\",\n \"initial_value\": 10000,\n \"benchmark\": \"ACWI.OQ\",\n \"include_transaction_costs\": false,\n \"transaction_cost_config\": {\n \"Singapore\": {\n \"buy\": 0.14,\n \"sell\": 0.14\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"valid": true,
"error_count": 123,
"warning_count": 123,
"errors": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
],
"warnings": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
],
"normalized": {}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Request model for creating a tracked portfolio.
List of portfolio holdings with dates and weights
Show child attributes
Show child attributes
Base currency for portfolio
"USD"
Initial portfolio value in base currency
10000
Benchmark for comparison
"ACWI.OQ"
Apply market-specific transaction costs during rebalancing
false
Custom transaction cost rates by market. Format: {'market_name': {'buy': rate, 'sell': rate}}.
{
"Singapore": { "buy": 0.14, "sell": 0.14 }
}
Response
Successful Response
True when the portfolio would pass track/update validation
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Portfolio definition after weight renormalization (only when valid)