---
title: "Run a single forecasting prediction"
method: POST
path: "/predict"
tags: ["Inference"]
---

# Run a single forecasting prediction

`POST /predict`

## Request

- Base URL: `https://foresea.ink` (the document declares no server; this is the origin it was published from)
- URL: `https://foresea.ink/predict`
- Auth: none declared

Submit a forecasting question and receive a typed structured prediction.

The model returns:
- **`question_type`** — `binary`, `multiple_choice`, `numeric`, or `date`
- **`predicted_answer`** — `Yes`/`No`, top option, or median estimate
- **`confidence`** — probability (0–1) for binary and multiple-choice answers
- **`options`** — per-option probabilities for multiple-choice questions
- **`range_forecast`** — p10/p50/p90 bounds for numeric and date questions
- **`rationale`** — 2–4 sentence explanation
- **`evidence_sources`** — news articles used as context
- **`market_analysis`** — model-vs-market edge when `market_probability` is provided

### Choosing a variant

Start with `variant0_neutral_baseline` (the default). Switch to other variants
to inject additional structure into the prompt — for example, `variant3_reasoning_type`
asks the model to identify whether the prediction is based on speculation, an expert
forecast, or a stated plan.

### Providing your own evidence

Pass pre-fetched articles in `news_articles` to use them directly.
Leave the list empty to trigger automatic news retrieval (if the evidence
pipeline is configured on the server).

### Example — binary request

```bash
curl -X POST /predict \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Will oil prices exceed $100 per barrel in 2026?",
    "question_type": "binary",
    "market_platform": "Kalshi",
    "market_probability": 0.31
  }'
```

### Example — multiple choice

```bash
curl -X POST /predict \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Who will win the 2026 Formula 1 drivers championship?",
    "question_type": "multiple_choice",
    "options": ["Max Verstappen", "Lando Norris", "Charles Leclerc", "Lewis Hamilton", "Other"],
    "attach_evidence": false
  }'
```

### Example — numeric forecast with context

```bash
curl -X POST /predict \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What will US CPI inflation be in December 2026?",
    "question_type": "numeric",
    "resolution_criteria": "Use the year-over-year CPI-U inflation rate for December 2026.",
    "categories": ["Economics", "United States"],
    "variant": "variant5_key_conditions"
  }'
```

## Query parameters

- `kb_user_id` string, nullable

## Request body

- PredictRequest: Input payload for a single forecasting prediction.
  - `question` string, required: The forecasting question to evaluate. It should ask about a future or otherwise resolvable event, option, quantity, or date.
  - `description` string: Extended background context that clarifies what the question is asking.
  - `resolution_criteria` string: Full venue conditions and measurement source used to resolve the forecast.
  - `categories` string[]: Topic tags (e.g. `['Economics', 'United States']`).
  - `news_articles` NewsArticle[]: Pre-fetched venue or caller news articles to preserve as evidence. When `attach_evidence` is true, fresh retrieved news is merged with them.
    - `title` string, nullable: Article headline.
    - `summary` string, nullable: Short human-written summary.
    - `summary_llm` string, nullable: LLM-generated summary.
    - `text` string, nullable: Full article body text.
    - `source` string, nullable: Publisher name (e.g. Reuters).
    - `credibility` object, nullable: Credibility score breakdown.
    - `frs` object, nullable: Future-Resolution Statement metadata.
    - `url` string, nullable: Canonical article URL.
    - `authors` unknown
    - `publish_date` string, nullable: ISO 8601 publish timestamp.
    - `keywords` unknown
    - `relevance_score` number, nullable: Cosine similarity to the question (0–1).
    - `search_query` string, nullable: Query used to retrieve this article.
  - `variant` string: Prompt variant that controls the reasoning instruction style. See the variant table in the Overview section.
  - `attach_evidence` boolean: If `true`, fetch live evidence and merge it with any supplied articles.
  - `evidence_top_k` integer: Maximum number of evidence articles to retrieve (1–100).
  - `evidence_detail` string: Evidence detail level in the model prompt. Use `summary` for scheduled multi-model runs to keep prompts bounded; default `full` preserves the interactive API behaviour.
  - `created_time` string, nullable: ISO 8601 question creation time.
  - `publish_time` string, nullable: ISO 8601 question publish time.
  - `resolve_time` string, nullable: ISO 8601 resolution deadline.
  - `days_open` integer, nullable: Days the question has been open.
  - `history` object[]: Prior conversation turns for multi-turn context, oldest first. Each item is `{"role": "user"|"assistant", "content": "..."}`.
  - `conversation_steer` string: Optional per-conversation steering instruction for tone, emphasis, or analytical stance. It cannot override safety rules or response contracts.
  - `question_type` string, nullable: Question type: `binary`, `multiple_choice`, `numeric`, or `date`. Set this explicitly for API clients; auto-detected from the question when omitted.
  - `options` string[]: Candidate answers for `multiple_choice` questions (optional; the model can infer them).
  - `market_platform` string, nullable: Prediction market venue, e.g. `Polymarket`, `Kalshi`, `Manifold`, or `Metaculus`.
  - `market_url` string, nullable: URL for the prediction market being analyzed. Must start with `http://` or `https://`.
  - `market_outcome` string, nullable: Outcome whose market-implied probability is provided. Defaults to `Yes` for binary markets; set this to `No` or to a multiple-choice option label when needed.
  - `market_ident` string, nullable: Venue market id (Polymarket slug / Kalshi ticker). Lets Foresea fetch live odds when `market_probability` is omitted.
  - `market_probability` number, nullable: Current market-implied probability for `market_outcome`. Use 0-1, or pass a percentage from 0-100 and Foresea will normalize it. When omitted but the market is identifiable (`market_url` or `market_platform`+`market_ident`), Foresea fetches the current live odds.
  - `market_volume` number, nullable: 24-hour trading volume in USD. Populated automatically from live odds when the market is identifiable.
  - `market_liquidity` number, nullable: Total open interest / liquidity in USD. Populated automatically from live odds.
  - `market_price_change_24h` number, nullable: Price change in the last 24 hours (in probability points, -1..1). Populated automatically from live odds.
  - `market_bid` number, nullable: Current best bid (YES) in probability units (0..1). Kalshi only; Polymarket uses the mid price.
  - `market_ask` number, nullable: Current best ask (YES) in probability units (0..1). Kalshi only.
  - `market_last_trade_price` number, nullable: Last actual trade price (0..1). More reliable than resting bid/ask in thin markets. Populated automatically.
  - `market_price_change_7d` number, nullable: 7-day price change in probability points (-1..1). Reveals slow drift that 24h misses. Populated automatically.
  - `market_resolution_source` string, nullable: Who resolves the market (e.g. UMA oracle, Kalshi team). Affects how much to trust the market price.
  - `market_no_sub_title` string, nullable: What the NO outcome represents (Kalshi). Useful when the question wording is ambiguous.
  - `market_expected_expiration_time` string, nullable: When the venue expects to settle (Kalshi). May differ from trading close date.
  - `market_floor_strike` unknown
  - `market_cap_strike` unknown
  - `market_price_history` object[], nullable: Recent price points for this market, newest first. Each entry: {ts: ISO timestamp, probability: float 0..1, volume?: float, liquidity?: float, bid?: float, ask?: float}. Up to 8 entries. Shown to the model as market-trajectory context so it can detect price and tradability changes that the current price alone would hide.
  - `forecast_history` object[], nullable: Prior Foresea forecast snapshots for the same market, newest first. Used by scheduled re-forecasts so repeat forecasts are stateful updates, not independent stateless calls.
  - `openrouter_api_key` string, nullable: User-supplied OpenRouter API key. When set, this request is routed through OpenRouter using `openrouter_model` instead of the server's default provider.
  - `openrouter_model` string, nullable: OpenRouter model ID (e.g. `openai/gpt-4o`, `anthropic/claude-3.5-sonnet`).
  - `model` string, nullable: Optional alternate server-hosted model to forecast with, from the SCADS allowlist (for example `gpt-oss-120b`, `scads-alias-reasoning`, `kimi-k2.7-code`). Uses the server's own key — no BYOK needed. Powers the multi-model paper-trading comparison.
  - `provider_base_url` string, nullable: Optional OpenAI-compatible chat-completions endpoint (e.g. `https://api.openai.com/v1/chat/completions`). When set with `openrouter_api_key` + `openrouter_model`, the request goes to your own endpoint instead of OpenRouter. Must be public HTTPS.
  - `chat_mode` boolean: When `true`, skips the forecast output template entirely. The model responds in plain natural language with no structured JSON.
  - `effort_tier` 'simple' | 'standard' | 'deep', nullable: How much reasoning effort the model call uses, when the provider supports it (best-effort; unsupported providers ignore it). Set explicitly to override; left unset, no reasoning-effort hint is sent.
  - `max_tokens` integer, nullable: Optional per-request generation cap. The server still clamps this to its configured model limit.
  - `ollama_base_url` string, nullable: Base URL of an Ollama instance, e.g. `http://localhost:11434`. No API key required. Cloud-metadata hosts are blocked; for foresea.ink the instance must be reachable from the server.

## Response `200`

Prediction returned successfully.

- PredictResponse: Prediction result for a single forecasting question.
  - `question_type` string: Detected type: `binary`, `multiple_choice`, `numeric`, or `date`.
  - `predicted_answer` string, nullable: Headline answer: Yes/No, the top option, or the median estimate.
  - `confidence` number, nullable: Confidence in the headline answer (binary/MC). Null for numeric.
  - `model_probability` number, nullable: Explicit model probability for conversational forecasts, when one was provided.
  - `options` OptionProb[]: Per-option probabilities for `multiple_choice`.
    - `label` string, required: The option text.
    - `probability` number, required: Probability assigned to this option (0–1).
  - `range_forecast` RangeForecast: A numeric or date estimate expressed as percentile bounds.
    - `p10` string, nullable: 10th-percentile (low) estimate.
    - `p50` string, nullable: 50th-percentile (median) estimate.
    - `p90` string, nullable: 90th-percentile (high) estimate.
    - `unit` string, nullable: Unit of the estimate, e.g. 'USD', '%', 'people'.
  - `rationale` string, nullable: 2–4 sentence explanation of the prediction.
  - `model_rationale` string, nullable: Raw rationale as returned by the model (may differ from `rationale` after post-processing).
  - `variant` string, required: Prompt variant used for this prediction.
  - `model_key` string, required: Model identifier (e.g. `gpt-oss-120b`).
  - `served_model_name` string, nullable: Exact upstream model name that served the response, if reported by the provider.
  - `evidence_sources` EvidenceSource[]: Deduplicated citations used as evidence.
    - `source` string, required: Publisher name.
    - `title` string, nullable: Article headline.
    - `url` string, nullable: Article URL.
    - `publish_date` string, nullable: ISO 8601 publish date.
    - `relevance_score` number, nullable: Relevance to the question (0–1).
  - `evidence_articles` NewsArticle[]: Full evidence articles passed to the model.
    - `title` string, nullable: Article headline.
    - `summary` string, nullable: Short human-written summary.
    - `summary_llm` string, nullable: LLM-generated summary.
    - `text` string, nullable: Full article body text.
    - `source` string, nullable: Publisher name (e.g. Reuters).
    - `credibility` object, nullable: Credibility score breakdown.
    - `frs` object, nullable: Future-Resolution Statement metadata.
    - `url` string, nullable: Canonical article URL.
    - `authors` unknown
    - `publish_date` string, nullable: ISO 8601 publish timestamp.
    - `keywords` unknown
    - `relevance_score` number, nullable: Cosine similarity to the question (0–1).
    - `search_query` string, nullable: Query used to retrieve this article.
  - `evidence_error` string, nullable: Non-null if evidence retrieval failed (prediction still returned).
  - `market_analysis` MarketAnalysis: Deterministic comparison between Foresea's forecast and a market price.
    - `platform` string, nullable: Prediction market venue supplied by the caller.
    - `market_url` string, nullable: Prediction market URL supplied by the caller.
    - `outcome` string, required: Outcome being compared against the market price.
    - `market_probability` number, required: Market-implied probability for the outcome.
    - `model_probability` number, nullable: Foresea probability for the same outcome (recalibrated from the live track record when warranted).
    - `model_probability_raw` number, nullable: Raw model probability before live calibration (only set when calibration was applied).
    - `edge` number, nullable: Model probability minus market probability.
    - `stance` string, required: `model_above_market`, `model_below_market`, `in_line`, or `not_comparable`.
    - `summary` string, required: Short human-readable market comparison.
  - `complexity` string, nullable: Model's own self-reported difficulty for this question: `low` or `high`.
  - `bull_factors` object[], nullable: Decomposed factors favoring the YES / upside outcome.
  - `bear_factors` object[], nullable: Decomposed counter-factors favoring the NO / downside outcome.
  - `key_catalysts` object[], nullable: Key upcoming events/dates that could trigger thesis revision.

## Other responses

- `400`: Invalid request — unknown variant or malformed input.
- `401`: Missing or invalid `X-API-Key` header (only when API key is configured).
- `422`: Validation Error
- `429`: Rate limit exceeded. Retry after 60 seconds.
- `503`: Server not yet initialised — LLM provider not loaded.

---

[API](https://skmtc.dev/foresea/apis/foresea-intelligence-api.md) · [All operations](https://skmtc.dev/foresea/apis/foresea-intelligence-api/llms.txt) · [OpenAPI document](https://skmtc.dev/foresea/apis/foresea-intelligence-api/revisions/b03e49f4385d?raw)
