Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Metaculus/metaculus/llms.txt
Use this file to discover all available pages before exploring further.
This guide shows you how to submit forecasts for different question types using the Metaculus API.
Prerequisites
All API requests require authentication. Make sure you have:
- Generated an API token from your account settings
- Include the token in the
Authorization header: Token YOUR_API_TOKEN
Binary Questions
Binary questions have yes/no outcomes. Submit a probability between 0 and 1.
Get the question details
First, retrieve the question to get its ID and confirm itβs a binary question:import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get post details
post_id = 1
response = requests.get(
f"https://www.metaculus.com/api/posts/{post_id}/",
headers=headers
)
post_data = response.json()
question = post_data["question"]
print(f"Question ID: {question['id']}")
print(f"Type: {question['type']}")
print(f"Title: {question['title']}")
Submit your binary forecast
Submit a probability for the yes outcome:import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Submit binary forecast
forecast_data = [
{
"question": 1, # Question ID
"probability_yes": 0.63
}
]
response = requests.post(
"https://www.metaculus.com/api/questions/forecast/",
headers=headers,
json=forecast_data
)
if response.status_code == 201:
print("Forecast submitted successfully!")
else:
print(f"Error: {response.status_code}")
print(response.json())
Numeric Questions (Continuous)
Numeric questions require a 201-point CDF (Cumulative Distribution Function). For detailed guidance on generating CDFs, see the Continuous CDF Guide.
Get the question scaling
Retrieve the question details to understand its range and scaling:import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get question details
post_id = 3530
response = requests.get(
f"https://www.metaculus.com/api/posts/{post_id}/",
headers=headers
)
question = response.json()["question"]
print(f"Type: {question['type']}")
print(f"Range: {question['scaling']['range_min']} to {question['scaling']['range_max']}")
print(f"Unit: {question['unit']}")
print(f"Open lower bound: {question['open_lower_bound']}")
print(f"Open upper bound: {question['open_upper_bound']}")
Generate a CDF
Create a 201-point CDF. This example shows a simple approach:import numpy as np
# For a question with closed bounds (range_min to range_max)
# Generate a simple normal-like distribution
def simple_cdf(mean_location=0.5, spread=0.3):
"""
Generate a 201-point CDF.
mean_location: center of distribution (0 to 1)
spread: how spread out the distribution is
"""
points = np.linspace(0, 1, 201)
# Simple sigmoid-based CDF
cdf = 1 / (1 + np.exp(-(points - mean_location) / spread))
# Normalize to [0, 1]
cdf = (cdf - cdf.min()) / (cdf.max() - cdf.min())
return cdf.tolist()
my_cdf = simple_cdf(mean_location=0.6, spread=0.15)
print(f"CDF has {len(my_cdf)} points")
print(f"First value: {my_cdf[0]:.5f}, Last value: {my_cdf[-1]:.5f}")
For production use, see the Continuous CDF Guide for proper CDF generation that handles:
- Linear and logarithmic scaling
- Open and closed bounds
- Percentile-based distributions
- CDF standardization and validation
Submit your numeric forecast
Submit the CDF to the API:import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Submit continuous forecast
forecast_data = [
{
"question": 3530,
"continuous_cdf": my_cdf # 201-point list
}
]
response = requests.post(
"https://www.metaculus.com/api/questions/forecast/",
headers=headers,
json=forecast_data
)
if response.status_code == 201:
print("Forecast submitted successfully!")
else:
print(f"Error: {response.status_code}")
print(response.json())
Multiple Choice Questions
For multiple choice questions, provide probabilities for each option that sum to 1.0.
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Submit multiple choice forecast
forecast_data = [
{
"question": 20772,
"probability_yes_per_category": {
"Democratic": 0.45,
"Republican": 0.40,
"Libertarian": 0.08,
"Green": 0.05,
"Other": 0.02
}
}
]
response = requests.post(
"https://www.metaculus.com/api/questions/forecast/",
headers=headers,
json=forecast_data
)
if response.status_code == 201:
print("Forecast submitted successfully!")
The probabilities must sum to exactly 1.0, or the API will reject your forecast.
Group of Questions
For posts containing multiple sub-questions, submit forecasts for each one:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Submit forecasts for multiple questions in a group
forecast_data = [
{"question": 10880, "probability_yes": 0.11}, # 2030
{"question": 10923, "probability_yes": 0.22}, # 2035
{"question": 10924, "probability_yes": 0.33} # 2040
]
response = requests.post(
"https://www.metaculus.com/api/questions/forecast/",
headers=headers,
json=forecast_data
)
if response.status_code == 201:
print("All forecasts submitted successfully!")
Withdrawing Forecasts
You can withdraw your current forecast on a question:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Withdraw forecast
withdrawal_data = [
{"question": 1}
]
response = requests.post(
"https://www.metaculus.com/api/questions/withdraw/",
headers=headers,
json=withdrawal_data
)
if response.status_code == 201:
print("Forecast withdrawn successfully!")
Next Steps