Kalkas

API reference

Kalkas API

Every endpoint, parameter and object of the REST API, rendered from its OpenAPI document. The API is read-only: it serves information and never acts in anyone’s account.

Version
2026-10-03
Base URL
https://api.kalkas.ai

Kalkas sells information: calibrated probabilities, fair odds, the de-vigged market probability, edges and the scored record. It never places a bet or an order, and no object here carries a stake, a price, a venue or a link. Every read goes through one projection that applies the caller's grants, the data licences and the time the caller first sees a call; a free caller sees a call after its question has closed.

Pick the API version with the Kalkas-Version header (a date); without it the latest answers. Every response carries Request-Id. Errors are one shape with a type and a code. Lists take limit and an opaque cursor. A request that changes something takes an Idempotency-Key; reads ignore it.

Endpoints

GET /v1/topics

List topics

Every topic Kalkas offers, with whether the caller holds it.

ParameterInTypeRequiredDescription
Kalkas-Versionheader2026-10-03noThe API version as a date. Absent: the latest. Unknown: 400 unsupported_version.
Idempotency-Keyheaderstringno1 to 255 visible ASCII characters. A request that changes something with the same key and request returns the first response for 24 hours; the same key with another request is 409 idempotency_key_reused. Reads ignore it.
limitqueryintegernoPage size, 1 to 100.
starting_afterquerystringnoThe next_cursor of the previous page.

Responses

  • 200 OK (TopicList)
  • 400 A malformed request: see error.code and error.param. (Error)
  • 403 The caller holds no grant for the topic (permission_error). (Error)
  • 404 Nothing at this id or path. (Error)
  • 405 The route does not take this method; Allow names the one it does. (Error)
  • 409 The request conflicts with an earlier one. (Error)
  • 503 The ledger could not be read; retry after the Retry-After seconds. (Error)

GET /v1/decisions

List decisions

The decisions Kalkas has committed, newest question first. A caller sees a decision once its tier first sees it: in a market with first sight on, a free caller after the question closes; in a market with it off, everyone once it is committed.

ParameterInTypeRequiredDescription
Kalkas-Versionheader2026-10-03noThe API version as a date. Absent: the latest. Unknown: 400 unsupported_version.
Idempotency-Keyheaderstringno1 to 255 visible ASCII characters. A request that changes something with the same key and request returns the first response for 24 hours; the same key with another request is 409 idempotency_key_reused. Reads ignore it.
limitqueryintegernoPage size, 1 to 100.
starting_afterquerystringnoThe next_cursor of the previous page.
topicquerystringnoOnly this decisions topic.
statusqueryopen | resolvednoopen: not yet resolved. resolved: settled, void or ambiguous.
subjectquerystringnoOnly questions about this entity key.

Responses

  • 200 OK (DecisionList)
  • 400 A malformed request: see error.code and error.param. (Error)
  • 403 The caller holds no grant for the topic (permission_error). (Error)
  • 404 Nothing at this id or path. (Error)
  • 405 The route does not take this method; Allow names the one it does. (Error)
  • 409 The request conflicts with an earlier one. (Error)
  • 503 The ledger could not be read; retry after the Retry-After seconds. (Error)

GET /v1/decisions/{id}

Get one decision

One decision by its question key (URL-encode it). 404 when the question has no decision this caller sees.

ParameterInTypeRequiredDescription
Kalkas-Versionheader2026-10-03noThe API version as a date. Absent: the latest. Unknown: 400 unsupported_version.
Idempotency-Keyheaderstringno1 to 255 visible ASCII characters. A request that changes something with the same key and request returns the first response for 24 hours; the same key with another request is 409 idempotency_key_reused. Reads ignore it.
idpathstringyes
expand[]queryanalysisnoanalysis adds every forecaster's latest forecast.

Responses

  • 200 OK (Decision)
  • 400 A malformed request: see error.code and error.param. (Error)
  • 403 The caller holds no grant for the topic (permission_error). (Error)
  • 404 Nothing at this id or path. (Error)
  • 405 The route does not take this method; Allow names the one it does. (Error)
  • 409 The request conflicts with an earlier one. (Error)
  • 503 The ledger could not be read; retry after the Retry-After seconds. (Error)

GET /v1/record

Get the record

The evaluator's aggregates for one decisions topic, or for every held topic.

ParameterInTypeRequiredDescription
Kalkas-Versionheader2026-10-03noThe API version as a date. Absent: the latest. Unknown: 400 unsupported_version.
Idempotency-Keyheaderstringno1 to 255 visible ASCII characters. A request that changes something with the same key and request returns the first response for 24 hours; the same key with another request is 409 idempotency_key_reused. Reads ignore it.
topicquerystringnoOnly this decisions topic.

Responses

  • 200 OK (Record | RecordList)
  • 400 A malformed request: see error.code and error.param. (Error)
  • 403 The caller holds no grant for the topic (permission_error). (Error)
  • 404 Nothing at this id or path. (Error)
  • 405 The route does not take this method; Allow names the one it does. (Error)
  • 409 The request conflicts with an earlier one. (Error)
  • 503 The ledger could not be read; retry after the Retry-After seconds. (Error)

GET /v1/events

List events

The decision event log, oldest first, for replay: decision.created, decision.updated and decision.resolved. Resume with after.

ParameterInTypeRequiredDescription
Kalkas-Versionheader2026-10-03noThe API version as a date. Absent: the latest. Unknown: 400 unsupported_version.
Idempotency-Keyheaderstringno1 to 255 visible ASCII characters. A request that changes something with the same key and request returns the first response for 24 hours; the same key with another request is 409 idempotency_key_reused. Reads ignore it.
limitqueryintegernoPage size, 1 to 100.
afterquerystringnoThe cursor of the last event read (or next_cursor of the previous page). Absent: from the start.
typesquerystringnoComma-separated event types.
topicsquerystringnoComma-separated decisions topics.

Responses

  • 200 OK (EventList)
  • 400 A malformed request: see error.code and error.param. (Error)
  • 403 The caller holds no grant for the topic (permission_error). (Error)
  • 404 Nothing at this id or path. (Error)
  • 405 The route does not take this method; Allow names the one it does. (Error)
  • 409 The request conflicts with an earlier one. (Error)
  • 503 The ledger could not be read; retry after the Retry-After seconds. (Error)

GET /v1/openapi.json

This document

ParameterInTypeRequiredDescription
Kalkas-Versionheader2026-10-03noThe API version as a date. Absent: the latest. Unknown: 400 unsupported_version.
Idempotency-Keyheaderstringno1 to 255 visible ASCII characters. A request that changes something with the same key and request returns the first response for 24 hours; the same key with another request is 409 idempotency_key_reused. Reads ignore it.

Responses

  • 200 OpenAPI 3.1 (object)
  • 400 A malformed request: see error.code and error.param. (Error)
  • 403 The caller holds no grant for the topic (permission_error). (Error)
  • 404 Nothing at this id or path. (Error)
  • 405 The route does not take this method; Allow names the one it does. (Error)
  • 409 The request conflicts with an earlier one. (Error)
  • 503 The ledger could not be read; retry after the Retry-After seconds. (Error)

Objects

Error

FieldTypeRequiredDescription
errorobjectyes

Topic

FieldTypeRequiredDescription
objectobjectyes
idstringyes
domainstringyes
kinddecisions | analysisyes
titlestringyes
heldbooleanyesWhether the caller holds a grant for the topic.

TopicList

Every topic Kalkas offers, by id.

FieldTypeRequiredDescription
objectobjectyes
dataarray of Topicyes
has_morebooleanyes
next_cursorstring | nullyesPass as the cursor parameter to continue. Opaque.

Forecast

One forecaster's latest forecast on a question.

FieldTypeRequiredDescription
forecaster_kindstringyes
forecaster_versionstringyes
probabilitynumberyes
market_probabilitynumber | nullyes
known_atstring (date-time)yes

Decision

FieldTypeRequiredDescription
objectobjectyes
idstringyesThe question's ledger key. URL-encode it in a path.
topicstringyes
domainstringyes
questionobjectyes
probabilitynumber | nullyesKalkas's committed probability that the question resolves yes.
fair_oddsnumber | nullyes1 / probability.
marketobjectyes
edgenumber | nullyes
headlineobject | nullyes
kalkas_paper_actionobjectyes
committed_atstring (date-time)yes
digeststringyesContent digest of the decision fact.
standingunresolved | resolved | void | ambiguousyes
resolutionobject | nullyes
scoreobject | nullyes
attributionarray of stringyesText to show with the decision, from the data licences behind it.
versionintegeryesHow many decisions Kalkas has committed on the question that this caller sees.
seqstringyesThe decision's position in decision lists.
analysisarray of ForecastnoPresent only with expand[]=analysis.

DecisionList

The decisions, newest first.

FieldTypeRequiredDescription
objectobjectyes
dataarray of Decisionyes
has_morebooleanyes
next_cursorstring | nullyesPass as the cursor parameter to continue. Opaque.

ScoreRow

FieldTypeRequiredDescription
classstringyes
forecasterstringyes
forecaster_kindstringyes
nintegeryes
edge_vs_marketnumber | nullyes
log_lossnumberyes
briernumberyes
mean_pnumberyes
hit_ratenumberyes
calibration_slopenumber | nullyes
ecenumberyes
calibration_flagstring | nullyes

Reliability

FieldTypeRequiredDescription
classstringyes
forecasterstringyes
forecaster_kindstringyes
nintegeryes
binsarray of objectyes

Record

Aggregates of the evaluator over resolved questions: no per-call rows, no stake or profit.

FieldTypeRequiredDescription
objectobjectyes
topicstringyes
domainstringyes
as_ofstring (date-time)yes
resolved_questionsintegeryes
void_questionsintegeryes
trialsintegeryes
scoresarray of ScoreRowyes
calibrationarray of Reliabilityyes
closing_line_valueobjectyes
attributionarray of stringyes

RecordList

One record per held decisions topic.

FieldTypeRequiredDescription
objectobjectyes
dataarray of Recordyes
has_morebooleanyes
next_cursorstring | nullyesPass as the cursor parameter to continue. Opaque.

Event

FieldTypeRequiredDescription
objectobjectyes
idstringyesStable: the same event has the same id however often it is read.
typedecision.created | decision.updated | decision.resolvedyes
topicstringyes
createdstring (date-time)yes
cursorstringyesPass as after to resume after this event.
dataobjectyes

EventList

Events in ledger order. A page ends at an event not yet due for the caller; the same cursor returns it once it is.

FieldTypeRequiredDescription
objectobjectyes
dataarray of Eventyes
has_morebooleanyes
next_cursorstring | nullyesPass as the cursor parameter to continue. Opaque.