curl --request POST \
--url https://api.chicago.global/v1/builder \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"query": "Find me top 50 electric vehicle companies in Asia",
"markets": [
"<string>"
],
"sectors": [
"<string>"
],
"strict_theme": true,
"rerank": true,
"min_relevance": 0.5
}
'import requests
url = "https://api.chicago.global/v1/builder"
payload = {
"query": "Find me top 50 electric vehicle companies in Asia",
"markets": ["<string>"],
"sectors": ["<string>"],
"strict_theme": True,
"rerank": True,
"min_relevance": 0.5
}
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({
query: 'Find me top 50 electric vehicle companies in Asia',
markets: ['<string>'],
sectors: ['<string>'],
strict_theme: true,
rerank: true,
min_relevance: 0.5
})
};
fetch('https://api.chicago.global/v1/builder', 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/builder",
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([
'query' => 'Find me top 50 electric vehicle companies in Asia',
'markets' => [
'<string>'
],
'sectors' => [
'<string>'
],
'strict_theme' => true,
'rerank' => true,
'min_relevance' => 0.5
]),
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/builder"
payload := strings.NewReader("{\n \"query\": \"Find me top 50 electric vehicle companies in Asia\",\n \"markets\": [\n \"<string>\"\n ],\n \"sectors\": [\n \"<string>\"\n ],\n \"strict_theme\": true,\n \"rerank\": true,\n \"min_relevance\": 0.5\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/builder")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"Find me top 50 electric vehicle companies in Asia\",\n \"markets\": [\n \"<string>\"\n ],\n \"sectors\": [\n \"<string>\"\n ],\n \"strict_theme\": true,\n \"rerank\": true,\n \"min_relevance\": 0.5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chicago.global/v1/builder")
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 \"query\": \"Find me top 50 electric vehicle companies in Asia\",\n \"markets\": [\n \"<string>\"\n ],\n \"sectors\": [\n \"<string>\"\n ],\n \"strict_theme\": true,\n \"rerank\": true,\n \"min_relevance\": 0.5\n}"
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Universe Builder
Build a thematic stock universe (ASYNC - returns job_id immediately).
Accepts a natural language query (e.g., “top 50 EV companies in Asia”, “fintech startups”, “gene therapy pure plays”). An LLM interprets the query to extract the theme, filters, and parameters, then searches ~65K company descriptions to find relevant stocks ranked by relevance score.
Typically takes 15-40 seconds. Use GET /jobs/ to check status and retrieve results.
curl --request POST \
--url https://api.chicago.global/v1/builder \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"query": "Find me top 50 electric vehicle companies in Asia",
"markets": [
"<string>"
],
"sectors": [
"<string>"
],
"strict_theme": true,
"rerank": true,
"min_relevance": 0.5
}
'import requests
url = "https://api.chicago.global/v1/builder"
payload = {
"query": "Find me top 50 electric vehicle companies in Asia",
"markets": ["<string>"],
"sectors": ["<string>"],
"strict_theme": True,
"rerank": True,
"min_relevance": 0.5
}
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({
query: 'Find me top 50 electric vehicle companies in Asia',
markets: ['<string>'],
sectors: ['<string>'],
strict_theme: true,
rerank: true,
min_relevance: 0.5
})
};
fetch('https://api.chicago.global/v1/builder', 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/builder",
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([
'query' => 'Find me top 50 electric vehicle companies in Asia',
'markets' => [
'<string>'
],
'sectors' => [
'<string>'
],
'strict_theme' => true,
'rerank' => true,
'min_relevance' => 0.5
]),
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/builder"
payload := strings.NewReader("{\n \"query\": \"Find me top 50 electric vehicle companies in Asia\",\n \"markets\": [\n \"<string>\"\n ],\n \"sectors\": [\n \"<string>\"\n ],\n \"strict_theme\": true,\n \"rerank\": true,\n \"min_relevance\": 0.5\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/builder")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"Find me top 50 electric vehicle companies in Asia\",\n \"markets\": [\n \"<string>\"\n ],\n \"sectors\": [\n \"<string>\"\n ],\n \"strict_theme\": true,\n \"rerank\": true,\n \"min_relevance\": 0.5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chicago.global/v1/builder")
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 \"query\": \"Find me top 50 electric vehicle companies in Asia\",\n \"markets\": [\n \"<string>\"\n ],\n \"sectors\": [\n \"<string>\"\n ],\n \"strict_theme\": true,\n \"rerank\": true,\n \"min_relevance\": 0.5\n}"
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}How It Works
This endpoint uses async job processing:- Submit Request: POST with a natural language query
- Receive Job ID: Get a job ID and polling URL immediately
- Poll for Status: Check
/v1/jobs/{job_id}until status iscompleted - Get Results: The completed job contains a ranked list of matching companies
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Natural language query describing the investment theme and any filters (2-500 characters) |
{
"query": "Find me top 50 electric vehicle companies in Asia"
}
Response (202 Accepted)
{
"job_id": "e2035316-0042-437a-9353-4b224f304d5a",
"status": "pending",
"query": "Top 20 electric vehicle companies in Asia",
"check_url": "/v1/jobs/e2035316-0042-437a-9353-4b224f304d5a",
"estimated_duration_seconds": 30,
"message": "Building stock universe for 'Top 20 electric vehicle companies in Asia'."
}
Completed Response
When the job completes,GET /v1/jobs/{job_id} returns the matched companies:
{
"job_id": "e2035316-0042-437a-9353-4b224f304d5a",
"status": "completed",
"result": {
"total_matches": 546,
"results_returned": 20,
"category_breakdown": {
"core": 18,
"peripheral": 2
},
"companies": [
{
"ric": "3677.HK",
"name": "Jiangsu Zenergy Battery Technologies Group Co Ltd",
"sector": "Industrials",
"market": "China",
"exchange": "Hong Kong",
"activity": "Active",
"market_cap": 12624996781.5,
"category": "core",
"composite_score": 249.43
},
{
"ric": "005380.KS",
"name": "Hyundai Motor Co",
"sector": "Consumer Cyclicals",
"market": "South Korea",
"exchange": "Korea",
"activity": "Active",
"market_cap": 91219584753000.0,
"category": "core",
"composite_score": 141.13
},
{
"ric": "0175.HK",
"name": "Geely Automobile Holdings Ltd",
"sector": "Consumer Cyclicals",
"market": "Hong Kong",
"exchange": "Hong Kong",
"activity": "Active",
"market_cap": 225892816535.3,
"category": "core",
"composite_score": 108.08
}
]
}
}
Company Fields
| Field | Description |
|---|---|
ric | Reuters Instrument Code (unique stock identifier) |
name | Company name |
sector | Business sector classification |
market | Country/market where the company is listed |
exchange | Stock exchange name |
activity | Company status (e.g., Active) |
market_cap | Market capitalization (in local currency) |
category | Match category: core (strongest match), peripheral, or satellite |
composite_score | Relevance score — higher means stronger thematic match |
Query Tips
The agent works best with specific, descriptive queries:| Good Queries | Why |
|---|---|
| ”Top 50 electric vehicle battery manufacturers in Asia” | Specific theme + region + count |
| ”Gene therapy and CRISPR companies with market cap over $1B” | Specific technology + size filter |
| ”Semiconductor lithography and chip fabrication equipment” | Narrow technical theme |
| Weak Queries | Why |
|---|---|
| ”Technology stocks” | Too broad — thousands of matches |
| ”Good companies” | No investable theme |
| ”Stocks” | Not actionable |
Supported Regions
When your query mentions a geography, the agent can filter by:- Regions: Europe, Asia, Americas, Middle East, Oceania
- Countries: United States, United Kingdom, Japan, South Korea, China, Hong Kong, Taiwan, Singapore, India, Germany, France, Canada, Brazil, Australia, Saudi Arabia, UAE, Thailand, Malaysia, Indonesia, and 20+ more
Example
curl -X POST "https://api.chicago.global/v1/builder" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "Top 30 AI infrastructure and data center companies"}'
const response = await fetch('https://api.chicago.global/v1/builder', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: 'Top 30 AI infrastructure and data center companies'
})
});
const { job_id, check_url } = await response.json();
// Poll for results
const interval = setInterval(async () => {
const status = await fetch(
`https://api.chicago.global${check_url}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
).then(r => r.json());
if (status.status === 'completed') {
clearInterval(interval);
const { companies, total_matches } = status.result;
console.log(`Found ${total_matches} matches, returned ${companies.length}`);
companies.forEach(c => {
console.log(`${c.name} (${c.ric}) — ${c.market}, score: ${c.composite_score}`);
});
} else if (status.status === 'failed') {
clearInterval(interval);
console.error('Failed:', status.error);
}
}, 5000);
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Request model for thematic stock universe builder.
Natural language query describing the investment theme and any filters
2 - 500"Find me top 50 electric vehicle companies in Asia"
Exact market names (e.g. 'United States', 'Japan'). Unknown names match zero companies.
1Geographic region filter — a single region or a list of them, which UNION together. Takes precedence over markets if both are set. Valid: Europe, Asia, Southeast Asia, South Asia, East Asia, Americas, Middle East, Oceania.
Europe, Asia, Southeast Asia, South Asia, East Asia, Americas, Middle East, Oceania TRBC sector names; GICS-11 names accepted and normalized (case-insensitive).
1Require a keyword match as well as thematic relevance. Disable for broader recall. Narrow themes may return fewer companies than requested.
Optionally rerank results by semantic similarity to the theme. Omit to use the server default. If reranking is unavailable, the original order is retained; inspect rerank.applied in the result.
Optional similarity threshold from 0 to 1, applied only when reranking is active. Companies without similarity data are retained. The returned similarity itself is not guaranteed to be within this interval.
0 <= x <= 1Response
Successful Response