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 demonstrates how to retrieve questions from the Metaculus API using various filters and pagination.
Basic Query
Retrieve a feed of posts (which contain questions):
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get posts feed
response = requests.get(
"https://www.metaculus.com/api/posts/",
headers=headers
)
data = response.json()
print(f"Total posts: {len(data['results'])}")
print(f"Next page: {data['next']}")
for post in data['results']:
print(f"Post {post['id']}: {post['title']}")
if post.get('question'):
print(f" Question type: {post['question']['type']}")
Filtering by Question Type
Filter posts by the type of question they contain:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get only binary questions
params = {
"forecast_type": ["binary"],
"limit": 20
}
response = requests.get(
"https://www.metaculus.com/api/posts/",
headers=headers,
params=params
)
data = response.json()
for post in data['results']:
question = post.get('question')
if question:
print(f"{question['title']}")
print(f" Status: {question['status']}")
print(f" Open time: {question['open_time']}")
print()
Available Question Types
binary - Yes/no questions
multiple_choice - Questions with multiple options
numeric - Continuous numeric predictions
date - Date predictions
conditional - Conditional question pairs
group_of_questions - Multiple related sub-questions
Filtering by Status
Get questions based on their lifecycle status:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get only open questions
params = {
"statuses": ["open"],
"forecast_type": ["numeric"],
"limit": 10
}
response = requests.get(
"https://www.metaculus.com/api/posts/",
headers=headers,
params=params
)
data = response.json()
print(f"Found {len(data['results'])} open numeric questions")
for post in data['results']:
question = post.get('question')
if question:
print(f"\nQuestion ID: {question['id']}")
print(f"Title: {question['title']}")
print(f"Close time: {question['scheduled_close_time']}")
print(f"Range: {question['scaling']['range_min']} to {question['scaling']['range_max']}")
Available Statuses
upcoming - Not yet open for forecasting
open - Currently accepting forecasts
closed - No longer accepting forecasts
resolved - Question has been resolved
Filtering by Tournament
Get questions from specific tournaments or projects:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get questions from specific tournaments
params = {
"tournaments": ["ai-forecasting", "metaculus-cup"],
"statuses": ["open"],
"limit": 20
}
response = requests.get(
"https://www.metaculus.com/api/posts/",
headers=headers,
params=params
)
data = response.json()
for post in data['results']:
print(f"Post: {post['title']}")
# Show which tournaments this post belongs to
if post.get('projects', {}).get('tournament'):
tournaments = [t['name'] for t in post['projects']['tournament']]
print(f" Tournaments: {', '.join(tournaments)}")
print()
Filtering by Category
Filter questions by topic categories:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get questions from specific categories
params = {
"categories": ["nuclear", "health-pandemics"],
"statuses": ["open"],
"limit": 15
}
response = requests.get(
"https://www.metaculus.com/api/posts/",
headers=headers,
params=params
)
data = response.json()
for post in data['results']:
print(f"\n{post['title']}")
if post.get('projects', {}).get('category'):
categories = [c['name'] for c in post['projects']['category']]
print(f"Categories: {', '.join(categories)}")
Filtering by Date Range
Get questions that opened, close, or resolve within specific date ranges:
import requests
from datetime import datetime, timedelta
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get questions that opened in the last 7 days
week_ago = (datetime.now() - timedelta(days=7)).isoformat()
params = {
"open_time__gte": week_ago,
"statuses": ["open"],
"limit": 20,
"order_by": "-open_time" # Most recent first
}
response = requests.get(
"https://www.metaculus.com/api/posts/",
headers=headers,
params=params
)
data = response.json()
print(f"Found {len(data['results'])} questions opened in the last week\n")
for post in data['results']:
question = post.get('question')
if question:
print(f"{question['title']}")
print(f" Opened: {question['open_time']}")
print(f" Type: {question['type']}")
print()
Available Date Filters
Each filter supports these operators:
__gt - Greater than
__gte - Greater than or equal to
__lt - Less than
__lte - Less than or equal to
Date filter fields:
open_time - When the question opened for forecasting
published_at - When the post was published
scheduled_resolve_time - When the question is scheduled to resolve
Handle large result sets with pagination:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
def fetch_all_pages(initial_url, max_pages=5):
"""Fetch multiple pages of results"""
all_posts = []
url = initial_url
page = 0
while url and page < max_pages:
response = requests.get(url, headers=headers)
data = response.json()
all_posts.extend(data['results'])
url = data.get('next') # URL for next page
page += 1
print(f"Fetched page {page}, total posts: {len(all_posts)}")
return all_posts
# Fetch first 5 pages of binary questions
params = {
"forecast_type": ["binary"],
"statuses": ["open"],
"limit": 20,
"offset": 0
}
base_url = "https://www.metaculus.com/api/posts/"
first_url = f"{base_url}?" + "&".join([f"{k}={v}" for k, v in params.items()])
posts = fetch_all_pages(first_url)
print(f"\nTotal posts fetched: {len(posts)}")
Sorting Results
Order results by different criteria:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get most commented questions
params = {
"statuses": ["open"],
"order_by": "-comment_count", # Prefix with - for descending
"limit": 10
}
response = requests.get(
"https://www.metaculus.com/api/posts/",
headers=headers,
params=params
)
data = response.json()
print("Most discussed questions:\n")
for post in data['results']:
print(f"{post['title']}")
print(f" Comments: {post['comment_count']}")
print(f" Forecasters: {post['nr_forecasters']}")
print()
Available Sort Options
published_at - Publication date
open_time - When question opened
vote_score - Community votes
comment_count - Number of comments
forecasts_count - Number of forecasts
scheduled_close_time - Close date
scheduled_resolve_time - Resolution date
hotness - Composite popularity score
weekly_movement - Recent forecast changes
divergence - Disagreement among forecasters
Prefix with - for descending order (e.g., -published_at).
Getting a Single Post
Retrieve detailed information about a specific post:
import requests
API_TOKEN = "your_api_token_here"
headers = {"Authorization": f"Token {API_TOKEN}"}
# Get specific post by ID
post_id = 3530
response = requests.get(
f"https://www.metaculus.com/api/posts/{post_id}/",
headers=headers
)
post = response.json()
print(f"Title: {post['title']}")
print(f"Status: {post['status']}")
print(f"Forecasters: {post['nr_forecasters']}")
print(f"Comments: {post['comment_count']}")
if post.get('question'):
question = post['question']
print(f"\nQuestion Details:")
print(f" Type: {question['type']}")
print(f" ID: {question['id']}")
print(f" Open: {question['open_time']}")
print(f" Close: {question['scheduled_close_time']}")
if question['type'] in ['numeric', 'date']:
print(f" Range: {question['scaling']['range_min']} to {question['scaling']['range_max']}")
print(f" Open bounds: lower={question['open_lower_bound']}, upper={question['open_upper_bound']}")
Next Steps