Query Financial Data via API with ChatGPT, Claude, or Any LLM
Use your AI to generate Python code that queries the Ceta Research API. Give it the endpoint docs, ask a question, run the code locally.
This guide is for developers using CLI-based AI tools (Claude Code, Cursor, Windsurf, Codex) that can execute code directly. The AI writes Python code, runs it, and displays results within your terminal session.
If you use web-based AI tools (ChatGPT, Claude.ai, Gemini), Guide 1 is a better fit. Those tools can generate SQL but cannot make API calls, so the copy-paste workflow is faster and simpler.
Prerequisites
- A Ceta Research API key (cetaresearch.com, Settings, API Keys)
- A CLI-based AI tool: Claude Code, Cursor, Windsurf, or similar
- Python 3.8+ with
requestsinstalled
Setup
Step 1: Set your API key
export CR_API_KEY="cr_your_key_here"
Add to ~/.zshrc or ~/.bashrc so it persists across sessions.
Step 2: Give the AI the API context
Paste this into your AI tool or add it to your project's configuration file (CLAUDE.md, .cursorrules, etc.):
Ceta Research API for financial data queries.
API key is in CR_API_KEY environment variable. Base URL: https://api.cetaresearch.com/api/v1
Query flow (4 steps):
1. Submit: POST /data-explorer/execute
Headers: X-API-Key, Content-Type: application/json
Body: {"query": "SQL", "options": {"format": "json", "timeout": 600, "limit": 10000}, "resources": {"memoryMb": 16384, "threads": 6}}
Response: {"taskId": "uuid"}
2. Poll: GET /data-explorer/tasks/{taskId}
Headers: X-API-Key
Response: {"status": "completed", "artifactId": "uuid", "rowCount": N}
Poll every 2s. Statuses: queued -> running -> completed | failed
3. Get download URL: GET /data-explorer/artifacts/{artifactId}/download/result.json?response_type=url
Headers: X-API-Key
Response: {"available": true, "url": "https://presigned-url"} or {"available": false, "retryAfter": 3}
4. Download: GET {presigned url from step 3}. No auth headers needed.
Response: JSON array of result rows.
Schema (public, no auth): GET /data-explorer/schema
SQL rules: DuckDB syntax. Tables: fmp.table_name. Use aliases. date_epoch is UINT32, cast to BIGINT for arithmetic. LIMIT 100 unless asked otherwise. Use max resources always.
Step 3: Ask questions
"What are the top 10 technology stocks by market cap?"
The AI will write and execute the Python code, poll for results, and display them. If a query fails, it can read the error message and fix the SQL automatically.
"Show me insider purchases over $1M in the last 30 days with their forward returns"
"Compare average P/E ratios across sectors for the last 5 years"
The AI handles the full submit-poll-download cycle on each query.
How the API works
The query API is asynchronous. You submit a query, poll for completion, then download results from a presigned storage URL.
Submit
POST https://api.cetaresearch.com/api/v1/data-explorer/execute
Headers: X-API-Key: cr_xxxxxxxxxxxx
Body: {
"query": "SELECT symbol, companyName, marketCap FROM fmp.company_screener WHERE sector = 'Technology' ORDER BY marketCap DESC LIMIT 10",
"options": {"format": "json", "timeout": 600, "limit": 10000},
"resources": {"memoryMb": 16384, "threads": 6}
}
Response: {"taskId": "a1b2c3d4-..."}
Poll
GET https://api.cetaresearch.com/api/v1/data-explorer/tasks/{taskId}
Headers: X-API-Key: cr_xxxxxxxxxxxx
When running: {"status": "running"}
When done: {"status": "completed", "artifactId": "uuid", "rowCount": 10, "executionTime": 0.342}
When failed: {"status": "failed", "error": "Column 'badColumn' not found"}
Poll every 2 seconds. Most queries complete in under 5 seconds.
Get download URL
GET https://api.cetaresearch.com/api/v1/data-explorer/artifacts/{artifactId}/download/result.json?response_type=url
Headers: X-API-Key: cr_xxxxxxxxxxxx
When ready: {"available": true, "url": "https://presigned-storage-url"}
When preparing: {"available": false, "retryAfter": 3}
If available is false, the server is converting results from parquet to JSON. Wait and retry.
Download results
GET {presigned URL from above}
No auth headers needed.
Response: [{"symbol": "AAPL", "companyName": "Apple Inc.", "marketCap": 3200000000000}, ...]
Get schema (public)
GET https://api.cetaresearch.com/api/v1/data-explorer/schema
No auth required.
Response: {"tables": [{"schemaName": "fmp", "tableName": "company_screener", "columns": [...]}, ...]}
Example: complete Python code
This is what the AI typically generates and runs:
import os
import requests
import time
API_KEY = os.environ["CR_API_KEY"]
BASE = "https://api.cetaresearch.com/api/v1"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
def query(sql):
# Submit
resp = requests.post(f"{BASE}/data-explorer/execute",
headers=HEADERS,
json={
"query": sql,
"options": {"format": "json", "timeout": 600, "limit": 10000},
"resources": {"memoryMb": 16384, "threads": 6}
})
task_id = resp.json()["taskId"]
# Poll
while True:
task = requests.get(f"{BASE}/data-explorer/tasks/{task_id}",
headers=HEADERS).json()
if task["status"] == "completed":
break
elif task["status"] == "failed":
raise Exception(f"Query failed: {task.get('error')}")
time.sleep(2)
# Get presigned download URL
artifact_id = task["artifactId"]
while True:
dl = requests.get(
f"{BASE}/data-explorer/artifacts/{artifact_id}/download/result.json?response_type=url",
headers=HEADERS).json()
if dl.get("available"):
break
time.sleep(dl.get("retryAfter", 3))
# Download
return requests.get(dl["url"]).json()
results = query("""
SELECT symbol, companyName, marketCap, sector
FROM fmp.company_screener
WHERE sector = 'Technology'
ORDER BY marketCap DESC
LIMIT 10
""")
for row in results:
print(f"{row['symbol']:>6} {row['companyName']:<35} ${row['marketCap']:>15,.0f}")
Tips
Always use maximum resources. Set memoryMb: 16384, threads: 6, timeout: 600 for best performance.
Poll every 2 seconds. Simple lookups complete in under a second. Complex joins with millions of rows can take up to 60 seconds.
Handle the download retry. The first download request may return {"available": false} while the server converts from parquet to JSON. Retry after the suggested delay.
Which guide should I use?
| Guide 1 (Copy-paste) | Guide 2 (API) | |
|---|---|---|
| Tools | Any AI chatbot | CLI-based AI tools only |
| Setup | None | API key + Python |
| How it works | Copy schema, AI generates SQL, you paste into platform | AI writes and runs Python code directly |
| Best for | One-off queries, quick lookups | Iterative analysis, scripting, pipelines |
Next steps
- Guide 3: Backtest Trading Strategies with AI - Run and customize 85+ strategies locally or on cloud compute