openapi: 3.0.0
info:
version: 2.0.0
title: Metaculus API
description: |
Welcome to the official Metaculus API!
API Data Access
⚠️ All use of the API and any data retrieved via the API is governed by the Metaculus Terms of Use.
In particular: data may not be used to train, evaluate, or otherwise create or develop AI/ML models or algorithms without Metaculus's prior written permission; and any commercial use whatsoever requires a separate written agreement. The endpoints below describe what is technically retrievable — the Terms of Use govern what you may do with what you retrieve.
The following data access restrictions and request throttling apply to the main Metaculus instance at metaculus.com. If you are running a custom instance, these restrictions do not apply.
⚠️ All API requests require valid authentication credentials. Unauthenticated requests will be rejected with an authentication error. Ensure you include your API token in the Authorization header for all requests.
See the "How to Authenticate" section below for setup instructions.
All Authenticated Accounts
All users, given authentication, have access to the following data via the API:
Your own data: Your predictions, scores, comments, and other personal data are always available.
Question text & resolution values: Open question text is always available. For closed questions, you can access the text and resolution value of any question you have predicted on.
Staff comments: Comments authored by Metaculus staff are available. To access comments, you must filter by author (your own user ID) or author_is_staff=true.
Community Prediction (limited): The current value of the Community Prediction is available on a small set of ~50 questions. On all other questions, aggregation data (Community Prediction and other aggregates) is not included in API responses.
Bot Benchmarking Access Tier
An additional access tier is available for AI forecasting bot developers. This tier grants current Community Prediction, question text, and resolution access on a larger set of ~250 open questions and ~250 resolved questions, intended for training and evaluation purposes.
To request access, please fill out this form: Metaculus Data Needs Form.
Commercial API or Data Access
For commercial use inquiries, please submit our data request form with details about your data needs and intended use case. A member of our team will follow up soon.
Metaculus Data Needs Form
Non-commercial API or Data Access
If you want to make non-commercial use of Metaculus data (for academic or private research, hobbyist, etc.), please fill out our form — we generally support research efforts, and sometimes support exciting hobbyist projects.
Metaculus Data Needs Form
Questions or Feedback
If you have questions, ideas, or feedback, please contact our team at
api-requests@metaculus.com. We are excited to keep building upon the API, and we’d like to keep making it more useful to you.
Get Started in 15 Seconds
Most of the API is (hopefully) self-explanatory. You’ll find all the documentation below.
If you’re testing the waters or doing a one-off analysis, you can dive right in!
If you’re building an application that connects to the Metaculus API, you’ll need to authenticate.
How to Authenticate
You can see your current API token (or generate one) at your settings page, under the header "API Access".
You can then add the token to your requests using the Authorization HTTP header. The token should be prefixed by the string literal "Token", with whitespace separating the two strings.
Example:
Generating a CDF to predict on a continuous question can be a bit tricky. We only accept predictions in the form of a 201 point
CDF, represented as a list of floats, so getting scaling right is very important.
Expand for CDF generation details and examples
To start off, let's take an example question: "What will be the temperature (in Celsius) in New York City on January 1st, 3000?"
If you were to open the question on the website, you would see that the prediction input will have an x-axis that goes from `-40` to `110`.
You could also find those values in the api by looking at the `"range_min"` and `"range_max"` properties inside `question["scaling"]`.
If you want to build a cdf, what does that mean to you? It means that you'll need to generate the heights of the cdf at 201 points
representing locations between -40 and 110. In this case, the first value of the CDF array we are going to build will be the probability
that the temperature is less than (not equal to) -40. The last value will represent the probability that the temperature is less
than or equal to 110. We then see that the `"zero_point"` in `question["scaling"]` is None, so we can conclude that the remaining
values in the CDF array represent the height of the cdf at equally spaced locations between -40 and 110. This is because the `"zero_point"`
being empty means that the question scaling is linear.
**Important note on closed bounds:** The asymmetry above — `cdf[0]` is strictly less-than while `cdf[-1]` is less-than-or-equal — has
a practical consequence for questions with a closed lower bound. Because outcomes strictly below a closed lower bound are impossible,
`cdf[0]` must be exactly `0.0`. This does *not* mean you must assign zero probability to the outcome equalling the lower bound exactly.
Instead, the probability of landing on the lower bound belongs in the first inbound bucket, which is `cdf[1] - cdf[0]` = `cdf[1]`.
For example, if you believe there is a 70% chance the outcome is exactly the lower bound, set `cdf[1] = 0.7` (and `cdf[0] = 0.0`).
Here's a function that can take in a nominal location and return the corresponding "internal location" x-value. Note that it
does account for logarithmic scaling.
```python
import datetime
import numpy as np
def nominal_location_to_cdf_location(
nominal_location: str | float,
question_data: dict,
) -> float:
"""Takes a location in nominal format (e.g. 123, "123",
or datetime in iso format) and scales it to metaculus's
"internal representation" range [0,1] incorporating question scaling"""
if question_data["type"] == "date":
scaled_location = datetime.fromisoformat(nominal_location).timestamp()
else:
scaled_location = float(nominal_location)
# Unscale the value to put it into the range [0,1]
scaling = question_data["scaling"]
range_min = scaling.get("range_min")
range_max = scaling.get("range_max")
zero_point = scaling.get("zero_point")
if zero_point is not None:
# logarithmically scaled question
deriv_ratio = (range_max - zero_point) / (range_min - zero_point)
unscaled_location = (
np.log(
(scaled_location - range_min) * (deriv_ratio - 1)
+ (range_max - range_min)
)
- np.log(range_max - range_min)
) / np.log(deriv_ratio)
else:
# linearly scaled question
unscaled_location = (scaled_location - range_min) / (range_max - range_min)
return unscaled_location
```
But you don't want to have to do this manually for every point in a 201 point CDF, so instead let's do it with percentiles.
Let's say that we have a solid idea about what our 5th, 25th, 50th, 75th, and 95th percentiles are in real units. We can use those to
generate a CDF. But, note that if our 5th and 95th percentiles don't overlap the range of the question, we'll have to add a few
more bits of information to complete our CDF.
Here's a function that can take in some percentiles and return an inferred linearly interpolated CDF.
```python
def generate_continuous_cdf(
percentiles: dict,
question_data: dict,
below_lower_bound: float = None,
above_upper_bound: float = None,
) -> list[float]:
"""
Takes a set of percentiles and returns a corresponding cdf with 201 values
Param: percentiles
dict[str, float | str]
keys must terminate in a number interpretable as a float in range (0, 100)
optionally preceded by an underscore "_"
values must be a nominal value in the scale of the question, either
interpretable as a float (for "numeric" type questions) or a datetime in
ISO format (for "date" type questions)
example percentiles:
percentiles = {
"percentile_01": 25,
"percentile_25.123": 500,
"50": 650,
"percentile_75": "700",
"percentile_99": 990,
}
optionally, include `below_lower_bound` and `above_upper_bound`
to indicate the amount of probability mass assigned strictly outside those bounds.
Note: `below_lower_bound` is P(outcome < lower_bound), i.e. strictly less than.
For questions with a closed lower bound this must be 0.0 (or omitted); any
probability you intend for the outcome equalling the lower bound exactly should
instead be expressed via a percentile at or just above the lower bound value.
percentiles = {
"percentile_25": 500,
"percentile_50": 650,
"percentile_75": 700,
}
below_lower_bound = 0.0025,
above_upper_bound = 0.009,
If the percentile locations don't encompass
[scaling["range_min"], scaling["range_max"]]
and "below_lower_bound"/"above_upper_bound" aren't provided,
then the prediction can't be interpreted as a cdf properly.
Note that range_min/range_max for date questions are unix timestamps.
"""
# This will be the set of (x, y) points that are the set points
# of the cdf
percentile_locations = []
# take the given boundary values
if below_lower_bound is not None:
percentile_locations.append((0.0, below_lower_bound))
if above_upper_bound is not None:
percentile_locations.append((1.0, 1 - above_upper_bound))
# generate the remaining set of points
for percentile, nominal_location in percentiles.items():
height = float(str(percentile).split("_")[-1]) / 100
location = nominal_location_to_cdf_location(nominal_location, question_data)
percentile_locations.append((location, height))
# sort to ensure lookup works
percentile_locations.sort()
# check validity
first_point, last_point = percentile_locations[0], percentile_locations[-1]
if (first_point[0] > 0.0) or (last_point[0] < 1.0):
raise ValueError("Percentiles must encompass bounds of the question")
def get_cdf_at(location):
# helper function that takes a location and returns
# the height of the cdf at that location, linearly
# interpolating between values
previous = percentile_locations[0]
for i in range(1, len(percentile_locations)):
current = percentile_locations[i]
if previous[0] <= location <= current[0]:
return previous[1] + (current[1] - previous[1]) * (
location - previous[0]
) / (current[0] - previous[0])
previous = current
# generate that cdf
continuous_cdf = [get_cdf_at(i / 200) for i in range(201)]
return continuous_cdf
```
Phew, that was pretty long, but now we can take a set of nominal percentiles and generate a CDF that is in the format
that the Metaculus api will accept. But wait! Just because we have a cdf that represents our beliefs, it doesn't
mean Metaculus will accept it. We'll have to make sure it obeys a few rules, lest it be rejected as invalid.
1. The cdf must be strictly increasing by at least 0.00005 per step (1% / inbound_outcome_count). This is because Metaculus
evaluates continuous forecasts by their PDF (technically a PMF) derived as the set of differences between consecutive
CDF points, and 0.00005 is the minimum value allowed to avoid scores getting too arbitrarily negative. Note that if the
inbound_outcome_count is less than the normal 200, this threshold will be larger.
2. The cdf must not increase by more than 0.2 at any step if the question has the normal inbound_outcome_count of 200. Otherwise,
that threshold is scaled as such: 0.2 * (200 / inbound_outcome_count). This prevents too extreme spikes in the distribution.
3. The cdf must obey bounds. If a boundary is open, at least 0.1% of probability mass must be assigned outside of it; if it
is closed, no probability mass may be outside of it. Concretely: for a closed lower bound `cdf[0]` must be exactly `0.0`,
and for a closed upper bound `cdf[-1]` must be exactly `1.0`. Note that a closed lower bound does not prevent you from
assigning probability to the outcome equalling the lower bound — that mass goes in the first inbound bucket (`cdf[1]`),
not in `cdf[0]`.
Here's a standardization function that ensures your CDF will be accepted. It does add a linear component to the cdf,
so those with an abundance of precision in their forecasts may want to skip it. The cdfs (and thus their derived pdfs)
you see on the website have been standardized in this way.
```python
def standardize_cdf(cdf, question_data: dict):
"""
Takes a cdf and returns a standardized version of it
- assigns no mass outside of closed bounds (scales accordingly)
- assigns at least a minimum amount of mass outside of open bounds
- increasing by at least the minimum amount (0.01 / 200 = 0.00005)
- caps the maximum growth to 0.2
Note, thresholds change with different `inbound_outcome_count`s
"""
lower_open = question_data["open_lower_bound"]
upper_open = question_data["open_upper_bound"]
inbound_outcome_count = question_data["inbound_outcome_count"]
default_inbound_outcome_count = 200
cdf = np.asarray(cdf, dtype=float)
if not cdf.size:
return []
# apply lower bound & enforce boundary values
scale_lower_to = 0 if lower_open else cdf[0]
scale_upper_to = 1.0 if upper_open else cdf[-1]
rescaled_inbound_mass = scale_upper_to - scale_lower_to
def standardize(F: float, location: float) -> float:
# `F` is the height of the cdf at `location` (in range [0, 1])
# rescale
rescaled_F = (F - scale_lower_to) / rescaled_inbound_mass
# offset
if lower_open and upper_open:
return 0.988 * rescaled_F + 0.01 * location + 0.001
elif lower_open:
return 0.989 * rescaled_F + 0.01 * location + 0.001
elif upper_open:
return 0.989 * rescaled_F + 0.01 * location
return 0.99 * rescaled_F + 0.01 * location
for i, value in enumerate(cdf):
cdf[i] = standardize(value, i / (len(cdf) - 1))
# apply upper bound
# operate in PMF space
pmf = np.diff(cdf, prepend=0, append=1)
# cap depends on inboundOutcomeCount (0.2 if it is the default 200)
cap = 0.2 * (default_inbound_outcome_count / inbound_outcome_count)
def cap_pmf(scale: float) -> np.ndarray:
return np.concatenate([pmf[:1], np.minimum(cap, scale * pmf[1:-1]), pmf[-1:]])
def capped_sum(scale: float) -> float:
return float(cap_pmf(scale).sum())
# find the appropriate scale search space
lo = hi = scale = 1.0
while capped_sum(hi) < 1.0:
hi *= 1.2
# hone in on scale value that makes capped sum 1
for _ in range(100):
scale = 0.5 * (lo + hi)
s = capped_sum(scale)
if s < 1.0:
lo = scale
else:
hi = scale
if s == 1.0 or (hi - lo) < 2e-5:
break
# apply scale and renormalize
pmf = cap_pmf(scale)
pmf[1:-1] *= (cdf[-1] - cdf[0]) / pmf[1:-1].sum()
# back to CDF space
cdf = np.cumsum(pmf)[:-1]
# round to minimize floating point errors
cdf = np.round(cdf, 10)
return cdf.tolist()
```
With this tiny guide, you can be well along your way to submitting continuous forecasts to Metaculus.
If you have any questions or suggestions, feel free to create tickets on the github: https://github.com/Metaculus/metaculus/issues
security:
- TokenAuth: [ ]
components:
securitySchemes:
TokenAuth:
type: apiKey
in: header
name: Authorization
description: "Token-based authentication. Use format: `Token `"
schemas:
Post:
type: object
properties:
id:
type: integer
example: 1
title:
type: string
example: "Binary Post title"
short_title:
type: string
example: "Binary Post url title"
slug:
type: string
example: "numeric-post"
author_id:
type: integer
example: 1000
author_username:
type: string
example: "metaculus"
projects:
type: object
properties:
site_main:
type: array
items:
$ref: '#/components/schemas/Project'
tournament:
type: array
items:
$ref: '#/components/schemas/Project'
category:
type: array
items:
$ref: '#/components/schemas/Category'
tag:
type: array
items:
$ref: "#/components/schemas/Tag"
question_series:
type: array
items:
$ref: '#/components/schemas/Project'
default_project:
$ref: '#/components/schemas/Project'
created_at:
type: string
format: date-time
example: "2024-10-16T12:56:51.751385Z"
published_at:
type: string
format: date-time
nullable: true
open_time:
type: string
format: date-time
nullable: true
edited_at:
type: string
format: date-time
curation_status:
type: string
enum: [ draft, pending, rejected, approved ]
example: "pending"
comment_count:
type: integer
example: 10
status:
type: string
example: "pending"
description: "Combination of curation status and post lifecycle statuses"
enum: [ open, upcoming, closed, resolved, draft, pending, rejected ]
nr_forecasters:
type: integer
example: 5
question:
$ref: '#/components/schemas/Question'
conditional:
$ref: '#/components/schemas/Conditional'
group_of_questions:
$ref: '#/components/schemas/GroupOfQuestions'
user_permission:
type: string
enum: [ forecaster, viewer ]
example: "forecaster"
vote:
$ref: '#/components/schemas/Vote'
forecasts_count:
type: integer
example: 0
Project:
type: object
properties:
id:
type: integer
example: 144
type:
type: string
example: "site_main"
name:
type: string
example: "Metaculus Community"
slug:
type: string
nullable: true
prize_pool:
type: string
example: "0.00"
start_date:
type: string
format: date-time
nullable: true
close_date:
type: string
format: date-time
nullable: true
html_metadata_json:
type: string
example: ""
is_ongoing:
type: boolean
nullable: true
user_permission:
type: string
nullable: true
created_at:
type: string
format: date-time
edited_at:
type: string
format: date-time
default_permission:
type: string
example: "forecaster"
visibility:
type: string
enum: [ normal, not_in_main_feed, unlisted ]
example: normal
Category:
type: object
properties:
id:
type: integer
example: 3690
name:
type: string
example: "Nuclear Technology & Risks"
slug:
type: string
example: "nuclear"
description:
type: string
example: "Nuclear Technology & Risks"
Tag:
type: object
properties:
name:
type: string
example: "Space"
Conditional:
type: object
properties:
id:
type: integer
example: 1
condition:
$ref: '#/components/schemas/Question'
condition_child:
$ref: '#/components/schemas/Question'
question_yes:
$ref: '#/components/schemas/Question'
question_no:
$ref: '#/components/schemas/Question'
GroupOfQuestions:
type: object
properties:
id:
type: integer
example: 1
description:
type: string
resolution_criteria:
type: string
fine_print:
type: string
group_variable:
type: string
graph_type:
type: string
enum: [ multiple_choice_graph, fan_graph ]
questions:
type: array
items:
$ref: '#/components/schemas/Question'
Question:
type: object
properties:
id:
type: integer
example: 2
title:
type: string
example: "Binary Question"
description:
type: string
example: "string"
created_at:
type: string
format: date-time
open_time:
type: string
format: date-time
scheduled_resolve_time:
type: string
format: date-time
actual_resolve_time:
type: string
format: date-time
nullable: true
resolution_set_time:
type: string
format: date-time
nullable: true
scheduled_close_time:
type: string
format: date-time
actual_close_time:
type: string
format: date-time
type:
type: string
enum: [ binary, multiple_choice, numeric, discrete, date ]
example: "binary"
options:
type: array
items:
type: string
description: "List of options for multiple_choice questions"
example:
- "Democratic"
- "Republican"
- "Libertarian"
- "Green"
- "Other"
all_options_ever:
type: array
items:
type: string
description: "List of all options ever for multiple_choice questions"
example:
- "Democratic"
- "Republican"
- "Libertarian"
- "Green"
- "Blue"
- "Other"
options_history:
type: array
description: "List of [iso format time, options] pairs for multiple_choice questions"
items:
type: array
items:
oneOf:
- type: string
description: "ISO 8601 timestamp when the options became active"
- type: array
items:
type: string
description: "Options list active from this timestamp onward"
example:
- ["0001-01-01T00:00:00", ["a", "b", "c", "other"]]
- ["2026-10-22T16:00:00", ["a", "b", "c", "d", "other"]]
status:
type: string
enum: [ upcoming, open, closed, resolved ]
example: "upcoming"
possibilities:
$ref: '#/components/schemas/QuestionPossibilities'
resolution:
type: string
nullable: true
open_upper_bound:
type: boolean
nullable: false
open_lower_bound:
type: boolean
nullable: false
inbound_outcome_count:
type: integer
nullable: true
example: 200
resolution_criteria:
type: string
example: "string"
fine_print:
type: string
example: "string"
label:
type: string
nullable: true
unit:
type: string
nullable: false
required: false
example: "$"
default: ""
scaling:
$ref: '#/components/schemas/QuestionScaling'
Vote:
type: object
properties:
score:
type: integer
example: 0
user_vote:
type: string
nullable: true
QuestionScaling:
type: object
properties:
range_max:
type: number
format: float
nullable: true
description: "The lower boundary of the input range. If the question is Discrete, it will be 1/2 a bucket width below the nominal lowest inbound outcome."
range_min:
type: number
format: float
nullable: true
description: "The upper boundary of the input range. If the question is Discrete, it will be 1/2 a bucket width above the nominal highest inbound outcome."
zero_point:
type: number
format: float
nullable: true
description: "Only populated if the question has logarithmic scaling. See 'continuous_range' for exact locations where the CDF gets evaluated."
open_upper_bound:
type: boolean
nullable: true
description: "Whether the upper bound is open."
open_lower_bound:
type: boolean
nullable: true
description: "Whether the lower bound is open."
inbound_outcome_count:
type: integer
example: 200
nullable: true
description: "Total number of possible outcomes within the question's range (does not include out of bounds)."
continuous_range:
type: array
example: [
"2023-01-01T00:00:00Z",
"2023-01-02T00:00:00Z",
"...",
"2023-01-03T00:00:00Z",
]
nullable: true
description: "List of real-value locations corresponding to where the CDF is evaluated"
items:
type: string
example: "2023-01-01T00:00:00Z"
QuestionPossibilities:
description: "WARNING: this is a deprecated field and may be removed without notice."
oneOf:
- type: object
properties:
type:
type: string
enum: [ "binary" ]
example: "binary"
- type: object
properties:
"type":
type: string
enum: [ "continuous" ]
example: "continuous"
low:
type: string
example: "tail"
high:
type: string
example: "tail"
scale:
type: object
properties:
max:
type: number
format: float
example: 1
min:
type: number
format: float
example: 100
deriv_ratio:
type: number
format: float
example: 1
format:
type: string
example: "num"
Forecast:
type: object
oneOf:
- $ref: '#/components/schemas/BinaryForecast'
- $ref: '#/components/schemas/ContinuousForecast'
- $ref: '#/components/schemas/MultipleChoiceForecast'
- $ref: '#/components/schemas/ConditionalForecast'
- $ref: '#/components/schemas/GroupForecast'
BinaryForecast:
type: object
required:
- question
- probability_yes
properties:
question:
type: integer
probability_yes:
type: number
format: float
description: Probability for a binary outcome
end_time:
type: string
format: date-time
description: The timestamp when the forecast is automatically withdrawn
ContinuousForecast:
type: object
required:
- question
- continuous_cdf
properties:
question:
description: ID of the numeric question (not post)
type: integer
continuous_cdf:
description: |
The CDF is 201 values long, representing the height of the CDF at 201
evenly spaced points across the question's range, taking into account
the question's scaling. See notes in this section for suggestions on
generating a cdf.
If a question has a closed lower bound
(`question["open_lower_bound"] == False`), the first value of the CDF
must be 0.0. Otherwise it must be at least 0.001 - meaning at least
0.1% of the probability mass must be assigned below the lower bound.
If a question has a closed upper bound
(`question["open_upper_bound"] == False`), the last value of the CDF
must be 1.0, otherwise no more than 0.999 - meaning at least
0.1% of the probability mass must be assigned above the upper bound.
At least 1% of the probability mass must be assigned uniformly within
bounds, which means that the CDF must be strictly increasing by at
least 0.01/200 = 0.00005 per step. No two adjacent values of the CDF
can differ by more than 0.59, which is the largest number obtainable
via the sliders.
type: array
items:
type: number
format: float
distribution_input:
description: Optional. Slider values used for populating the sliders on the frontend at page load.
type: object
required:
- type
- components
properties:
type:
type: string
enum: [ slider, quantile ]
example: slider
forecast:
type: array
items:
type: object
properties:
center:
type: number
format: float
left:
type: number
format: float
right:
type: number
format: float
weight:
type: number
format: float
end_time:
type: string
format: date-time
description: The timestamp when the forecast is automatically withdrawn
MultipleChoiceForecast:
type: object
required:
- question
- probability_yes_per_category
properties:
question:
type: integer
probability_yes_per_category:
type: object
additionalProperties:
type: number
format: float
description: Probability distribution for multiple categories. Sum of values must equal 1.0.
end_time:
type: string
format: date-time
description: The timestamp when the forecast is automatically withdrawn
ConditionalForecast:
type: array
description: Forecast for conditional questions (if Yes/No scenarios)
items:
type: object
required:
- question
- probability_yes
properties:
question:
type: integer
probability_yes:
type: number
format: float
end_time:
type: string
format: date-time
description: The timestamp when the forecast is automatically withdrawn
GroupForecast:
type: array
description: Group forecast of Binary, Numeric or Date subquestions
items:
oneOf:
- $ref: '#/components/schemas/BinaryForecast'
- $ref: '#/components/schemas/ContinuousForecast'
Withdrawal:
type: object
required:
- question
properties:
question:
type: integer
Comment:
type: object
properties:
id:
type: integer
description: Unique identifier for the comment.
author:
type: object
properties:
id:
type: integer
description: Author's user ID.
username:
type: string
description: Author's username.
is_bot:
type: boolean
description: If the author is a bot.
is_staff:
type: boolean
description: If the author is a staff member.
parent_id:
type: integer
nullable: true
description: ID of the comment being replied to (if applicable).
root_id:
type: integer
nullable: true
description: ID of the root comment in the thread.
created_at:
type: string
format: date-time
description: Timestamp when the comment was created.
text:
type: string
description: The content of the comment.
on_post:
type: integer
description: ID of the post the comment belongs to.
included_forecast:
type: boolean
description: If the user's last forecast is included.
is_private:
type: boolean
description: If the comment is private.
vote_score:
type: integer
description: Total vote score for the comment.
changed_my_mind:
type: object
properties:
count:
type: integer
description: Number of users who changed their mind based on this comment.
for_this_user:
type: boolean
description: If the current user changed their mind based on this comment.
mentioned_users:
type: array
items:
type: object
properties:
id:
type: integer
description: ID of the mentioned user.
username:
type: string
description: Username of the mentioned user.
user_vote:
type: integer
description: Current user's vote on this comment (-1, 0, 1).
QuestionDataCSV:
description: "Warning: this data may be out of date, please consult the README included in the zip file for the most up to date information."
type: object
properties:
Question ID:
type: integer
description: The ID of the question.
example: 3
Question URL:
type: string
description: The URL of the question page.
Question Title:
type: string
description: The title of the (sub)question.
Post ID:
type: integer
description: The ID of the post containing the question.
Post Curation Status:
type: string
enum: [ draft, pending, rejected, approved ]
example: pending
Post Published Time:
type: string
format: date-time
description: The time the post was published.
Default Project:
type: string
description: The default project for the Post.
Default Project ID:
type: integer
description: The ID of the default project for the Post.
Categories:
type: string
description: Comma-separated list of category slugs for the post.
Leaderboard Tags:
type: string
description: Comma-separated list of leaderboard tags for the post.
Label:
type: string
description: For sub questions only. The label of the question.
Question Type:
type: string
description: The type of the question.
enum: [ binary, multiple_choice, numeric, date ]
example: binary
MC Options (Current):
type: string
description: For multiple choice questions only. The current set of options.
MC Options (All):
type: string
description: For multiple choice questions only. All options including removed ones.
MC Options History:
type: string
description: For multiple choice questions only. History of option changes.
Lower Bound:
type: number
description: For continuous questions only. The minimum value of the input range. For date questions, formatted as a date string.
Open Lower Bound:
type: boolean
description: Whether the lower bound of the range is open.
Upper Bound:
type: number
description: For continuous questions only. The maximum value of the input range. For date questions, formatted as a date string.
Open Upper Bound:
type: boolean
description: Whether the upper bound of the range is open.
Continuous Range:
type: string
description: For continuous questions only. A human-readable representation of the question range.
Open Time:
type: string
format: date-time
description: The time the question was opened.
CP Reveal Time:
type: string
format: date-time
description: The time the CP was revealed. This is also the default setting for when Spot Scores are evaluated.
Scheduled Close Time:
type: string
format: date-time
description: The time the question is scheduled to close.
Actual Close Time:
type: string
format: date-time
description: The time the question actually closed.
Resolution:
type: string
description: The nominal resolution of the question. E.g. 'no', 'yes' for binary, '2022-01-01' for date, etc.
Resolution Known Time:
type: string
format: date-time
description: The time the question resolution was publicly known.
Include Bots in Aggregates:
type: boolean
description: Whether bots are included in the aggregates.
Question Weight:
type: number
description: The weight of the question within its post.
ForecastDataCSV:
type: object
properties:
Question ID:
type: integer
description: The ID of the question this forecast is made on.
example: 3
Forecaster ID:
type: integer
description: The forecaster's ID. None if forecast is an Aggregation.
example: 421323
Forecaster Username:
type: string
description: The forecaster's username or aggregation method.
example: John Doe
Is Bot:
type: boolean
description: Whether the forecaster is a bot account.
Start Time:
type: string
format: date-time
description: The start time of the prediction.
End Time:
type: string
format: date-time
description: The end time of the prediction.
Forecaster Count:
type: integer
description: The number of forecasts that contributed to this Aggregation. null if not an Aggregation.
example: 3
Probability Yes:
type: number
format: float
description: For Binary Questions only. The prediction value in range [0, 1].
example: 0.5
Probability Yes Per Category:
type: string
description: For Multiple Choice Questions only. The predictions for the possible outcomes, all in range [0, 1].
example: "[0.2, 0.5, 0.3]"
Continuous CDF:
type: string
description: For Continuous Questions only. The CDF of the prediction as a list of 201 values.
example: "[0.01, 0.02, 0.03, ..., 0.74, 0.75]"
Probability Below Lower Bound:
type: number
format: float
description: For Continuous Questions only. The probability mass below the lower bound.
Probability Above Upper Bound:
type: number
format: float
description: For Continuous Questions only. The probability mass above the upper bound.
5th Percentile:
type: number
description: For Continuous Questions only. The 5th percentile of the forecast distribution.
25th Percentile:
type: number
description: For Continuous Questions only. The 25th percentile of the forecast distribution.
Median:
type: number
description: For Continuous Questions only. The median (50th percentile) of the forecast distribution.
75th Percentile:
type: number
description: For Continuous Questions only. The 75th percentile of the forecast distribution.
95th Percentile:
type: number
description: For Continuous Questions only. The 95th percentile of the forecast distribution.
Probability of Resolution:
type: number
format: float
description: The probability assigned to the actual resolution value, if resolved.
PDF at Resolution:
type: number
format: float
description: For Continuous Questions only. The PDF value at the resolution point.
ScoreDataCSV:
description: "Warning: this data may be out of date, please consult the README included in the zip file for the most up to date information."
type: object
properties:
Question ID:
type: integer
description: The ID of the question the score is for.
example: 42
User ID:
type: integer
description: The ID of the user who made the score.
example: 12345
User Username:
type: string
description: The username of the user who made the score.
example: "john_doe"
Score Type:
type: string
enum: [ relative_legacy, peer, baseline, spot_peer, spot_baseline, manual ]
description: The type of score.
example: "peer"
Score:
type: number
format: float
description: The score value.
example: 85.5
Coverage:
type: number
format: float
description: The coverage that earned this score.
example: 0.95
CommentDataCSV:
description: "Warning: this data may be out of date, please consult the README included in the zip file for the most up to date information."
type: object
properties:
Post ID:
type: integer
description: The ID of the post the comment is on.
example: 101
Author ID:
type: integer
description: The ID of the author of the comment.
example: 202
Author Username:
type: string
description: The username of the author of the comment.
example: "jane_doe"
Parent Comment ID:
type: integer
description: The ID of the parent comment, if any.
example: 303
Root Comment ID:
type: integer
description: The ID of the root comment, if any.
example: 404
Created At:
type: string
format: date-time
description: The time the comment was created.
example: "2023-10-01T12:34:56Z"
Comment Text:
type: string
description: The text of the comment.
example: "This is a sample comment text."
DataZip:
type: object
description: "Warning: this data may be out of date, please consult the README included in the zip file for the most up to date information. A zip file containing CSVs for Question data, Forecast data, and (optionally) Scoring data, Comment data, and Key Factor data."
properties:
question_data.csv:
$ref: '#/components/schemas/QuestionDataCSV'
forecast_data.csv:
$ref: '#/components/schemas/ForecastDataCSV'
score_data.csv:
$ref: '#/components/schemas/ScoreDataCSV'
comment_data.csv:
$ref: '#/components/schemas/CommentDataCSV'
key_factor_data.csv:
type: object
description: "Optional. Included when include_key_factors is true. Contains key factors (drivers, base rates, news) associated with questions."
tags:
- name: Feed
description: |
In the updated version of Metaculus, standalone questions no longer exist. Instead, the feed is made up of Post entities, where each post can contain various types of content objects. These include:
- Individual questions
- Groups of questions
- Conditional pairs
- Notebooks
The primary entry point for retrieving feed data and interacting with both Posts and Questions is the `/api/posts` endpoint.
- name: Questions & Forecasts
description: |
- name: Comments
- name: Utilities & Data
description: |
**Tip:** You can also access data downloads through the Metaculus website without using the API directly. On any question page, click the ellipsis menu (⋯) in the top-right corner and select "Download data". A modal will appear with the same options available in the endpoints below.
paths:
/api/posts/:
get:
summary: Retrieve posts feed
description: Retrieves a feed of posts with various filters.
tags:
- Feed
parameters:
- in: query
name: tournaments
schema:
type: array
items:
type: string
example: [ 'metaculus-cup', 'aibq3' ]
description: Tournament slug. You can apply multiple filters.
- in: query
name: statuses
schema:
type: array
items:
type: string
enum: [ upcoming, closed, resolved, open ]
example: [ 'closed', 'resolved' ]
description: Post statuses. You can apply multiple filters.
- in: query
name: forecaster_id
schema:
type: integer
example: 123
description: Filters posts where the specified user has submitted a forecast on a question within the post.
- in: query
name: with_cp
schema:
type: boolean
default: false
example: true
description: "Include Community Prediction data in the response. Note: aggregation data is only available for certain questions depending on your API access tier (see above). When enabled on a group post, only the top 3 subquestions include CP; use the post details endpoint for all subquestions."
- in: query
name: include_cp_history
schema:
type: boolean
default: false
example: true
description: "Include full aggregation history in the response."
- in: query
name: include_descriptions
schema:
type: boolean
example: true
description: "With this flag enabled, each post question will include the description, fine_print, and resolution_criteria fields in its response."
- in: query
name: not_forecaster_id
schema:
type: integer
example: 123
description: Filters posts where the specified user has not submitted a forecast on a question within the post.
- in: query
name: open_time__gt
schema:
type: string
format: date-time
example: '2024-01-01'
description: "Post open timestamp filter: `open_time__`. Supported operators: `gt`, `gte`, `lt`, `lte`."
- in: query
name: published_at__gt
schema:
type: string
format: date-time
example: '2024-01-01'
description: "Post publication timestamp filter: `published_at__`. Supported operators: `gt`, `gte`, `lt`, `lte`."
- in: query
name: scheduled_resolve_time__gt
schema:
type: string
format: date-time
example: '2024-01-01'
description: "Scheduled resolution timestamp filter: `scheduled_resolve_time__`. Supported operators: `gt`, `gte`, `lt`, `lte`."
- in: query
name: forecast_type
schema:
type: array
items:
type: string
enum: [ binary, multiple_choice, numeric, discrete, date, conditional, group_of_questions, notebook ]
example: [ 'numeric', 'binary' ]
description: Forecast type. You can apply multiple filters.
- in: query
name: limit
schema:
type: integer
example: 20
description: Number of posts to return per page (pagination limit).
- in: query
name: offset
schema:
type: integer
example: 0
description: Number of posts to skip (pagination offset).
- in: query
name: for_main_feed
schema:
type: boolean
example: true
description: Filter posts suitable for the main feed.
- in: query
name: categories
schema:
type: array
items:
type: string
example: [ 'nuclear', 'health-pandemics' ]
description: Category slugs to filter by. You can apply multiple filters.
- in: query
name: order_by
schema:
type: string
enum:
- published_at
- open_time
- vote_score
- comment_count
- forecasts_count
- scheduled_close_time
- scheduled_resolve_time
- user_last_forecasts_date
- unread_comment_count
- weekly_movement
- divergence
- hotness
- score
example: '-published_at'
description: |
Order by specific fields. For DESC sorting, add `-` prefix, e.g. `-published_at`.
**Sorting option descriptions:**
- `hotness`: Composite score based on post approval time, relevant news, votes, comments, and question metrics (movement, open time, resolution). Uses a decay function where scores decrease over time (posts older than 3.5 days decay with (days/3.5)^-2).
- `score`: User-specific forecasting performance score. **Requires** `forecaster_id` parameter to be provided.
responses:
'200':
description: A paginated list of posts
content:
application/json:
schema:
type: object
properties:
next:
type: string
nullable: true
example: "https://metaculus.com/api/posts/?forecast_type=binary&limit=1&offset=1"
previous:
type: string
nullable: true
example: null
results:
type: array
items:
$ref: '#/components/schemas/Post'
examples:
NumericRequestExample:
summary: Post With Numeric Question
value:
next: "https://metaculus.com/api/posts/"
previous: null
results:
- id: 3530
title: "How many people will die as a result of the 2019 novel coronavirus (COVID-19) before 2021?"
short_title: "COVID-19 Related Deaths before 2021"
slug: "covid-19-related-deaths-before-2021"
author_id: 101465
author_username: "Jgalt"
projects:
category:
- id: 3685
name: "Health & Pandemics"
slug: "health-pandemics"
description: "Health & Pandemics"
tag:
- id: 5262
name: "Public health"
slug: "public-health"
default_project:
id: 144
type: "site_main"
name: "Metaculus Community"
slug: null
prize_pool: "0.00"
start_date: null
close_date: null
html_metadata_json: ""
is_ongoing: null
user_permission: null
created_at: "2023-11-08T16:55:29.484707Z"
edited_at: "2023-11-08T16:55:29.537784Z"
default_permission: "forecaster"
visibility: "normal"
topic:
- id: 15858
name: "Health & Pandemics"
slug: "biosecurity"
emoji: "🧬"
section: "hot_categories"
created_at: "2020-01-25T04:09:23.208127Z"
published_at: "2020-01-27T00:00:00Z"
edited_at: "2024-10-03T08:38:21.381658Z"
curation_status: "approved"
comment_count: 270
status: "resolved"
resolved: true
actual_close_time: "2020-11-01T00:00:00Z"
scheduled_close_time: "2020-11-01T00:00:00Z"
scheduled_resolve_time: "2022-05-06T16:00:00Z"
open_time: "2020-01-27T00:00:00Z"
nr_forecasters: 546
question:
id: 3530
title: "How many people will die as a result of the 2019 novel coronavirus (COVID-19) before 2021?"
description: ""
created_at: "2020-01-25T04:09:23.208127Z"
open_time: "2020-01-27T00:00:00Z"
scheduled_resolve_time: "2022-05-06T16:00:00Z"
actual_resolve_time: "2022-05-06T16:00:00Z"
resolution_set_time: "2022-05-06T16:00:00Z"
scheduled_close_time: "2020-11-01T00:00:00Z"
actual_close_time: "2020-11-01T00:00:00Z"
type: "numeric"
options: null
options_history: null
status: "resolved"
resolution: "77289125.94957079"
resolution_criteria: "Resolution Criteria Copy"
fine_print: ""
label: null
open_upper_bound: true
open_lower_bound: true
inbound_outcome_count: 200
unit: "people"
scaling:
range_max: 100000000.0
range_min: 200.0
zero_point: 0.0
open_upper_bound: true
open_lower_bound: true
inbound_outcome_count: 200
continuous_range: [
200.0,213.6328,228.1949,243.7497,260.3647,278.1123,297.0696,317.3191,
338.9489,362.0531,386.7322,413.0935,441.2517,471.3293,503.4572,
537.7749,574.4320,613.5877,655.4124,700.0882,747.8091,798.7830,853.2315,
911.3913,973.5157,1039.8746,1110.7569,1186.4708,1267.3457,1353.7334,
1446.0096,1544.5758,1649.8607,1762.3222,1882.4496,2010.7653,2147.8277,
2294.2327,2450.6174,2617.6619,2796.0929,2986.6865,3190.2718,3407.7342,
3640.0199,3888.1392,4153.1713,4436.2691,4738.6641,5061.6716,5406.6966,
5775.2401,6168.9050,6589.4038,7038.5656,7518.3442,8030.8265,8578.2418,
9162.9713,9787.5584,10454.7200,11167.3582,11928.5729,12741.6751,13610.2019,
14537.9312,15528.8984,16587.4142,17718.0829,18925.8228,20215.8874,21593.8883,
23065.8196,24638.0840,26317.5206,28111.4347,30027.6297,32074.4407,34260.7710,
36596.1309,39090.6789,41755.2659,44601.4824,47641.7092,50889.1707,54357.9931,
58063.2651,62021.1043,66248.7266,70764.5216,75588.1325,80740.5411,86244.1599,
92122.9287,98402.4194,105109.9469,112274.6880,119927.8083,128102.5979,
136834.6159,146161.8454,156124.8586,166766.9931,178134.5408,190276.9488,
203247.0351,217101.2176,231899.7601,247707.0343,264591.7994,282627.5020,
301892.5949,322470.8784,344451.8652,367931.1696,393010.9233,419800.2196,
448415.5884,478981.5024,511630.9192,546505.8591,583758.0232,623549.4533,
666053.2366,711454.2585,759950.0073,811751.4325,867083.8633,926187.9879,
989320.9011,1056757.2222,1128790.2898,1205733.4377,1287921.3579,1375711.5564,
1469485.9082,1569652.3188,1676646.4980,1790933.8556,1913011.5257,2043410.5291,
2182698.0833,2331480.0696,2490403.6691,2660160.1771,2841488.0109,3035175.9211,
3242066.4233,3463059.4622,3699116.3267,3951263.8312,4220598.7823,4508292.7493,
4815597.1610,5143848.7486,5494475.3608,5869002.1744,6269058.3288,6696384.0126,
7152838.0327,7640405.9005,8161208.4683,8717511.1546,9311733.7984,9946461.1854,
10624454.2911,11348662.2911,12122235.3891,12948538.5201,13831165.9876,
14773957.0979,15781012.8607,16856713.8284,18005739.1499,19233086.9251,
20544095.9458,21944468.9182,23440297.2695,25038087.6444,26744790.2080,
28567828.8785,30515133.6199,32595174.9361,34817000.7167,37190275.5940,
39725322.9826,42433169.9851,45325595.3583,48415180.7489,51715365.4227,
55240504.7225,59005932.5125,63028027.8786,67324286.3744,71913396.1252,
76815319.1183,82051378.0350,87644349.0011,93618560.6603,100000000.0
]
post_id: 3530
aggregations:
recency_weighted:
history:
- start_time: 1580307151.25848
end_time: 1580486372.895453
forecast_values: null
forecaster_count: 24
interval_lower_bounds:
- 0.12959500321439227
centers:
- 0.25918927393346786
interval_upper_bounds:
- 0.4362854344258292
means: null
histogram: null
latest:
start_time: 1604186008.116567
end_time: null
forecast_values:
- 0.0023223077886532994
- 0.002387641461850537
- 0.0024531345535807863
forecaster_count: 545
interval_lower_bounds:
- 0.6809976958737698
centers:
- 0.703534857578826
interval_upper_bounds:
- 0.7304231105944988
means: null
histogram: null
score_data:
peer_score: 51.665686599518814
coverage: 0.9980877695216895
baseline_score: 35.14605488073114
spot_peer_score: 57.555204604943135
peer_archived_score: 51.665686599518814
baseline_archived_score: 35.14605488073114
spot_peer_archived_score: 57.555204604943135
unweighted:
history: [ ]
latest: null
score_data: { }
single_aggregation:
history: [ ]
latest: null
score_data: { }
metaculus_prediction:
history:
- start_time: 1580129296.168167
end_time: 1580280255.056228
forecast_values: null
forecaster_count: 1
interval_lower_bounds:
- 0.15523
centers:
- 0.17581
interval_upper_bounds:
- 0.19643
means: null
histogram: null
latest:
start_time: 1604186009.588382
end_time: null
forecast_values:
- 0.01088
- 0.010930492245919658
- 0.010980984491839312
forecaster_count: 545
interval_lower_bounds:
- 0.69824
centers:
- 0.71735
interval_upper_bounds:
- 0.73726
means: null
histogram: null
score_data: { }
user_permission: "forecaster"
vote:
score: 172
user_vote: null
forecasts_count: 2760
BinaryRequestExample:
summary: Post With Binary Question
value:
next: "https://www.metaculus.com/api/posts/"
previous: null
results:
- id: 1
title: "Will advanced LIGO announce discovery of gravitational waves by Jan. 31 2016?"
short_title: ""
slug: "will-advanced-ligo-announce-discovery-of-gravitational-waves-by-jan-31-2016"
author_id: 8
author_username: "Anthony"
coauthors: [ ]
projects: { }
created_at: "2015-10-02T02:35:57.581979Z"
published_at: "2015-10-02T02:34:00Z"
edited_at: "2024-10-03T07:58:31.800928Z"
curation_status: "approved"
comment_count: 5
status: "resolved"
resolved: true
actual_close_time: "2015-12-15T03:34:00Z"
scheduled_close_time: "2015-12-15T03:34:00Z"
scheduled_resolve_time: "2016-02-01T03:34:00Z"
open_time: "2015-10-02T02:34:00Z"
nr_forecasters: 10
question:
id: 1
title: "Will advanced LIGO announce discovery of gravitational waves by Jan. 31 2016?"
description: ""
created_at: "2015-10-02T02:35:57.581979Z"
open_time: "2015-10-02T02:34:00Z"
scheduled_resolve_time: "2016-02-01T03:34:00Z"
actual_resolve_time: "2016-02-01T03:34:00Z"
resolution_set_time: "2016-02-01T03:34:00Z"
scheduled_close_time: "2015-12-15T03:34:00Z"
actual_close_time: "2015-12-15T03:34:00Z"
type: "binary"
options: null
options_history: null
status: "resolved"
possibilities:
type: "binary"
resolution: "no"
resolution_criteria: "Resolution Criteria Copy"
fine_print: ""
label: null
open_upper_bound: null
open_lower_bound: null
unit: ""
scaling:
range_max: null
range_min: null
zero_point: null
open_upper_bound: null
open_lower_bound: null
inbound_outcome_count: null
continuous_range: null
post_id: 1
aggregations: { }
user_permission: "forecaster"
vote:
score: 6
user_vote: null
forecasts_count: 16
MultipleChoiceRequestExample:
summary: Post With Multiple-Choice Question
value:
next: "https://www.metaculus.com/api/posts/"
previous: null
results:
- id: 20772
title: "Which party will win the 2024 US presidential election?"
short_title: "Party Winning the Presidency in 2024?"
slug: "party-winning-the-presidency-in-2024"
author_id: 117502
author_username: "RyanBeck"
coauthors: [ ]
projects: { }
created_at: "2023-12-22T04:14:45.479858Z"
published_at: "2024-01-01T07:00:00Z"
edited_at: "2024-10-03T09:16:21.660122Z"
curation_status: "approved"
comment_count: 12
status: "open"
resolved: false
actual_close_time: null
scheduled_close_time: "2024-11-07T16:00:00Z"
scheduled_resolve_time: "2025-01-06T14:00:00Z"
open_time: "2024-01-01T07:00:00Z"
nr_forecasters: 984
question:
id: 20772
title: "Which party will win the 2024 US presidential election?"
description: "Long description"
created_at: "2023-12-22T04:14:45.479858Z"
open_time: "2024-01-01T07:00:00Z"
scheduled_resolve_time: "2025-01-06T14:00:00Z"
actual_resolve_time: null
resolution_set_time: null
scheduled_close_time: "2024-11-07T16:00:00Z"
actual_close_time: "2024-11-07T16:00:00Z"
type: "multiple_choice"
options:
- "Democratic"
- "Republican"
- "Libertarian"
- "Green"
- "Other"
all_options_ever:
- "Democratic"
- "Republican"
- "Libertarian"
- "Green"
- "Blue"
- "Other"
options_history:
- ["0001-01-01T00:00:00", ["Democratic", "Republican", "Libertarian", "Other"]]
- ["2026-10-22T16:00:00", ["Democratic", "Republican", "Libertarian", "Green", "Other"]]
status: "open"
possibilities: { }
resolution: null
resolution_criteria: "Resolution Criteria Copy"
fine_print: "Fine Print Copy"
label: null
open_upper_bound: null
open_lower_bound: null
unit: ""
scaling:
range_max: null
range_min: null
zero_point: null
open_upper_bound: null
open_lower_bound: null
inbound_outcome_count: null
continuous_range: null
post_id: 20772
aggregations: { }
user_permission: "forecaster"
vote:
score: 36
user_vote: null
forecasts_count: 2057
ConditionalRequestExample:
summary: Post With Conditional Questions
value:
next: "https://www.metaculus.com/api/posts/"
previous: null
results:
- id: 21475
title: "2024 Democratic Presidential Nominee? (Joe Biden) → Democrat Wins 2024 US Presidential Election?"
short_title: "Democrat Wins 2024 US Presidential Election?"
slug: "democrat-wins-2024-us-presidential-election"
author_id: 130973
author_username: "NMorrison"
coauthors: [ ]
projects: { }
created_at: "2024-02-21T01:37:23.166501Z"
published_at: "2024-02-21T07:00:00Z"
edited_at: "2024-09-30T15:59:05.961173Z"
curation_status: "approved"
comment_count: 7
status: "open"
resolved: false
actual_close_time: null
scheduled_close_time: "2024-11-05T13:00:00Z"
scheduled_resolve_time: "2025-01-21T05:00:00Z"
open_time: "2021-03-11T05:00:00Z"
nr_forecasters: 121
conditional:
id: 21475
condition:
id: 5712
title: "Who will be the Democratic nominee for the 2024 US Presidential Election? (Joe Biden)"
description: "Description"
created_at: "2020-11-13T05:21:18.530122Z"
open_time: "2021-03-11T05:00:00Z"
scheduled_resolve_time: "2024-09-01T04:00:00Z"
actual_resolve_time: "2024-08-21T01:30:00Z"
resolution_set_time: "2024-08-21T01:30:00Z"
scheduled_close_time: "2024-09-01T04:00:00Z"
actual_close_time: "2024-08-21T01:30:00Z"
type: "binary"
options: null
status: "resolved"
possibilities:
type: "binary"
resolution: "no"
resolution_criteria: "resolution_criteria"
fine_print: "fine_print"
label: null
open_upper_bound: null
open_lower_bound: null
unit: ""
scaling:
range_max: null
range_min: null
zero_point: null
open_upper_bound: null
open_lower_bound: null
inbound_outcome_count: null
continuous_range: null
post_id: 11379
aggregations: { }
condition_child:
id: 6478
title: "Will a Democrat win the 2024 US presidential election?"
description: "Description"
created_at: "2021-02-03T17:46:46.976981Z"
open_time: "2021-02-08T05:00:00Z"
scheduled_resolve_time: "2025-01-21T05:00:00Z"
actual_resolve_time: null
resolution_set_time: null
scheduled_close_time: "2024-11-05T13:00:00Z"
actual_close_time: "2024-11-05T13:00:00Z"
type: "binary"
options: null
status: "open"
possibilities:
type: "binary"
resolution: null
resolution_criteria: "Resolution Criteria"
fine_print: ""
label: null
open_upper_bound: null
open_lower_bound: null
unit: ""
scaling:
range_max: null
range_min: null
zero_point: null
open_upper_bound: null
open_lower_bound: null
inbound_outcome_count: null
continuous_range: null
post_id: 6478
aggregations: { }
question_yes:
id: 21477
title: "2024 Democratic Presidential Nominee (Joe Biden) (Yes) → Democrat Wins 2024 US Presidential Election?"
description: ""
created_at: "2024-02-21T01:37:24.033782Z"
open_time: "2024-02-21T07:00:00Z"
scheduled_resolve_time: "2024-09-01T04:00:00Z"
actual_resolve_time: "2024-08-21T01:30:00Z"
resolution_set_time: "2024-08-21T01:30:00Z"
scheduled_close_time: "2024-09-01T04:00:00Z"
actual_close_time: "2024-08-21T01:30:00Z"
type: "binary"
options: null
status: "resolved"
possibilities:
type: "binary"
resolution: "annulled"
resolution_criteria: ""
fine_print: ""
label: null
open_upper_bound: null
open_lower_bound: null
unit: ""
scaling:
range_max: null
range_min: null
zero_point: null
open_upper_bound: null
open_lower_bound: null
inbound_outcome_count: null
continuous_range: null
post_id: 21475
aggregations: { }
question_no:
id: 21476
title: "2024 Democratic Presidential Nominee? (Joe Biden) (No) → Democrat Wins 2024 US Presidential Election?"
description: ""
created_at: "2024-02-21T01:37:24.033665Z"
open_time: "2024-02-21T07:00:00Z"
scheduled_resolve_time: "2025-01-21T05:00:00Z"
actual_resolve_time: null
resolution_set_time: null
scheduled_close_time: "2024-09-01T04:00:00Z"
actual_close_time: "2024-08-21T01:30:00Z"
type: "binary"
options: null
status: "closed"
possibilities:
type: "binary"
resolution: null
resolution_criteria: ""
fine_print: ""
label: null
open_upper_bound: null
open_lower_bound: null
unit: ""
scaling:
range_max: null
range_min: null
zero_point: null
open_upper_bound: null
open_lower_bound: null
inbound_outcome_count: null
continuous_range: null
post_id: 21475
aggregations: { }
user_permission: "forecaster"
vote:
score: 25
user_vote: null
forecasts_count: 466
GroupOfQuestionsRequestExample:
summary: Post With Group Of Questions
value:
next: "https://www.metaculus.com/api/posts/"
previous: null
results:
- id: 11480
title: "Will China launch a full-scale invasion of Taiwan by the following years?"
short_title: "Chinese Invasion of Taiwan?"
slug: "chinese-invasion-of-taiwan"
author_id: 104161
author_username: "casens"
coauthors: [ ]
projects: { }
created_at: "2022-06-21T17:44:44.092940Z"
published_at: "2022-05-06T04:00:00Z"
edited_at: "2024-09-29T14:14:15.433250Z"
curation_status: "approved"
comment_count: 338
status: "open"
resolved: false
actual_close_time: null
scheduled_close_time: "2035-01-01T05:00:00Z"
scheduled_resolve_time: "2035-01-01T05:00:00Z"
open_time: "2022-05-06T04:00:00Z"
nr_forecasters: 764
group_of_questions:
id: 11480
description: "description"
resolution_criteria: "resolution_criteria"
fine_print: ""
group_variable: "Date"
graph_type: "multiple_choice_graph"
questions:
- id: 10880
title: "Will China launch a full-scale invasion of Taiwan by the following years? (2030)"
description: "description"
created_at: "2022-05-08T03:15:15.689218Z"
open_time: "2022-05-10T04:00:00Z"
scheduled_resolve_time: "2030-01-01T05:00:00Z"
actual_resolve_time: null
resolution_set_time: null
scheduled_close_time: "2030-01-01T05:00:00Z"
actual_close_time: "2030-01-01T05:00:00Z"
type: "binary"
options: null
status: "open"
possibilities:
type: "binary"
resolution: null
resolution_criteria: "resolution_criteria"
fine_print: ""
label: null
open_upper_bound: null
open_lower_bound: null
unit: ""
scaling:
range_max: null
range_min: null
zero_point: null
open_upper_bound: null
open_lower_bound: null
inbound_outcome_count: null
continuous_range: null
post_id: 11480
aggregations: { }
- id: 10923
title: "Will China launch a full-scale invasion of Taiwan by the following years? (2035)"
description: "description"
created_at: "2022-05-10T19:13:46.688335Z"
open_time: "2022-05-13T04:00:00Z"
scheduled_resolve_time: "2035-01-01T05:00:00Z"
actual_resolve_time: null
resolution_set_time: null
scheduled_close_time: "2035-01-01T05:00:00Z"
actual_close_time: "2035-01-01T05:00:00Z"
type: "binary"
options: null
status: "open"
possibilities:
type: "binary"
resolution: null
resolution_criteria: "resolution_criteria"
fine_print: ""
label: null
open_upper_bound: null
open_lower_bound: null
unit: ""
scaling:
range_max: null
range_min: null
zero_point: null
open_upper_bound: null
open_lower_bound: null
inbound_outcome_count: null
continuous_range: null
post_id: 11480
aggregations: { }
user_permission: "forecaster"
vote:
score: 69
user_vote: null
forecasts_count: 4670
/api/posts/{postId}/:
get:
summary: Retrieve post details
tags:
- Feed
parameters:
- name: postId
in: path
required: true
schema:
type: integer
description: The ID of the post to retrieve
responses:
'200':
description: Post details
content:
application/json:
schema:
$ref: '#/components/schemas/Post'
/api/data/download/:
get:
summary: Download data as a Zip file of CSVs
description: |
Downloads question data, forecast data, and optionally comments, scores, and key factors as a Zip file of CSVs.
You must provide at least one of `post_id`, `question_id`, or `project_id` to specify the data to download.
**Note:** This is a restricted endpoint. To request access, please fill out the [Metaculus Data Needs Form](https://docs.google.com/forms/d/e/1FAIpQLSeJhtZzHl5qMvBjbXbatyaqoS4IU7RE0GGw_vlhs6I9syqn1g/viewform?usp=pp_url&entry.192763438=https://www.metaculus.com/api/). For questions or feedback, contact [api-requests@metaculus.com](mailto:api-requests@metaculus.com). Additionally, the `project_id` parameter is only accepted if your account has been whitelisted for that specific project, to prevent heavy data requests.
This endpoint may time out for large data exports. If your download fails due to a timeout, use the `/api/data/email/` endpoint instead, which processes the export asynchronously.
tags:
- Utilities & Data
parameters:
- name: post_id
in: query
required: false
schema:
type: integer
description: The ID of the post to download data for.
- name: question_id
in: query
required: false
schema:
type: integer
description: The ID of the question to download data for.
- name: project_id
in: query
required: false
schema:
type: integer
description: The ID of the project to download data for.
- name: sub_question
in: query
required: false
schema:
type: integer
description: If the post contains a group or conditional question, specify a sub-question ID to download data for only that sub-question.
- name: aggregation_methods
in: query
required: false
schema:
type: string
description: |
Comma-separated list of aggregation methods to include, or `all` to include all available methods.
Valid methods: `recency_weighted`, `unweighted`, `metaculus_prediction`, `single_aggregation`.
`single_aggregation` is only available to site admins.
If not provided, only `recency_weighted` is included. Including this parameter triggers a recalculation of aggregations, which may increase response time.
- name: minimize
in: query
required: false
schema:
type: boolean
default: true
description: If false, includes all data points in recalculated aggregations (requires `aggregation_methods`). May result in very large files or server timeouts for questions with many forecasts.
- name: include_bots
in: query
required: false
schema:
type: boolean
description: Whether to include bot forecasts in aggregation recalculations. Requires `aggregation_methods`. If not given, uses the question's `include_bots_in_aggregations` setting.
- name: user_ids
in: query
required: false
schema:
type: array
items:
type: integer
description: A list of user IDs to recalculate aggregations for only those users' forecasts. Requires `aggregation_methods`. Only available to staff and whitelisted users.
- name: include_comments
in: query
required: false
schema:
type: boolean
default: false
description: If true, includes a CSV file containing all public comments.
- name: include_scores
in: query
required: false
schema:
type: boolean
default: true
description: If true, includes a CSV file containing all scores.
- name: include_key_factors
in: query
required: false
schema:
type: boolean
default: false
description: If true, includes key factors data in the download.
responses:
'200':
description: Zip file containing CSVs (question_data.csv, forecast_data.csv, and optionally comment_data.csv, score_data.csv)
content:
application/zip:
schema:
$ref: '#/components/schemas/DataZip'
/api/data/email/:
post:
summary: Email data as a Zip file of CSVs
description: |
Schedules an email to be sent to the authenticated user containing question data, forecast data, and optionally comments, scores, and key factors as a Zip file of CSVs.
Useful for large data exports that may time out with a direct download. Accepts the same parameters as `/api/data/download/`.
You must provide at least one of `post_id`, `question_id`, or `project_id`.
**Note:** This is a restricted endpoint. To request access, please fill out the [Metaculus Data Needs Form](https://docs.google.com/forms/d/e/1FAIpQLSeJhtZzHl5qMvBjbXbatyaqoS4IU7RE0GGw_vlhs6I9syqn1g/viewform?usp=pp_url&entry.192763438=https://www.metaculus.com/api/). For questions or feedback, contact [api-requests@metaculus.com](mailto:api-requests@metaculus.com). Additionally, the `project_id` parameter is only accepted if your account has been whitelisted for that specific project.
The email attachment has a size limit of 25 MB. If your export exceeds this limit, try removing `include_comments` to reduce the file size.
tags:
- Utilities & Data
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
post_id:
type: integer
description: The ID of the post to export data for.
question_id:
type: integer
description: The ID of the question to export data for.
project_id:
type: integer
description: The ID of the project to export data for.
sub_question:
type: integer
description: If the post contains a group or conditional question, specify a sub-question ID.
aggregation_methods:
type: array
items:
type: string
description: "List of aggregation methods to include. Valid methods: `recency_weighted`, `unweighted`, `metaculus_prediction`, `single_aggregation`."
minimize:
type: boolean
default: true
description: If false, includes all data points in recalculated aggregations.
include_bots:
type: boolean
description: Whether to include bot forecasts in aggregation recalculations.
user_ids:
type: array
items:
type: integer
description: A list of user IDs to restrict aggregation recalculations to. Only available to staff and whitelisted users.
include_comments:
type: boolean
default: false
description: If true, includes comment data.
include_scores:
type: boolean
default: true
description: If true, includes score data.
include_key_factors:
type: boolean
default: false
description: If true, includes key factors data.
responses:
'200':
description: Email scheduled successfully
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "Email scheduled to be sent"
/api/questions/forecast/:
post:
summary: Submit forecasts for questions
description: This endpoint supports multiple simultaneous predictions, so the base object is a list of forecasts.
Pass one forecast object for single questions and multiple forecast objects for group of questions or conditional forecasts.
tags:
- Questions & Forecasts
requestBody:
required: true
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Forecast'
examples:
BinaryQuestionExample:
summary: Binary Question
value:
- question: 1
probability_yes: 0.63
ContinuousQuestionExample1:
summary: Continuous Question - closed bounds
value:
- question: 1
continuous_cdf: [
0.00000, 0.00005, 0.00010, 0.00015, 0.00020, 0.00025, 0.00030, 0.00035,
0.00040, 0.00045, 0.00050, 0.00055, 0.00060, 0.00065, 0.00070, 0.00075,
0.00080, 0.00085, 0.00090, 0.00095, 0.00100, 0.00105, 0.00110, 0.00115,
0.00120, 0.00125, 0.00130, 0.00135, 0.00140, 0.00145, 0.00150, 0.00155,
0.00160, 0.00165, 0.00170, 0.00175, 0.00180, 0.00185, 0.00190, 0.00195,
0.00200, 0.00205, 0.00210, 0.00215, 0.00220, 0.00225, 0.00230, 0.00236,
0.00241, 0.00246, 0.00251, 0.00256, 0.00261, 0.00266, 0.00272, 0.00277,
0.00282, 0.00287, 0.00293, 0.00298, 0.00304, 0.00309, 0.00314, 0.00320,
0.00326, 0.00331, 0.00337, 0.00343, 0.00349, 0.00354, 0.00361, 0.00367,
0.00373, 0.00379, 0.00386, 0.00393, 0.00400, 0.00407, 0.00414, 0.00422,
0.00430, 0.00438, 0.00447, 0.00456, 0.00465, 0.00475, 0.00485, 0.00496,
0.00508, 0.00520, 0.00533, 0.00547, 0.00562, 0.00578, 0.00595, 0.00614,
0.00633, 0.00655, 0.00678, 0.00703, 0.00730, 0.00760, 0.00792, 0.00827,
0.00865, 0.00907, 0.00952, 0.01002, 0.01057, 0.01117, 0.01182, 0.01254,
0.01334, 0.01420, 0.01516, 0.01621, 0.01736, 0.01863, 0.02002, 0.02156,
0.02324, 0.02510, 0.02714, 0.02938, 0.03185, 0.03455, 0.03753, 0.04080,
0.04438, 0.04832, 0.05263, 0.05735, 0.06252, 0.06817, 0.07434, 0.08108,
0.08841, 0.09639, 0.10506, 0.11447, 0.12464, 0.13564, 0.14749, 0.16024,
0.17392, 0.18855, 0.20416, 0.22076, 0.23835, 0.25693, 0.27649, 0.29698,
0.31838, 0.34062, 0.36363, 0.38733, 0.41164, 0.43643, 0.46160, 0.48702,
0.51257, 0.53811, 0.56352, 0.58866, 0.61342, 0.63768, 0.66134, 0.68429,
0.70646, 0.72779, 0.74821, 0.76769, 0.78619, 0.80370, 0.82022, 0.83575,
0.85031, 0.86391, 0.87658, 0.88837, 0.89930, 0.90941, 0.91875, 0.92737,
0.93530, 0.94258, 0.94927, 0.95540, 0.96101, 0.96614, 0.97083, 0.97511,
0.97901, 0.98257, 0.98582, 0.98877, 0.99146, 0.99390, 0.99613, 0.99815,
1.00000
]
ContinuousQuestionExample2:
summary: Continuous Question - open lower bound, closed upper bound
value:
- question: 1
continuous_cdf: [
0.00655, 0.00690, 0.00727, 0.00766, 0.00807, 0.00849, 0.00894, 0.00941,
0.00990, 0.01042, 0.01096, 0.01152, 0.01212, 0.01274, 0.01340, 0.01409,
0.01481, 0.01557, 0.01636, 0.01720, 0.01808, 0.01900, 0.01997, 0.02099,
0.02206, 0.02318, 0.02436, 0.02560, 0.02690, 0.02827, 0.02970, 0.03121,
0.03280, 0.03446, 0.03621, 0.03804, 0.03997, 0.04199, 0.04411, 0.04634,
0.04868, 0.05113, 0.05370, 0.05639, 0.05922, 0.06218, 0.06528, 0.06853,
0.07193, 0.07550, 0.07923, 0.08313, 0.08721, 0.09147, 0.09593, 0.10058,
0.10544, 0.11051, 0.11580, 0.12131, 0.12705, 0.13303, 0.13925, 0.14572,
0.15244, 0.15942, 0.16667, 0.17418, 0.18197, 0.19003, 0.19837, 0.20699,
0.21589, 0.22508, 0.23454, 0.24429, 0.25432, 0.26463, 0.27521, 0.28606,
0.29717, 0.30854, 0.32015, 0.33201, 0.34410, 0.35640, 0.36891, 0.38162,
0.39450, 0.40755, 0.42075, 0.43408, 0.44752, 0.46106, 0.47468, 0.48836,
0.50207, 0.51581, 0.52954, 0.54325, 0.55692, 0.57052, 0.58404, 0.59745,
0.61073, 0.62386, 0.63683, 0.64962, 0.66221, 0.67458, 0.68673, 0.69863,
0.71029, 0.72168, 0.73280, 0.74364, 0.75420, 0.76447, 0.77444, 0.78412,
0.79350, 0.80258, 0.81136, 0.81984, 0.82802, 0.83592, 0.84352, 0.85084,
0.85788, 0.86464, 0.87114, 0.87737, 0.88334, 0.88907, 0.89455, 0.89979,
0.90481, 0.90961, 0.91419, 0.91856, 0.92273, 0.92671, 0.93051, 0.93413,
0.93758, 0.94086, 0.94399, 0.94697, 0.94980, 0.95249, 0.95505, 0.95749,
0.95980, 0.96200, 0.96410, 0.96608, 0.96797, 0.96976, 0.97146, 0.97308,
0.97461, 0.97607, 0.97745, 0.97877, 0.98001, 0.98120, 0.98232, 0.98339,
0.98440, 0.98536, 0.98627, 0.98713, 0.98796, 0.98874, 0.98948, 0.99018,
0.99085, 0.99149, 0.99209, 0.99266, 0.99321, 0.99373, 0.99422, 0.99469,
0.99513, 0.99556, 0.99596, 0.99635, 0.99671, 0.99706, 0.99739, 0.99771,
0.99801, 0.99830, 0.99858, 0.99884, 0.99909, 0.99933, 0.99956, 0.99978,
1.00000
]
ContinuousQuestionExample3:
summary: Discrete Question - inbound_outcome_count = 10, closed bounds
value:
- question: 1
continuous_cdf: [0, 0.05, 0.1, 0.15, 0.2, 0.35, 0.6, 0.75, 0.85, 0.95, 1.0]
MultipleChoiceQuestionExample:
summary: Multiple Choice
value:
- question: 1
probability_yes_per_category:
{
"Futurama": 0.5,
"Paperclipalypse": 0.3,
"Singularia": 0.2
}
ConditionalQuestionExample:
summary: Conditional Question
value:
[
# Forecast for question "if Yes"
{
"question": 1,
"probability_yes": 0.499,
},
# Forecast for question "if No"
{
"question": 2,
"probability_yes": 0.501,
}
]
BinaryGroupExample:
summary: Binary group of questions forecast example
value:
[
{ "question": 1, "probability_yes": 0.11 },
{ "question": 2, "probability_yes": 0.22 },
{ "question": 3, "probability_yes": 0.33 }
]
responses:
'201':
description: Forecasts submitted successfully
'400':
description: Invalid request format
/api/questions/withdraw/:
post:
summary: Withdraw current forecasts for questions
description: This endpoint supports multiple simultaneous withdrawals, so the base object is a list of withdrawals.
Pass one withdrawal object for single questions and multiple withdrawal objects for group of questions or conditional forecasts.
tags:
- Questions & Forecasts
requestBody:
required: true
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Withdrawal'
/api/comments/create/:
post:
summary: Create a new comment
description: Submit a new comment on a post
tags:
- Comments
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- included_forecast
- is_private
- on_post
- text
properties:
included_forecast:
type: boolean
description: Include the user's last forecast.
is_private:
type: boolean
description: If the comment is private or public.
on_post:
type: integer
description: ID of the post.
parent:
type: integer
description: ID of the comment you're replying to.
text:
type: string
description: The content of the comment.
examples:
CreateCommentExample:
summary: Example of a comment creation
value:
included_forecast: false
is_private: false
on_post: 1
text: "Bot comment"
responses:
'201':
description: Comment created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Comment'
'400':
description: Invalid request format
/api/comments/:
get:
summary: Retrieve comments
description: |
Fetch comments with filters for author and pagination. If API access is restricted, you must include at least one of: `author=` and/or `author_is_staff=true` - requests without one of these filters will be rejected.
tags:
- Comments
parameters:
- name: post
in: query
required: false
schema:
type: integer
description: ID of the post to filter comments by.
- name: author
in: query
required: false
schema:
type: integer
description: Filter comments by author user ID. Use your own user ID to retrieve your comments.
- name: author_is_staff
in: query
required: false
schema:
type: boolean
description: "When set to `true`, returns root-level comments authored by Metaculus staff (staff replies to other comments are not included). Treated as an 'OR' filter with `author`."
- name: limit
in: query
required: false
schema:
type: integer
description: Number of comments to retrieve.
- name: offset
in: query
required: false
schema:
type: integer
description: Offset for pagination.
- name: is_private
in: query
required: false
schema:
type: boolean
default: false
description: Filter between private comments (for the current user) and public comments. Defaults to false.
- name: use_root_comments_pagination
in: query
required: false
schema:
type: boolean
description: If true, pagination will only apply to root comments, and all child comments will be included for those root comments.
- name: sort
in: query
required: false
schema:
type: string
enum: [ "-created_at", "created_at" ]
description: Sort comments by creation date. Use `-created_at` for descending order.
- name: focus_comment_id
in: query
required: false
schema:
type: integer
description: The ID of a comment to place at the top of the results.
responses:
'200':
description: List of comments
content:
application/json:
schema:
type: object
properties:
total_count:
type: integer
description: Total number of root and child comments.
count:
type: integer
description: Total number of root comments only.
next:
type: string
format: uri
nullable: true
description: URL for the next page of results, if available.
previous:
type: string
format: uri
nullable: true
description: URL for the previous page of results, if available.
results:
type: array
items:
$ref: '#/components/schemas/Comment'
'400':
description: Invalid request format