API reference · Research
Get calibration
GET/v1/research/calibration
How the venue's opening prices compared with settlement over every settled market the filters keep, by price bucket, with intervals.
On this page
Auth. An API token: Authorization: Bearer lb_… (create one). Signed-in web sessions work too.
Limits. One history query per call (500 a day on Free; unlimited on Builder and Standard).
Parameters
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
speaker | string | no | A canonical speaker key. |
series | string | no | A venue series ticker. |
category | string | no | A category. |
phrase | string | no | A normalized phrase key. |
venue | string | no | kalshi or polymarket. |
since | integer | no | ms epoch, by settlement time. |
until | integer | no | ms epoch, by settlement time. |
min_volume | integer | no | Leave out markets with less volume. |
basis | string | no | mid (the first two-sided mid, default) or trade (the first trade, which the caveats explain). |
buckets | integer | no | Number of equal-width price buckets. 2 to 20. Default 10. |
test_fraction | number | no | Share of markets, by settlement time, held out as the later split. Default 0.3. |
Request
curl "https://api.langbot.ai/v1/research/calibration?speaker=powell&basis=mid" \
-H "Authorization: Bearer $LANGBOT_API_TOKEN"from langbot import LangbotClient
async with LangbotClient() as lb: # reads LANGBOT_API_TOKEN
cal = await lb.calibration(speaker="powell", basis="mid")
print(cal["n"], cal["overall"])const res = await fetch("https://api.langbot.ai/v1/research/calibration?speaker=powell&basis=mid", {
headers: { Authorization: `Bearer ${process.env.LANGBOT_API_TOKEN}` },
});
console.log(await res.json());Response
200 OK
{
"v": 1,
"basis": "mid",
"buckets": 10,
"n": 214,
"by_bucket": [ { "bucket": 1, "lo_c": 10, "hi_c": 20, "n": 31, "avg_price_c": 14.6, "yes_rate": 0.161, "yes_rate_ci90": [0.08, 0.29], "gap_c": 1.5, "brier": 0.134, "p_value": 0.71 } ],
"overall": { "n": 214, "gap_c": -0.8, "gap_ci90_clustered": [-4.1, 2.6], "brier": 0.151 },
"split": { "test_fraction": 0.3, "train": { "n": 150 }, "test": { "n": 64 } },
"trials": { "count_30d": 4 },
"caveats": ["mid basis: the first two-sided mid"]
}Every figure has its sample size and a 90% interval, with Benjamini-Hochberg control across buckets. Each query is written to your trials ledger. Measurements, never signals.
Errors
| Status | code | When |
|---|---|---|
| 401 | auth_required | No token was sent. |
| 401 | token_invalid | The token was not recognised (mistyped, revoked or expired). |
| 422 | validation_error | A parameter failed validation; detail[].loc names it. |
| 429 | quota_exceeded | Today's history queries are spent; quota.resets_at says when they reset. |
| 429 | rate_limited | Over your request budget; wait Retry-After seconds. |
Every error body is {"detail": …, "code": "…"}; branch on code. All codes: Errors.