Updated October 6, 2026

Quickstart

A plan and a key, one call, then the same call from Python and TypeScript.

1. Get a key

Keys come with a plan: create an account in the console, choose a plan under Billing, then create a key under Keys. See Authentication and keys.

Keys start with gds_. Keep the key in an environment variable:

bash
export GLOOM_DATASETS_KEY=gds_...

2. Call a dataset

bash
curl https://api.gloom.sh/v1/kpis/AAPL \
  -H "Authorization: Bearer $GLOOM_DATASETS_KEY"

The answer is data plus meta. Two headers say what it cost: X-Credits-Cost and X-Credits-Remaining. Price a call first, with no key and no account:

bash
curl "https://api.gloom.sh/v1/datasets/cost?endpoint=kpis.company&symbol=AAPL&from=2024-01-01"

A date range reads history, so it costs the history price. See Credits and limits.

3. Use it from code

Python

python
import os
import requests

response = requests.get(
    "https://api.gloom.sh/v1/kpis/AAPL",
    params={"from": "2024-01-01", "to": "2026-09-30"},
    headers={"Authorization": f"Bearer {os.environ['GLOOM_DATASETS_KEY']}"},
)
response.raise_for_status()
body = response.json()

print(body["meta"]["source"])
for series in body["data"]["series"]:
    print(series["key"], series["latest"]["value"])

TypeScript

ts
const response = await fetch(
  "https://api.gloom.sh/v1/cftc/cot?report=legacy&traderClass=noncommercial",
  { headers: { Authorization: `Bearer ${process.env.GLOOM_DATASETS_KEY}` } },
)
if (!response.ok) {
  const { error, message } = await response.json()
  throw new Error(`${error}: ${message}`)
}

const { data, meta } = await response.json()
for (const row of data.rows) {
  console.log(row.contractCode, row.reportDate, row.position.net)
}
console.log(meta.asOf, response.headers.get("X-Credits-Remaining"))

Errors share one body, { "error": code, "message": text }. Branch on the code, see Errors.