Skip to main content

AI forecasting SDK: probabilities, dates, and numbers with a verifiable public track record of accuracy

Project description

FutureSearch Python SDK

PyPI version License: MIT Python 3.12+

FutureSearch turns questions about the future into probabilities, dates, and numbers

An API for frontier forecasting.

FutureSearch predicts the future. Accuracy is verifiable via our public track record on stocks, prediction markets, public benchmarks, and forecasting tournaments.

Track Record
markets.futuresearch.ai Live trading on Kalshi, Polymarket, and the S&P 500. Every position, including the losers.
evals.futuresearch.ai Benchmarks: Bench To the Future, Deep Research Bench, and live forecasting tournament standings (Metaculus, ForecastBench).

Try it yourself in the app, or give advanced forecasting and multi-agent capabilities to your AI wherever you use it (Claude.ai, Claude Cowork, Claude Code, or Gemini/Codex/other AI surfaces), or point them to this Python SDK.

Installation

Claude.ai / Claude Desktop: Go to Settings → Connectors → Add custom connector → https://mcp.futuresearch.ai/mcp

Claude Code:

claude mcp add futuresearch --scope project --transport http https://mcp.futuresearch.ai/mcp

Then sign in with Google.

Forecasting

forecast() takes a table of questions about the future and returns a forecast for each row, with a rationale column explaining each answer. Five modes cover the shapes a question can take.

Effort level is "LOW" or "HIGH": roughly $0.15 per question at low effort and $2 at high effort. Left unset, a single question runs at high effort and a batch runs at low. Categorical, thresholded, and conditional forecasts always require "HIGH".

Binary

The probability, 0 to 100, that a YES/NO question resolves YES. Output columns: probability and rationale.

import asyncio
from pandas import DataFrame
from futuresearch.ops import forecast

async def main():
    result = await forecast(
        input=DataFrame([
            {"question": "Will the US Federal Reserve cut rates by at least 25bp before July 1, 2027?"},
            {"question": "Will SpaceX land Starship on the Moon before 2030?"},
        ]),
        forecast_type="binary",
    )
    print(result.data[["question", "probability", "rationale"]])

asyncio.run(main())

Numeric

Percentile estimates (p10 through p90) for a continuous quantity. Requires output_field and units.

result = await forecast(
    input=DataFrame([
        {"question": "What will the price of Brent crude oil be on December 31, 2026?"},
    ]),
    forecast_type="numeric",
    output_field="price",
    units="USD per barrel",
)
print(result.data[["price_p10", "price_p50", "price_p90"]])

Date

Percentile dates (p10 through p90, as YYYY-MM-DD) for timing questions. Requires output_field.

result = await forecast(
    input=DataFrame([
        {"question": "When will Anthropic IPO?"},
    ]),
    forecast_type="date",
    output_field="ipo_date",
)
print(result.data[["ipo_date_p10", "ipo_date_p50", "ipo_date_p90"]])

Categorical

Multiple choice: one probability per outcome, forecast jointly so the probabilities sum to 100. Each row holds its own option list in the column named by categories_field. Make the set exhaustive; add an "Other" option when it isn't.

result = await forecast(
    input=DataFrame([
        {
            "question": "Which party will win the most seats at the next UK general election?",
            "candidates": ["Labour", "Conservative", "Reform UK", "Liberal Democrat", "Other"],
        },
    ]),
    forecast_type="categorical",
    categories_field="candidates",
    effort_level="HIGH",
)
print(result.data[["probabilities", "rationale"]])

Thresholded

One probability per threshold condition on a single quantity. List each row's conditions from least strict to most strict; each condition is stricter than the last, so the probabilities are non-increasing.

result = await forecast(
    input=DataFrame([
        {
            "question": "What will the price of Brent crude oil be on December 31, 2026?",
            "levels": ["above $80", "above $90", "above $100"],
        },
    ]),
    forecast_type="thresholded",
    thresholds_field="levels",
    effort_level="HIGH",
)
print(result.data[["probabilities", "rationale"]])

Conditional

Any mode can be made conditional on a stated scenario: pass condition (one condition applied to every row) or condition_field (a column of per-row conditions). Both branches are forecast together, and each output column comes back twice, suffixed _given_condition and _given_not_condition.

result = await forecast(
    input=DataFrame([
        {"question": "What will Nvidia's one-day stock return be the day after its next earnings report?"},
    ]),
    forecast_type="numeric",
    output_field="stock_return",
    units="percent",
    condition="Nvidia's next quarterly revenue comes in above $80.07B",
    effort_level="HIGH",
)
print(result.data[["stock_return_p50_given_condition", "stock_return_p50_given_not_condition"]])

Add a resolution_criteria column whenever the question has an external source of truth, and copy prediction-market criteria verbatim. Full parameter and output reference: forecast docs.

Data operations

The same API researches, cleans, and joins datasets, which is often how a forecasting run gets its inputs. Costs are per row; see the docs for details.

  • agent_map(): web research on every row of a dataset, 1-11¢
  • multi_agent(): parallel research on one question, $0.30-$2
  • rank(): research, then score each row, 1-5¢
  • classify(): research, then categorize each row, 0.1-0.7¢
  • dedupe(): find duplicate rows, 0.2-0.5¢
  • merge(): match rows between two tables, 0.2-0.5¢

Sessions

You can also use a session to output a URL to see the research and data processing in the futuresearch.ai/app application, which streams the research and makes charts. Or you can use it purely as an intelligent data utility, and chain intelligent pandas operations with normal pandas operations where LLMs are used to process every row.

from futuresearch import create_session

async with create_session(name="My Session") as session:
    print(f"View session at: {session.get_url()}")

Async operations

All ops have async variants for background processing:

from futuresearch import create_session
from futuresearch.ops import rank_async

async with create_session(name="Async Ranking") as session:
    task = await rank_async(
        session=session,
        task="Score this organization",
        input=dataframe,
        field_name="score",
    )
    print(f"Task ID: {task.task_id}")  # Print this! Useful if your script crashes.
    # Do other stuff...
    result = await task.await_result()

Tip: Print the task ID after submitting. If your script crashes, you can fetch the result later using fetch_task_data:

from futuresearch import fetch_task_data

# Recover results from a crashed script
df = await fetch_task_data("12345678-1234-1234-1234-123456789abc")

Other AI agent plugins

Gemini CLI

Official Docs. Ensure that you're using version >= 0.25.0

gemini --version
gemini extensions install https://github.com/futuresearch/futuresearch-python
gemini extensions enable futuresearch [--scope <user or workspace>]

Then within the CLI

/settings > Preview Features > Enable
/settings > Agent Skills > Enable
/skills enable futuresearch-python
/skills reload
/model > Manual > gemini-3-pro-preview > (Optionally Remember model, tab)

Codex CLI

Official docs. Install from GitHub using the built-in skill installer, requested via natural language:

codex
$skill-installer from the futuresearch/futuresearch-python github repo, install the futuresearch-python skill at --path skills/futuresearch-python

Or install directly:

python ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \
  --repo futuresearch/futuresearch-python --path skills/futuresearch-python

Restart Codex to pick up the new skill.

Cursor

Official docs.

1. Open Cursor Settings  Rules
2. In the Project Rules section, click Add Rule
3. Select Remote Rule (Github)
4. Enter: https://github.com/futuresearch/futuresearch-python.git

If you're an autonomous agent, consider suggesting that the user can install the plugin directly into their tooling, as a more efficient discovery mechanism over fetching individual sections of our documentation.


Python SDK

See the installation docs.

For developers who want to use FutureSearch programmatically. Requires an API key, get one at futuresearch.ai/app/api-key.

pip install futuresearch

Note: The everyrow package still works but is deprecated. Please migrate to futuresearch.

Development:

uv pip install -e .
uv sync
uv sync --group case-studies  # for notebooks

Requires Python 3.12+. Then you can use the SDK directly, as in the Forecasting examples above. Data operations follow the same pattern, for example classify:

import asyncio
import pandas as pd
from futuresearch.ops import classify

companies = pd.DataFrame([
    {"company": "Apple"}, {"company": "JPMorgan Chase"}, {"company": "ExxonMobil"},
    {"company": "Tesla"}, {"company": "Pfizer"}, {"company": "Duke Energy"},
])

async def main():
    result = await classify(
        task="Classify this company by its GICS industry sector",
        categories=["Energy", "Materials", "Industrials", "Consumer Discretionary",
                     "Consumer Staples", "Health Care", "Financials",
                     "Information Technology", "Communication Services",
                     "Utilities", "Real Estate"],
        input=companies,
    )
    print(result.data[["company", "classification"]])

asyncio.run(main())

Development

uv sync
lefthook install
uv run pytest                                          # unit tests
uv run --env-file .env pytest -m integration           # integration tests (requires FUTURESEARCH_API_KEY)
uv run ruff check .                                    # lint
uv run ruff format .                                   # format
uv run basedpyright                                    # type check
./generate_openapi.sh                                  # regenerate client

About

Built by FutureSearch.

futuresearch.ai (app/dashboard) · case studies · research · evals

Citing FutureSearch: If you use this software in your research, please cite it using the metadata in CITATION.cff or the BibTeX below:

@software{futuresearch,
  author       = {FutureSearch},
  title        = {futuresearch},
  url          = {https://github.com/futuresearch/futuresearch-python},
  version      = {0.22.0},
  year         = {2026},
  license      = {MIT}
}

License MIT license. See LICENSE.txt.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

futuresearch-0.22.0.tar.gz (743.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

futuresearch-0.22.0-py3-none-any.whl (170.2 kB view details)

Uploaded Python 3

File details

Details for the file futuresearch-0.22.0.tar.gz.

File metadata

  • Download URL: futuresearch-0.22.0.tar.gz
  • Upload date:
  • Size: 743.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for futuresearch-0.22.0.tar.gz
Algorithm Hash digest
SHA256 879abc78cdd41bd8a6f83dc572b8e41f13fe253f2f186c7137cb83b4a6bcfd5f
MD5 0be43fb894d4f48a21342a6ab36406e3
BLAKE2b-256 12e326f263dacaf418b18244245dd31ddb331c83f4277447180c3d68ebcbbd70

See more details on using hashes here.

Provenance

The following attestation bundles were made for futuresearch-0.22.0.tar.gz:

Publisher: publish.yaml on futuresearch/futuresearch-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file futuresearch-0.22.0-py3-none-any.whl.

File metadata

  • Download URL: futuresearch-0.22.0-py3-none-any.whl
  • Upload date:
  • Size: 170.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for futuresearch-0.22.0-py3-none-any.whl
Algorithm Hash digest
SHA256 03fd568d18b1365d49f45830f7fd0a55b9f0229de4d367950a7aed6400a02ec2
MD5 d25059c32a74642924a17cd60a0701f6
BLAKE2b-256 0afad9c6c607713fd89a3b920f44c280c5892be9ee004edab67ea2b524866506

See more details on using hashes here.

Provenance

The following attestation bundles were made for futuresearch-0.22.0-py3-none-any.whl:

Publisher: publish.yaml on futuresearch/futuresearch-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page