Stock Report
curl --request POST \
--url https://api.chicago.global/v1/stock-report \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"symbol": "AAPL.O",
"force": false,
"lang": "en"
}
'import requests
url = "https://api.chicago.global/v1/stock-report"
payload = {
"symbol": "AAPL.O",
"force": False,
"lang": "en"
}
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({symbol: 'AAPL.O', force: false, lang: 'en'})
};
fetch('https://api.chicago.global/v1/stock-report', 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/stock-report",
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([
'symbol' => 'AAPL.O',
'force' => false,
'lang' => 'en'
]),
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/stock-report"
payload := strings.NewReader("{\n \"symbol\": \"AAPL.O\",\n \"force\": false,\n \"lang\": \"en\"\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/stock-report")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"symbol\": \"AAPL.O\",\n \"force\": false,\n \"lang\": \"en\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chicago.global/v1/stock-report")
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 \"symbol\": \"AAPL.O\",\n \"force\": false,\n \"lang\": \"en\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"error": "<string>",
"timestamp": "<string>",
"details": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}{
"success": true,
"error": "<string>",
"timestamp": "<string>",
"details": "<string>"
}Stock
Generate Stock Report
Generate comprehensive stock report (ASYNC - returns job_id immediately).
This endpoint creates a background job for report generation. The actual generation
happens asynchronously without blocking. Use GET /jobs/{job_id} to check status.
**Response Format:**
```json
{
"job_id": "uuid-string",
"status": "pending",
"symbol": "AAPL.O",
"check_url": "/v1/jobs/{job_id}",
"estimated_duration_seconds": 300
}
```
**Workflow:**
1. POST /stock-report → Get job_id (returns in <1 second)
2. Poll GET /jobs/{job_id} every 5-10 seconds
3. When status="completed", result contains pdf_url, html_url, json_url
**Example:**
```bash
# Start generation
curl -X POST "https://api/v1/stock-report" \
-H "Authorization: Bearer key" \
-d '{"symbol":"AAPL.O","force":false}'
# Check status
curl "https://api/v1/jobs/{job_id}" -H "Authorization: Bearer key"
```
POST
/
v1
/
stock-report
Stock Report
curl --request POST \
--url https://api.chicago.global/v1/stock-report \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"symbol": "AAPL.O",
"force": false,
"lang": "en"
}
'import requests
url = "https://api.chicago.global/v1/stock-report"
payload = {
"symbol": "AAPL.O",
"force": False,
"lang": "en"
}
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({symbol: 'AAPL.O', force: false, lang: 'en'})
};
fetch('https://api.chicago.global/v1/stock-report', 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/stock-report",
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([
'symbol' => 'AAPL.O',
'force' => false,
'lang' => 'en'
]),
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/stock-report"
payload := strings.NewReader("{\n \"symbol\": \"AAPL.O\",\n \"force\": false,\n \"lang\": \"en\"\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/stock-report")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"symbol\": \"AAPL.O\",\n \"force\": false,\n \"lang\": \"en\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chicago.global/v1/stock-report")
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 \"symbol\": \"AAPL.O\",\n \"force\": false,\n \"lang\": \"en\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"error": "<string>",
"timestamp": "<string>",
"details": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}{
"success": true,
"error": "<string>",
"timestamp": "<string>",
"details": "<string>"
}How It Works
This endpoint uses async job processing for generating comprehensive stock reports:- Submit Request: POST the stock symbol to
/v1/stock-report - Receive Job ID: Get a job ID and polling URL immediately
- Poll for Status: Check
/v1/jobs/{job_id}until status iscompleted - Get Report URLs: The completed job contains URLs to PDF, HTML, and JSON reports
Report generation typically takes 5-10 minutes. Reports include financial analysis, valuation metrics, AI-generated insights, and more.
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
symbol | string | Yes | - | Stock symbol (e.g., AAPL.O for Apple Inc) |
force | boolean | No | false | Force regeneration even if recent report exists |
If
force is false and a recent report exists (generated within the last 30 days), the cached report URLs will be returned immediately.Response (202 Accepted)
When the job is created:{
"job_id": "stock-a3522a92-87ed-4be0-a912-ad56ed6a8806",
"status": "pending",
"symbol": "AAPL.O",
"force": false,
"check_url": "/v1/jobs/stock-a3522a92-87ed-4be0-a912-ad56ed6a8806",
"estimated_duration_seconds": 600,
"message": "Stock report generation started for AAPL.O. Poll the check_url to get results."
}
Completed Response
When the job completes,GET /v1/jobs/{job_id} returns:
{
"job_id": "stock-a3522a92-87ed-4be0-a912-ad56ed6a8806",
"job_type": "stock_report",
"status": "completed",
"result": {
"success": true,
"symbol": "AAPL.O",
"pdf_url": "https://storage.example.com/reports/AAPL.O/report.pdf",
"html_url": "https://storage.example.com/reports/AAPL.O/report.html",
"json_url": "https://storage.example.com/reports/AAPL.O/report.json"
}
}
Example: Polling for Results
const response = await fetch('https://api.chicago.global/v1/stock-report', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ symbol: 'AAPL.O' })
});
const { job_id } = await response.json();
// Poll every 10 seconds (reports take ~15 minutes)
const interval = setInterval(async () => {
const status = await fetch(
`https://api.chicago.global/v1/jobs/${job_id}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
).then(r => r.json());
if (status.status === 'completed') {
clearInterval(interval);
console.log('PDF:', status.result.pdf_url);
console.log('HTML:', status.result.html_url);
console.log('JSON:', status.result.json_url);
} else if (status.status === 'failed') {
clearInterval(interval);
console.error('Failed:', status.error);
} else {
console.log(`Status: ${status.status}, Progress: ${status.progress}`);
}
}, 10000);
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid symbol - no company data found |
| 401 | Invalid or missing API key |
| 500 | Internal server error |
{
"detail": "Invalid symbol 'INVALID': No company data found for this symbol."
}
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/json
Response
Job created successfully
Last modified on January 20, 2026
⌘I