# Quickstart

Forecasting API quickstart.

Lightning Rod's **Foresight** models return calibrated probability forecasts for any forward-looking question through an OpenAI-compatible API.

### Your first prediction

To get started, [get an API key](https://dashboard.lightningrod.ai/sign-up?redirect=/api) in our dashboard and configure the `api_key` and `base_url` of any [OpenAI API client](https://developers.openai.com/api/docs/libraries) or query [our REST API](https://docs.lightningrod.ai/api-reference) directly.

> **Building an agent?** Get an API key and credits with no signup or dashboard by paying a top-up over MPP (from $1) — see [Agentic Payments](/forecasting/agentic-payments).

Minimal example code using Python:

```python
from openai import OpenAI

client = OpenAI(
    api_key="your-api-key",
    base_url="https://api.lightningrod.ai/v1/openai",
)

response = client.chat.completions.create(
    model="foresight-v4",
    messages=[
        {"role": "user", "content": "Will any company operate a commercial AI data center in space before January 1, 2028?"},
    ],
)
print(response.choices[0].message.content)
```

### Available Models

| Model        | Model ID       | Description                 |
| ------------ | -------------- | --------------------------- |
| Foresight v4 | `foresight-v4` | Latest forecasting model.   |
| Foresight v3 | `foresight-v3` | Previous forecasting model. |

### Structured Prediction

The unstructured result is useful when the response message consumer is a human or an LLM, but for programmatic use you'll probably want a structured prediction response.

We offer a custom `answer_type` extension parameter to achieve exactly that. We recommend using our [SDK](/forecasting/sdk) to automatically parse the responses, but if you want to use a standard OpenAI client please refer to [our answer format guide](/forecasting/openai).

### Prediction Context

By default, none of the models have access to external sources - they are limited by the context they were trained on.

To achieve accurate and useful prediction results, you should always provide relevant context alongside your question. There are currently two ways of doing that:

1. provide your own custom-aggregated context (this is the "secret sauce" that can give you an edge)
2. use our built-in "research mode" to automatically gather relevant context from trusted sources like Perplexity or Google News

See how you can configure research mode using [OpenAI clients](/forecasting/openai) or our [Python SDK](/forecasting/sdk).

### Custom Models

Need forecasting models tailored to your domain? Use the [enterprise platform](/platform-enterprise/overview) to generate datasets, fine-tune models, and evaluate performance.

[Book a call](https://calendly.com/d/ctq4-7gd-nyq/lightning-rod-demo) to talk through your use case.

### Next steps

* [OpenAI](/forecasting/openai) - how to effectively use our OpenAI API
* [SDK](/forecasting/sdk) - Python wrapper on top of the OpenAI API for ease of use
* [Recipes](/forecasting/recipes) — writing good forecasting prompts
* [Enterprise Platform](/platform-enterprise/overview) — generate datasets and fine-tune your own forecasting models


# OpenAI API

Use Foresight through any OpenAI-compatible client.

## Minimal example

```python
from openai import OpenAI

client = OpenAI(
    api_key="your-api-key",
    base_url="https://api.lightningrod.ai/v1/openai",
)

response = client.chat.completions.create(
    model="foresight-v4",
    messages=[
        {"role": "user", "content": "Will the Fed cut interest rates in 2026?"},
    ],
)

message = response.choices[0].message
print(message.content)
```

A few useful response fields:

* `response.choices[0].message.content` — model response, including `<answer></answer>` tags when `answer_type` is set.
* `response.choices[0].message.thinking` — reasoning tokens
* `response.choices[0].message.annotations` — citations, when research runs.
* `response.usage` — cost metadata.

See the [REST API reference](https://docs.lightningrod.ai/api-reference) for more details.

## Answer formats

When `answer_type` is set, `message.content` includes machine-readable tags.

```python
response = client.chat.completions.create(
    model="foresight-v4",
    messages=[
        {"role": "user", "content": "Will the Fed cut interest rates in 2026?"},
    ],
    extra_body={"answer_type": "auto"},
)

print(response.choices[0].message.content) # ... <answer>0.62</answer>
```

| `answer_type`       | Raw response shape                                           |
| ------------------- | ------------------------------------------------------------ |
| `"binary"`          | `<answer>0.62</answer>`                                      |
| `"continuous"`      | `<answer>{"mean": 42.5, "standard_deviation": 5.2}</answer>` |
| `"multiple_choice"` | `<answer>{"A": 0.55, "B": 0.45}</answer>`                    |
| `"free_response"`   | `<answer>...</answer>`                                       |
| `"auto"`            | Server-selected structured answer raw response shape         |

See our [API reference](https://docs.lightningrod.ai/api-reference) for more response examples.

## Research

Pass `research` in `extra_body` to gather live web context before forecasting. Set it to `true` to query all default sources, or pass a `sources` array to limit which providers run:

```python
response = client.chat.completions.create(
    model="foresight-v4",
    messages=[
        {"role": "user", "content": "Will the Fed cut interest rates in 2026?"},
    ],
    extra_body={
        "research": {"sources": ["perplexity", "google_news"]},
        "answer_type": "binary",
    },
)
```

See our [API reference](https://docs.lightningrod.ai/api-reference) for an up-to-date list of supported sources.

## Reasoning effort

```python
response = client.chat.completions.create(
    model="foresight-v4",
    messages=[
        {"role": "user", "content": "Will the Fed cut interest rates in 2026?"},
    ],
    reasoning_effort="low",
)

print(response.choices[0].message.content)
print(response.usage.total_tokens)
```

Recommendation: use `low` reasoning effort if cost and latency outweigh marginal improvements in accuracy.

See [Recipes](/forecasting/recipes) for more forecasting guidelines.


# Python SDK

Structured predictions with lr.predict()

## Minimal example

```python
import lightningrod as lr

client = lr.LightningRod(api_key="your-api-key")

result = client.predict("Will the Fed cut interest rates in 2026?", model="foresight-v4")

print(result.content)
```

Response fields:

| Field             | Type                             | Description                                                     |
| ----------------- | -------------------------------- | --------------------------------------------------------------- |
| `content`         | `str`                            | Full response, including any `<answer>` tags.                   |
| `thinking`        | `str \| None`                    | Reasoning, when returned.                                       |
| `sources`         | `list[Source]`                   | URL citations from research. Each source has `url` and `title`. |
| `usage`           | `Usage`                          | Token counts and cost fields.                                   |
| `model`           | `str`                            | Model that served the request.                                  |
| `id`              | `str`                            | Response ID.                                                    |
| `binary`          | `BinaryPrediction \| None`       | Populated when `answer_type="binary"`.                          |
| `continuous`      | `ContinuousPrediction \| None`   | Populated when `answer_type="continuous"`.                      |
| `multiple_choice` | `MultiChoicePrediction \| None`  | Populated when `answer_type="multiple_choice"`.                 |
| `free_response`   | `FreeResponsePrediction \| None` | Populated when `answer_type="free_response"`.                   |

## Answer formats

When `answer_type` is set, `predict()` parses the response tags into typed fields on `PredictionResult`.

```python
import lightningrod as lr

client = lr.LightningRod(api_key="your-api-key")

result = client.predict(
    "Will the Fed cut interest rates in 2026?",
    answer_type="binary",
)

print(result.binary.probability)
print(result.content)
```

| `answer_type`       | `PredictionResult` field                                                 |
| ------------------- | ------------------------------------------------------------------------ |
| `"binary"`          | `result.binary.probability`                                              |
| `"continuous"`      | `result.continuous.mean`, `result.continuous.standard_deviation`         |
| `"multiple_choice"` | `result.multiple_choice.probabilities`                                   |
| `"free_response"`   | `result.free_response.text`                                              |
| `"auto"`            | One of the above fields, inferred from the server-classified answer type |

`answer_type="auto"` classifies the question server-side and populates the matching prediction field. `result.usage.classification_cost_usd` is set when classification runs (cost is negligible).

See our [API reference](https://docs.lightningrod.ai/api-reference) for more response examples.

## Research

Pass `research=True` to query all default sources, or pass a list to restrict providers:

```python
result = client.predict(
    "Will the Fed cut interest rates in 2026?",
    research=["perplexity", "google_news"],
)

for source in result.sources:
    print(source.title, source.url)
print(result.usage.research_cost_usd)
```

See our [API reference](https://docs.lightningrod.ai/api-reference) for an up-to-date list of supported sources.

## Reasoning effort

```python
result = client.predict(
    "Will the Fed cut interest rates in 2026?",
    reasoning_effort="low",
)

print(result.content)
print(result.usage.total_tokens)
```

Recommendation: use `low` reasoning effort if cost and latency outweigh marginal improvements in accuracy.

See [Recipes](/forecasting/recipes) for more forecasting guidelines.


# Recipes

Guidelines on how to effectively forecast using our API.

## Writing good questions

Foresight works best when the question has clear resolution criteria: the event or value, the threshold, and the deadline.

* **Name the event and deadline.** *"Will the Federal Reserve lower the target federal funds rate by at least 25 bps by December 31, 2026?"* is clearer than *"Will the Fed cut soon?"*
* **Use measurable thresholds.** *"Will the S\&P 500 close above 7,000 on December 31, 2026?"* is clearer than *"Will stocks do well?"*
* **Ask one thing and choose the right answer type.** Use `binary` for yes/no, `continuous` for a number, and `multiple_choice` for a fixed set of outcomes.

## Improving accuracy

* **Gather and provide relevant context.**
* **Turn on `research`** for questions that depend on recent events—it lets the model gather live evidence and attach sources you can inspect via `result.sources`.
* **Use ensemble predictions.** Send the same request multiple times and use the median response.
* **Fine-tune on your domain (enterprise).** If you want to achieve better accuracy and cost on your domain, leveraging your internal data, see [our enteprise platform](/platform-enterprise/overview).

## Optimizing costs

* **Curate your context.** Implement custom context aggregation logic, tuned for your forecasting question.
* **Use low reasoning.** This will significantly reduce token usage, while still maintaining accuracy edge over the current frontier models. Note: avoid setting low max\_tokens as this can result in the response being truncated during reasoning and no final prediction captured. Use "low" reasoning effort instead.


# Agentic Payments (MPP)

Get an API key and credits with no human, no signup, no dashboard — pay per top-up with MPP.

Agents can obtain an API key and credits without a human — no signup, no dashboard. Pay a credit top-up over [MPP](https://datatracker.ietf.org/doc/draft-ietf-httpauth-payment/) (`Machine Payments Protocol`) and get an API key back, then use it against the standard [OpenAI-compatible API](/forecasting/openai).

The amount is **your choice**: it defaults to **$5.00**, and you can pay as little as **$1.00** by passing `amount_cents` in the request body (e.g. `{"amount_cents": 100}`). The challenge call and the paid retry must quote the **same** amount — MPP binds the credential to it.

The top-up endpoint offers **two payment rails** — pay whichever your wallet supports:

* `method="tempo"` — on-chain USDC on [Tempo](https://tempo.xyz) (chain id `4217`)
* `method="stripe"` — Stripe card / Link Shared Payment Token

## Fastest path (Tempo wallet)

If you have a Tempo wallet (`tempo wallet login`):

```bash
tempo request -X POST https://api.lightningrod.ai/v1/mpp/topup
```

This pays the default $5.00 USDC-on-Tempo challenge and returns credits + an API key automatically. Pass `-d '{"amount_cents": 100}'` to top up a different amount (min $1.00). Any other MPP-aware client (`mppx`, `link-cli`) works the same way — point it at the same URL.

## Manual flow (raw HTTP, any MPP client)

### 1. Request a challenge (no payment)

```bash
curl -s -X POST https://api.lightningrod.ai/v1/mpp/topup
```

Returns `402` with **two** `WWW-Authenticate: Payment` header instances — pay whichever rail you can:

```
WWW-Authenticate: Payment id="...", realm="api.lightningrod.ai", method="stripe", intent="charge", request="<base64url>", expires="2026-01-01T00:00:00Z", description="Lightning Rod Labs credit top-up ($5.00)"
WWW-Authenticate: Payment id="...", realm="api.lightningrod.ai", method="tempo", intent="charge", request="<base64url>", expires="2026-01-01T00:00:00Z", description="Lightning Rod Labs credit top-up ($5.00)"
```

`request` is base64url-encoded JSON per the MPP spec (`draft-ietf-httpauth-payment`); decode it for the exact recipient/amount, or read the machine-readable offers (amount, currency, decimals) in `x-payment-info` at [`https://api.lightningrod.ai/openapi.json`](https://api.lightningrod.ai/openapi.json).

### 2. Pay and retry with the credential

Your wallet/CLI builds and signs the credential for you. Retry with `Authorization: Payment <credential>`:

```bash
curl -s -X POST https://api.lightningrod.ai/v1/mpp/topup \
  -H 'Authorization: Payment <credential-from-step-2>'
```

Returns `200`:

```json
{"organization_id": "org_mpp_...", "credited_cents": 500, "api_key": "sk_...", "api_key_id": "key_..."}
```

`api_key` is minted once — **save it.**

### 3. Use the key, and refill when credits run out

Use it as `Authorization: Bearer sk_...` on `POST /v1/openai/chat/completions`:

```bash
curl -s https://api.lightningrod.ai/v1/openai/chat/completions \
  -H 'Authorization: Bearer sk_...' \
  -H 'Content-Type: application/json' \
  -d '{"model": "foresight-v4", "messages": [{"role": "user", "content": "Will the Fed cut interest rates in 2026?"}]}'
```

When credits run out, that endpoint returns `402`. Call `/mpp/topup` again with the same key in `X-API-Key` to refill **without minting a new org**:

```bash
tempo request -X POST https://api.lightningrod.ai/v1/mpp/topup \
  -H 'X-API-Key: sk_...'
```

## See also

* [OpenAI API](/forecasting/openai) — everything you can do once you have a key
* [API reference: Agentic Payments](https://docs.lightningrod.ai/api-reference/agentic-payments) — the `/mpp/topup` schema


# Overview

Generate labeled forecasting datasets from your sources and fine-tune custom models.

Use the Lightning Rod platform when you need a forecasting model tailored to your domain or data.

We work with teams to:

* **Generate** labeled forecasting datasets from your own sources—news, documents, and custom data—through a configurable pipeline, with no manual question writing or labeling.
* **Fine-tune** specialized models on those datasets.
* **Evaluate** performance against held-out test sets.
* **Serve** the resulting models through an OpenAI-compatible API.

[**Book a call →**](https://calendly.com/d/ctq4-7gd-nyq/lightning-rod-demo) to talk through your use case.


# Open AI API

## Chat Completions

> OpenAI-compatible chat/completions endpoint for Lightning Rod's \*\*Foresight\*\* forecasting models.\
> \
> The default limit is \*\*120 requests per minute\*\* per organization (sliding window). Exceeded requests receive a \`429\`; check \`Retry-After\` and \`X-RateLimit-\*\` headers to pace retries. Contact \[<support@lightningrod.ai>]\(mailto:<support@lightningrod.ai>) for higher limits.

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"servers":[{"url":"https://api.lightningrod.ai"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Lightning Rod API key (`sk_…`) sent as a Bearer token. Obtain one via `POST /v1/mpp/topup` (agents) or the dashboard (humans)."}},"schemas":{"ChatCompletionRequest":{"properties":{"model":{"type":"string","title":"Model","description":"ID of the model to use"},"messages":{"items":{"$ref":"#/components/schemas/ChatMessage"},"type":"array","title":"Messages","description":"A list of messages comprising the conversation so far"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Sampling temperature between 0 and 2","default":0.6},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens","description":"Maximum number of tokens to generate"},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P","description":"Nucleus sampling parameter"},"top_k":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Top K","description":"Number of top tokens to consider"},"min_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min P","description":"Minimum probability for a token to be considered"},"reasoning_effort":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reasoning Effort","description":"Lightning Rod extension. Reasoning budget the model spends before answering: `low`, `medium`, or `high`. Higher effort improves accuracy on harder questions at additional token cost. With raw OpenAI clients pass via `extra_body`."},"stream":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Stream","description":"Whether to stream back partial progress","default":false},"n":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"N","description":"Number of chat completion choices to generate","default":1},"stop":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stop","description":"Up to 4 sequences where the API will stop generating"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"Deterministic sampling seed"},"research":{"anyOf":[{"type":"boolean"},{"$ref":"#/components/schemas/ResearchOptions"},{"type":"null"}],"title":"Research","description":"Lightning Rod extension. Opt-in web research before forecasting. Pass `true` to query all default sources, or a `ResearchOptions` object to select sources. Each source is billed as a separate research event; when research runs, its cost is reported in `usage`. With raw OpenAI clients pass via `extra_body`."},"answer_type":{"anyOf":[{"$ref":"#/components/schemas/AnswerTypeEnum"},{"type":"string","const":"auto"},{"type":"null"}],"title":"Answer Type","description":"Lightning Rod extension that injects output-format guidance and appends a structured answer between `<answer></answer>` tags in the response content. One of `binary`, `multiple_choice`, `continuous`, `free_response`, or `auto`. Raw response shapes: `binary` -> `<answer>0.62</answer>` (probability between 0 and 1); `continuous` -> `<answer>{\"mean\": 42.5, \"standard_deviation\": 5.2}</answer>`; `multiple_choice` -> `<answer>{\"A\": 0.55, \"B\": 0.45}</answer>`; `free_response` -> `<answer>...</answer>`. `auto` classifies the user question server-side first, then returns one of the above. Omit for prose only. With raw OpenAI clients pass via `extra_body`."}},"type":"object","required":["model","messages"],"title":"ChatCompletionRequest"},"ChatMessage":{"properties":{"role":{"type":"string","title":"Role","description":"The role of the message author (system, user, or assistant)"},"content":{"type":"string","title":"Content","description":"The content of the message"}},"type":"object","required":["role","content"],"title":"ChatMessage"},"ResearchOptions":{"properties":{"sources":{"items":{"type":"string","enum":["perplexity","google_news"]},"type":"array","title":"Sources","description":"Which research source providers to use. Each provider is billed separately."}},"type":"object","title":"ResearchOptions","description":"Opt-in research enrichment for forecasting requests.\n\nWhen set, the API fetches web-grounded context from the requested sources\nand injects it into the prompt before calling the model. Each successful\nsource produces a billable RESEARCH event."},"AnswerTypeEnum":{"type":"string","enum":["BINARY","MULTIPLE_CHOICE","CONTINUOUS","CONTINUOUS_VALUE_ONLY","FREE_RESPONSE"],"title":"AnswerTypeEnum"},"ChatCompletionResponse":{"properties":{"id":{"type":"string","title":"Id","description":"A unique identifier for the chat completion"},"object":{"type":"string","const":"chat.completion","title":"Object","description":"The object type","default":"chat.completion"},"created":{"type":"integer","title":"Created","description":"Unix timestamp of when the completion was created"},"model":{"type":"string","title":"Model","description":"The model used for the chat completion"},"choices":{"items":{"$ref":"#/components/schemas/Choice"},"type":"array","title":"Choices","description":"A list of chat completion choices"},"usage":{"anyOf":[{"$ref":"#/components/schemas/Usage"},{"type":"null"}],"description":"Usage statistics for the completion request"}},"type":"object","required":["id","created","model","choices"],"title":"ChatCompletionResponse"},"Choice":{"properties":{"index":{"type":"integer","title":"Index","description":"The index of this choice"},"message":{"$ref":"#/components/schemas/ResponseMessage","description":"The message generated by the model"},"finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finish Reason","description":"The reason the model stopped generating tokens"}},"type":"object","required":["index","message"],"title":"Choice"},"ResponseMessage":{"properties":{"role":{"type":"string","title":"Role","description":"The role of the message author"},"content":{"type":"string","title":"Content","description":"The model's full response. When `answer_type` was set on the request, a machine-readable answer is embedded between `<answer></answer>` tags at the end (e.g. `<answer>0.62</answer>` for a binary probability). See the request's `answer_type` field for the per-type shapes."},"thinking":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thinking","description":"The model's reasoning/thinking chain, when returned by the model."},"annotations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/UrlCitationAnnotation"}},{"type":"null"}],"title":"Annotations","description":"Source citations from web research, present only when `research` ran. Each entry is a `url_citation` referencing a source the model used."}},"type":"object","required":["role","content"],"title":"ResponseMessage"},"UrlCitationAnnotation":{"properties":{"type":{"type":"string","const":"url_citation","title":"Type","description":"The annotation type. Always `url_citation`.","default":"url_citation"},"url_citation":{"$ref":"#/components/schemas/UrlCitation","description":"The cited source."}},"type":"object","required":["type","url_citation"],"title":"UrlCitationAnnotation"},"UrlCitation":{"properties":{"url":{"type":"string","title":"Url","description":"URL of the cited source."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Title of the cited source, when available."}},"type":"object","required":["url"],"title":"UrlCitation"},"Usage":{"properties":{"prompt_tokens":{"type":"integer","title":"Prompt Tokens","description":"Number of tokens in the prompt"},"completion_tokens":{"type":"integer","title":"Completion Tokens","description":"Number of tokens in the completion"},"total_tokens":{"type":"integer","title":"Total Tokens","description":"Total number of tokens used"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd","description":"Lightning Rod total cost of the call in USD, summing inference and any research/classification costs."},"inference_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inference Cost Usd","description":"Lightning Rod cost in USD attributable to model inference."},"research_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Research Cost Usd","description":"Lightning Rod cost in USD for web research, when `research` was enabled. Each source is billed as a separate RESEARCH event."},"classification_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Classification Cost Usd","description":"Lightning Rod cost in USD for question classification, when `answer_type` was `auto`."}},"type":"object","required":["prompt_tokens","completion_tokens","total_tokens"],"title":"Usage","description":"Token counts plus Lightning Rod cost fields. The `*_cost_usd` fields are present when applicable (research and classification costs only appear when those steps ran)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"headers":{"X-RateLimit-Limit":{"description":"Default request limit per minute for this organization (120 requests per minute). Contact `support@lightningrod.ai` for higher limits.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Number of requests remaining in the current 60-second window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the current rate-limit window resets.","schema":{"type":"integer"}}},"responses":{"TooManyRequests":{"description":"Rate limit exceeded. Retry after the number of seconds in `Retry-After`.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}}}},"paths":{"/v1/openai/chat/completions":{"post":{"tags":["OpenAI API"],"summary":"Chat Completions","description":"OpenAI-compatible chat/completions endpoint for Lightning Rod's **Foresight** forecasting models.\n\nThe default limit is **120 requests per minute** per organization (sliding window). Exceeded requests receive a `429`; check `Retry-After` and `X-RateLimit-*` headers to pace retries. Contact [support@lightningrod.ai](mailto:support@lightningrod.ai) for higher limits.","operationId":"chat_completions_openai_chat_completions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}}}}
```

## Completions

> OpenAI-compatible text completion endpoint for Lightning Rod's \*\*Foresight\*\* forecasting models.\
> \
> Prefer the \*\*chat/completions\*\* endpoint for multi-turn conversations and framework compatibility.\
> \
> The default limit is \*\*120 requests per minute\*\* per organization (sliding window). Exceeded requests receive a \`429\`; check \`Retry-After\` and \`X-RateLimit-\*\` headers to pace retries. Contact \[<support@lightningrod.ai>]\(mailto:<support@lightningrod.ai>) for higher limits.

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"servers":[{"url":"https://api.lightningrod.ai"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Lightning Rod API key (`sk_…`) sent as a Bearer token. Obtain one via `POST /v1/mpp/topup` (agents) or the dashboard (humans)."}},"schemas":{"CompletionRequest":{"properties":{"model":{"type":"string","title":"Model","description":"ID of the model to use"},"prompt":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Prompt","description":"The prompt(s) to generate completions for"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Sampling temperature between 0 and 2","default":0.6},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens","description":"Maximum number of tokens to generate"},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P","description":"Nucleus sampling parameter"},"top_k":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Top K","description":"Number of top tokens to consider"},"min_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min P","description":"Minimum probability for a token to be considered"},"reasoning_effort":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reasoning Effort","description":"Lightning Rod extension. Reasoning budget the model spends before answering: `low`, `medium`, or `high`. Higher effort improves accuracy on harder questions at additional token cost. With raw OpenAI clients pass via `extra_body`."},"stream":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Stream","description":"Whether to stream back partial progress","default":false},"n":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"N","description":"Number of completions to generate","default":1},"stop":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stop","description":"Up to 4 sequences where the API will stop generating"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"Deterministic sampling seed"},"research":{"anyOf":[{"type":"boolean"},{"$ref":"#/components/schemas/ResearchOptions"},{"type":"null"}],"title":"Research","description":"Lightning Rod extension. Opt-in web research before forecasting. Pass `true` to query all default sources, or a `ResearchOptions` object to select sources. Available sources: `perplexity` (Perplexity web search), `google_news` (recent Google News articles). Each source runs as its own query and is billed as a separate RESEARCH event; when research runs, its cost is reported in `usage`. With raw OpenAI clients pass via `extra_body`."},"answer_type":{"anyOf":[{"$ref":"#/components/schemas/AnswerTypeEnum"},{"type":"string","const":"auto"},{"type":"null"}],"title":"Answer Type","description":"Lightning Rod extension that injects output-format guidance and appends a structured answer between `<answer></answer>` tags in the response text. One of `binary`, `multiple_choice`, `continuous`, `free_response`, or `auto`. Raw response shapes: `binary` -> `<answer>0.62</answer>` (probability between 0 and 1); `continuous` -> `<answer>{\"mean\": 42.5, \"standard_deviation\": 5.2}</answer>`; `multiple_choice` -> `<options>{\"A\": \"...\", \"B\": \"...\"}</options>` followed by `<answer>{\"A\": 0.55, \"B\": 0.45}</answer>`; `free_response` -> `<answer>...</answer>`. `auto` classifies the prompt server-side first, then returns one of the above. Omit for prose only. With raw OpenAI clients pass via `extra_body`."}},"type":"object","required":["model","prompt"],"title":"CompletionRequest"},"ResearchOptions":{"properties":{"sources":{"items":{"type":"string","enum":["perplexity","google_news"]},"type":"array","title":"Sources","description":"Which research source providers to use. Each provider is billed separately."}},"type":"object","title":"ResearchOptions","description":"Opt-in research enrichment for forecasting requests.\n\nWhen set, the API fetches web-grounded context from the requested sources\nand injects it into the prompt before calling the model. Each successful\nsource produces a billable RESEARCH event."},"AnswerTypeEnum":{"type":"string","enum":["BINARY","MULTIPLE_CHOICE","CONTINUOUS","CONTINUOUS_VALUE_ONLY","FREE_RESPONSE"],"title":"AnswerTypeEnum"},"CompletionResponse":{"properties":{"id":{"type":"string","title":"Id","description":"A unique identifier for the completion"},"object":{"type":"string","const":"text_completion","title":"Object","description":"The object type","default":"text_completion"},"created":{"type":"integer","title":"Created","description":"Unix timestamp of when the completion was created"},"model":{"type":"string","title":"Model","description":"The model used for the completion"},"choices":{"items":{"$ref":"#/components/schemas/CompletionChoice"},"type":"array","title":"Choices","description":"A list of completion choices"},"usage":{"anyOf":[{"$ref":"#/components/schemas/Usage"},{"type":"null"}],"description":"Usage statistics for the completion request"}},"type":"object","required":["id","created","model","choices"],"title":"CompletionResponse"},"CompletionChoice":{"properties":{"index":{"type":"integer","title":"Index","description":"The index of this choice"},"text":{"type":"string","title":"Text","description":"The generated text"},"finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finish Reason","description":"The reason the model stopped generating tokens"}},"type":"object","required":["index","text"],"title":"CompletionChoice"},"Usage":{"properties":{"prompt_tokens":{"type":"integer","title":"Prompt Tokens","description":"Number of tokens in the prompt"},"completion_tokens":{"type":"integer","title":"Completion Tokens","description":"Number of tokens in the completion"},"total_tokens":{"type":"integer","title":"Total Tokens","description":"Total number of tokens used"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd","description":"Lightning Rod total cost of the call in USD, summing inference and any research/classification costs."},"inference_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inference Cost Usd","description":"Lightning Rod cost in USD attributable to model inference."},"research_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Research Cost Usd","description":"Lightning Rod cost in USD for web research, when `research` was enabled. Each source is billed as a separate RESEARCH event."},"classification_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Classification Cost Usd","description":"Lightning Rod cost in USD for question classification, when `answer_type` was `auto`."}},"type":"object","required":["prompt_tokens","completion_tokens","total_tokens"],"title":"Usage","description":"Token counts plus Lightning Rod cost fields. The `*_cost_usd` fields are present when applicable (research and classification costs only appear when those steps ran)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"headers":{"X-RateLimit-Limit":{"description":"Default request limit per minute for this organization (120 requests per minute). Contact `support@lightningrod.ai` for higher limits.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Number of requests remaining in the current 60-second window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the current rate-limit window resets.","schema":{"type":"integer"}}},"responses":{"TooManyRequests":{"description":"Rate limit exceeded. Retry after the number of seconds in `Retry-After`.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}}}},"paths":{"/v1/openai/completions":{"post":{"tags":["OpenAI API"],"summary":"Completions","description":"OpenAI-compatible text completion endpoint for Lightning Rod's **Foresight** forecasting models.\n\nPrefer the **chat/completions** endpoint for multi-turn conversations and framework compatibility.\n\nThe default limit is **120 requests per minute** per organization (sliding window). Exceeded requests receive a `429`; check `Retry-After` and `X-RateLimit-*` headers to pace retries. Contact [support@lightningrod.ai](mailto:support@lightningrod.ai) for higher limits.","operationId":"completions_openai_completions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}}}}
```

## List Models

> List available models.

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"servers":[{"url":"https://api.lightningrod.ai"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Lightning Rod API key (`sk_…`) sent as a Bearer token. Obtain one via `POST /v1/mpp/topup` (agents) or the dashboard (humans)."}},"schemas":{"ModelListResponse":{"properties":{"object":{"type":"string","const":"list","title":"Object","description":"The object type","default":"list"},"data":{"items":{"$ref":"#/components/schemas/ModelObject"},"type":"array","title":"Data","description":"A list of model objects"}},"type":"object","required":["data"],"title":"ModelListResponse"},"ModelObject":{"properties":{"id":{"type":"string","title":"Id","description":"The model identifier"},"object":{"type":"string","const":"model","title":"Object","description":"The object type","default":"model"},"created":{"type":"integer","title":"Created","description":"Unix timestamp of when the model was created","default":0},"owned_by":{"type":"string","title":"Owned By","description":"The organization that owns the model","default":"lightningrodlabs"},"name":{"type":"string","title":"Name","description":"Display name of the model","default":""},"description":{"type":"string","title":"Description","description":"Description of the model","default":""},"context_length":{"type":"integer","title":"Context Length","description":"Maximum context length in tokens","default":0},"max_completion_tokens":{"type":"integer","title":"Max Completion Tokens","description":"Maximum number of tokens to generate","default":0},"pricing":{"additionalProperties":true,"type":"object","title":"Pricing","description":"Per-token pricing"}},"type":"object","required":["id"],"title":"ModelObject"}}},"paths":{"/v1/openai/models":{"get":{"tags":["OpenAI API"],"summary":"List Models","description":"List available models.","operationId":"list_models_openai_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelListResponse"}}}}}}}}}
```


# Agentic Payments

## Add credits via MPP (Machine Payments Protocol)

> Pay via MPP to add credits and obtain (or refresh) an API key, then call the standard \`/v1/openai/\*\` endpoints with it as a \`Bearer\` token.\
> \
> \*\*Payment rails:\*\* every challenge offers both, as two separate \`WWW-Authenticate\` header instances. Pay whichever one you can and retry with that rail's credential:\
> \
> \- \*\*Stripe\*\* (\`method="stripe"\`): pay with a Stripe card or Link Shared Payment Token. Retry with \`Authorization: Payment \<stripe-credential>\`.\
> \
> \- \*\*Tempo\*\* (\`method="tempo"\`): pay with on-chain USDC on the Tempo network. Retry with \`Authorization: Payment \<tempo-credential>\`.\
> \
> \*\*Amount:\*\* defaults to $5.00; pass \`amount\_cents\` to choose a size (clamped to the credit-purchase limits). Send the \*\*same\*\* \`amount\_cents\` on the paid retry as on the challenge call.\
> \
> \*\*Headers:\*\*\
> \- \`Authorization: Payment \<credential>\` — the MPP payment credential.\
> \- \`X-API-Key: sk\_…\` \*(optional)\* — refill an existing org; omit to mint a new org + key (returned once in the response body).

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"servers":[{"url":"https://api.lightningrod.ai"}],"paths":{"/v1/mpp/topup":{"post":{"tags":["Agentic Payments"],"summary":"Add credits via MPP (Machine Payments Protocol)","description":"Pay via MPP to add credits and obtain (or refresh) an API key, then call the standard `/v1/openai/*` endpoints with it as a `Bearer` token.\n\n**Payment rails:** every challenge offers both, as two separate `WWW-Authenticate` header instances. Pay whichever one you can and retry with that rail's credential:\n\n- **Stripe** (`method=\"stripe\"`): pay with a Stripe card or Link Shared Payment Token. Retry with `Authorization: Payment <stripe-credential>`.\n\n- **Tempo** (`method=\"tempo\"`): pay with on-chain USDC on the Tempo network. Retry with `Authorization: Payment <tempo-credential>`.\n\n**Amount:** defaults to $5.00; pass `amount_cents` to choose a size (clamped to the credit-purchase limits). Send the **same** `amount_cents` on the paid retry as on the challenge call.\n\n**Headers:**\n- `Authorization: Payment <credential>` — the MPP payment credential.\n- `X-API-Key: sk_…` *(optional)* — refill an existing org; omit to mint a new org + key (returned once in the response body).","operationId":"mpp_topup","requestBody":{"content":{"application/json":{"schema":{"type":"object","title":"MppTopupRequest","properties":{"amount_cents":{"type":"integer","title":"Amount Cents","description":"Top-up size in cents. Defaults to 500 ($5.00). Range $1.00–$10,000.00. Must be identical on the challenge call and the paid retry.","default":500,"minimum":100,"maximum":1000000}},"additionalProperties":false}}},"required":false},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MppTopupResponse"}}}},"402":{"description":"Payment required. Two `WWW-Authenticate: Payment` header instances are returned, one per supported rail (`method=\"stripe\"` and `method=\"tempo\"`), each quoting the top-up amount; pay either and retry.","headers":{"WWW-Authenticate":{"description":"MPP Payment challenge (scheme `Payment`). Sent once per each supported payment rail.","schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"MppTopupResponse":{"properties":{"organization_id":{"type":"string","title":"Organization Id"},"credited_cents":{"type":"integer","title":"Credited Cents"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key"},"api_key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key Id"}},"type":"object","required":["organization_id","credited_cents"],"title":"MppTopupResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}
```


# Models

## The AnswerTypeEnum object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"AnswerTypeEnum":{"type":"string","enum":["BINARY","MULTIPLE_CHOICE","CONTINUOUS","CONTINUOUS_VALUE_ONLY","FREE_RESPONSE"],"title":"AnswerTypeEnum"}}}}
```

## The ChatCompletionRequest object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"ChatCompletionRequest":{"properties":{"model":{"type":"string","title":"Model","description":"ID of the model to use"},"messages":{"items":{"$ref":"#/components/schemas/ChatMessage"},"type":"array","title":"Messages","description":"A list of messages comprising the conversation so far"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Sampling temperature between 0 and 2","default":0.6},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens","description":"Maximum number of tokens to generate"},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P","description":"Nucleus sampling parameter"},"top_k":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Top K","description":"Number of top tokens to consider"},"min_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min P","description":"Minimum probability for a token to be considered"},"reasoning_effort":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reasoning Effort","description":"Lightning Rod extension. Reasoning budget the model spends before answering: `low`, `medium`, or `high`. Higher effort improves accuracy on harder questions at additional token cost. With raw OpenAI clients pass via `extra_body`."},"stream":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Stream","description":"Whether to stream back partial progress","default":false},"n":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"N","description":"Number of chat completion choices to generate","default":1},"stop":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stop","description":"Up to 4 sequences where the API will stop generating"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"Deterministic sampling seed"},"research":{"anyOf":[{"type":"boolean"},{"$ref":"#/components/schemas/ResearchOptions"},{"type":"null"}],"title":"Research","description":"Lightning Rod extension. Opt-in web research before forecasting. Pass `true` to query all default sources, or a `ResearchOptions` object to select sources. Each source is billed as a separate research event; when research runs, its cost is reported in `usage`. With raw OpenAI clients pass via `extra_body`."},"answer_type":{"anyOf":[{"$ref":"#/components/schemas/AnswerTypeEnum"},{"type":"string","const":"auto"},{"type":"null"}],"title":"Answer Type","description":"Lightning Rod extension that injects output-format guidance and appends a structured answer between `<answer></answer>` tags in the response content. One of `binary`, `multiple_choice`, `continuous`, `free_response`, or `auto`. Raw response shapes: `binary` -> `<answer>0.62</answer>` (probability between 0 and 1); `continuous` -> `<answer>{\"mean\": 42.5, \"standard_deviation\": 5.2}</answer>`; `multiple_choice` -> `<answer>{\"A\": 0.55, \"B\": 0.45}</answer>`; `free_response` -> `<answer>...</answer>`. `auto` classifies the user question server-side first, then returns one of the above. Omit for prose only. With raw OpenAI clients pass via `extra_body`."}},"type":"object","required":["model","messages"],"title":"ChatCompletionRequest"},"ChatMessage":{"properties":{"role":{"type":"string","title":"Role","description":"The role of the message author (system, user, or assistant)"},"content":{"type":"string","title":"Content","description":"The content of the message"}},"type":"object","required":["role","content"],"title":"ChatMessage"},"ResearchOptions":{"properties":{"sources":{"items":{"type":"string","enum":["perplexity","google_news"]},"type":"array","title":"Sources","description":"Which research source providers to use. Each provider is billed separately."}},"type":"object","title":"ResearchOptions","description":"Opt-in research enrichment for forecasting requests.\n\nWhen set, the API fetches web-grounded context from the requested sources\nand injects it into the prompt before calling the model. Each successful\nsource produces a billable RESEARCH event."},"AnswerTypeEnum":{"type":"string","enum":["BINARY","MULTIPLE_CHOICE","CONTINUOUS","CONTINUOUS_VALUE_ONLY","FREE_RESPONSE"],"title":"AnswerTypeEnum"}}}}
```

## The ChatCompletionResponse object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"ChatCompletionResponse":{"properties":{"id":{"type":"string","title":"Id","description":"A unique identifier for the chat completion"},"object":{"type":"string","const":"chat.completion","title":"Object","description":"The object type","default":"chat.completion"},"created":{"type":"integer","title":"Created","description":"Unix timestamp of when the completion was created"},"model":{"type":"string","title":"Model","description":"The model used for the chat completion"},"choices":{"items":{"$ref":"#/components/schemas/Choice"},"type":"array","title":"Choices","description":"A list of chat completion choices"},"usage":{"anyOf":[{"$ref":"#/components/schemas/Usage"},{"type":"null"}],"description":"Usage statistics for the completion request"}},"type":"object","required":["id","created","model","choices"],"title":"ChatCompletionResponse"},"Choice":{"properties":{"index":{"type":"integer","title":"Index","description":"The index of this choice"},"message":{"$ref":"#/components/schemas/ResponseMessage","description":"The message generated by the model"},"finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finish Reason","description":"The reason the model stopped generating tokens"}},"type":"object","required":["index","message"],"title":"Choice"},"ResponseMessage":{"properties":{"role":{"type":"string","title":"Role","description":"The role of the message author"},"content":{"type":"string","title":"Content","description":"The model's full response. When `answer_type` was set on the request, a machine-readable answer is embedded between `<answer></answer>` tags at the end (e.g. `<answer>0.62</answer>` for a binary probability). See the request's `answer_type` field for the per-type shapes."},"thinking":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thinking","description":"The model's reasoning/thinking chain, when returned by the model."},"annotations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/UrlCitationAnnotation"}},{"type":"null"}],"title":"Annotations","description":"Source citations from web research, present only when `research` ran. Each entry is a `url_citation` referencing a source the model used."}},"type":"object","required":["role","content"],"title":"ResponseMessage"},"UrlCitationAnnotation":{"properties":{"type":{"type":"string","const":"url_citation","title":"Type","description":"The annotation type. Always `url_citation`.","default":"url_citation"},"url_citation":{"$ref":"#/components/schemas/UrlCitation","description":"The cited source."}},"type":"object","required":["type","url_citation"],"title":"UrlCitationAnnotation"},"UrlCitation":{"properties":{"url":{"type":"string","title":"Url","description":"URL of the cited source."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Title of the cited source, when available."}},"type":"object","required":["url"],"title":"UrlCitation"},"Usage":{"properties":{"prompt_tokens":{"type":"integer","title":"Prompt Tokens","description":"Number of tokens in the prompt"},"completion_tokens":{"type":"integer","title":"Completion Tokens","description":"Number of tokens in the completion"},"total_tokens":{"type":"integer","title":"Total Tokens","description":"Total number of tokens used"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd","description":"Lightning Rod total cost of the call in USD, summing inference and any research/classification costs."},"inference_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inference Cost Usd","description":"Lightning Rod cost in USD attributable to model inference."},"research_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Research Cost Usd","description":"Lightning Rod cost in USD for web research, when `research` was enabled. Each source is billed as a separate RESEARCH event."},"classification_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Classification Cost Usd","description":"Lightning Rod cost in USD for question classification, when `answer_type` was `auto`."}},"type":"object","required":["prompt_tokens","completion_tokens","total_tokens"],"title":"Usage","description":"Token counts plus Lightning Rod cost fields. The `*_cost_usd` fields are present when applicable (research and classification costs only appear when those steps ran)."}}}}
```

## The ChatMessage object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"ChatMessage":{"properties":{"role":{"type":"string","title":"Role","description":"The role of the message author (system, user, or assistant)"},"content":{"type":"string","title":"Content","description":"The content of the message"}},"type":"object","required":["role","content"],"title":"ChatMessage"}}}}
```

## The Choice object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"Choice":{"properties":{"index":{"type":"integer","title":"Index","description":"The index of this choice"},"message":{"$ref":"#/components/schemas/ResponseMessage","description":"The message generated by the model"},"finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finish Reason","description":"The reason the model stopped generating tokens"}},"type":"object","required":["index","message"],"title":"Choice"},"ResponseMessage":{"properties":{"role":{"type":"string","title":"Role","description":"The role of the message author"},"content":{"type":"string","title":"Content","description":"The model's full response. When `answer_type` was set on the request, a machine-readable answer is embedded between `<answer></answer>` tags at the end (e.g. `<answer>0.62</answer>` for a binary probability). See the request's `answer_type` field for the per-type shapes."},"thinking":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thinking","description":"The model's reasoning/thinking chain, when returned by the model."},"annotations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/UrlCitationAnnotation"}},{"type":"null"}],"title":"Annotations","description":"Source citations from web research, present only when `research` ran. Each entry is a `url_citation` referencing a source the model used."}},"type":"object","required":["role","content"],"title":"ResponseMessage"},"UrlCitationAnnotation":{"properties":{"type":{"type":"string","const":"url_citation","title":"Type","description":"The annotation type. Always `url_citation`.","default":"url_citation"},"url_citation":{"$ref":"#/components/schemas/UrlCitation","description":"The cited source."}},"type":"object","required":["type","url_citation"],"title":"UrlCitationAnnotation"},"UrlCitation":{"properties":{"url":{"type":"string","title":"Url","description":"URL of the cited source."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Title of the cited source, when available."}},"type":"object","required":["url"],"title":"UrlCitation"}}}}
```

## The CompletionChoice object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"CompletionChoice":{"properties":{"index":{"type":"integer","title":"Index","description":"The index of this choice"},"text":{"type":"string","title":"Text","description":"The generated text"},"finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finish Reason","description":"The reason the model stopped generating tokens"}},"type":"object","required":["index","text"],"title":"CompletionChoice"}}}}
```

## The CompletionRequest object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"CompletionRequest":{"properties":{"model":{"type":"string","title":"Model","description":"ID of the model to use"},"prompt":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Prompt","description":"The prompt(s) to generate completions for"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Sampling temperature between 0 and 2","default":0.6},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens","description":"Maximum number of tokens to generate"},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P","description":"Nucleus sampling parameter"},"top_k":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Top K","description":"Number of top tokens to consider"},"min_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min P","description":"Minimum probability for a token to be considered"},"reasoning_effort":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reasoning Effort","description":"Lightning Rod extension. Reasoning budget the model spends before answering: `low`, `medium`, or `high`. Higher effort improves accuracy on harder questions at additional token cost. With raw OpenAI clients pass via `extra_body`."},"stream":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Stream","description":"Whether to stream back partial progress","default":false},"n":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"N","description":"Number of completions to generate","default":1},"stop":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stop","description":"Up to 4 sequences where the API will stop generating"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"Deterministic sampling seed"},"research":{"anyOf":[{"type":"boolean"},{"$ref":"#/components/schemas/ResearchOptions"},{"type":"null"}],"title":"Research","description":"Lightning Rod extension. Opt-in web research before forecasting. Pass `true` to query all default sources, or a `ResearchOptions` object to select sources. Available sources: `perplexity` (Perplexity web search), `google_news` (recent Google News articles). Each source runs as its own query and is billed as a separate RESEARCH event; when research runs, its cost is reported in `usage`. With raw OpenAI clients pass via `extra_body`."},"answer_type":{"anyOf":[{"$ref":"#/components/schemas/AnswerTypeEnum"},{"type":"string","const":"auto"},{"type":"null"}],"title":"Answer Type","description":"Lightning Rod extension that injects output-format guidance and appends a structured answer between `<answer></answer>` tags in the response text. One of `binary`, `multiple_choice`, `continuous`, `free_response`, or `auto`. Raw response shapes: `binary` -> `<answer>0.62</answer>` (probability between 0 and 1); `continuous` -> `<answer>{\"mean\": 42.5, \"standard_deviation\": 5.2}</answer>`; `multiple_choice` -> `<options>{\"A\": \"...\", \"B\": \"...\"}</options>` followed by `<answer>{\"A\": 0.55, \"B\": 0.45}</answer>`; `free_response` -> `<answer>...</answer>`. `auto` classifies the prompt server-side first, then returns one of the above. Omit for prose only. With raw OpenAI clients pass via `extra_body`."}},"type":"object","required":["model","prompt"],"title":"CompletionRequest"},"ResearchOptions":{"properties":{"sources":{"items":{"type":"string","enum":["perplexity","google_news"]},"type":"array","title":"Sources","description":"Which research source providers to use. Each provider is billed separately."}},"type":"object","title":"ResearchOptions","description":"Opt-in research enrichment for forecasting requests.\n\nWhen set, the API fetches web-grounded context from the requested sources\nand injects it into the prompt before calling the model. Each successful\nsource produces a billable RESEARCH event."},"AnswerTypeEnum":{"type":"string","enum":["BINARY","MULTIPLE_CHOICE","CONTINUOUS","CONTINUOUS_VALUE_ONLY","FREE_RESPONSE"],"title":"AnswerTypeEnum"}}}}
```

## The CompletionResponse object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"CompletionResponse":{"properties":{"id":{"type":"string","title":"Id","description":"A unique identifier for the completion"},"object":{"type":"string","const":"text_completion","title":"Object","description":"The object type","default":"text_completion"},"created":{"type":"integer","title":"Created","description":"Unix timestamp of when the completion was created"},"model":{"type":"string","title":"Model","description":"The model used for the completion"},"choices":{"items":{"$ref":"#/components/schemas/CompletionChoice"},"type":"array","title":"Choices","description":"A list of completion choices"},"usage":{"anyOf":[{"$ref":"#/components/schemas/Usage"},{"type":"null"}],"description":"Usage statistics for the completion request"}},"type":"object","required":["id","created","model","choices"],"title":"CompletionResponse"},"CompletionChoice":{"properties":{"index":{"type":"integer","title":"Index","description":"The index of this choice"},"text":{"type":"string","title":"Text","description":"The generated text"},"finish_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finish Reason","description":"The reason the model stopped generating tokens"}},"type":"object","required":["index","text"],"title":"CompletionChoice"},"Usage":{"properties":{"prompt_tokens":{"type":"integer","title":"Prompt Tokens","description":"Number of tokens in the prompt"},"completion_tokens":{"type":"integer","title":"Completion Tokens","description":"Number of tokens in the completion"},"total_tokens":{"type":"integer","title":"Total Tokens","description":"Total number of tokens used"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd","description":"Lightning Rod total cost of the call in USD, summing inference and any research/classification costs."},"inference_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inference Cost Usd","description":"Lightning Rod cost in USD attributable to model inference."},"research_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Research Cost Usd","description":"Lightning Rod cost in USD for web research, when `research` was enabled. Each source is billed as a separate RESEARCH event."},"classification_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Classification Cost Usd","description":"Lightning Rod cost in USD for question classification, when `answer_type` was `auto`."}},"type":"object","required":["prompt_tokens","completion_tokens","total_tokens"],"title":"Usage","description":"Token counts plus Lightning Rod cost fields. The `*_cost_usd` fields are present when applicable (research and classification costs only appear when those steps ran)."}}}}
```

## The HTTPValidationError object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}
```

## The ModelListResponse object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"ModelListResponse":{"properties":{"object":{"type":"string","const":"list","title":"Object","description":"The object type","default":"list"},"data":{"items":{"$ref":"#/components/schemas/ModelObject"},"type":"array","title":"Data","description":"A list of model objects"}},"type":"object","required":["data"],"title":"ModelListResponse"},"ModelObject":{"properties":{"id":{"type":"string","title":"Id","description":"The model identifier"},"object":{"type":"string","const":"model","title":"Object","description":"The object type","default":"model"},"created":{"type":"integer","title":"Created","description":"Unix timestamp of when the model was created","default":0},"owned_by":{"type":"string","title":"Owned By","description":"The organization that owns the model","default":"lightningrodlabs"},"name":{"type":"string","title":"Name","description":"Display name of the model","default":""},"description":{"type":"string","title":"Description","description":"Description of the model","default":""},"context_length":{"type":"integer","title":"Context Length","description":"Maximum context length in tokens","default":0},"max_completion_tokens":{"type":"integer","title":"Max Completion Tokens","description":"Maximum number of tokens to generate","default":0},"pricing":{"additionalProperties":true,"type":"object","title":"Pricing","description":"Per-token pricing"}},"type":"object","required":["id"],"title":"ModelObject"}}}}
```

## The ModelObject object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"ModelObject":{"properties":{"id":{"type":"string","title":"Id","description":"The model identifier"},"object":{"type":"string","const":"model","title":"Object","description":"The object type","default":"model"},"created":{"type":"integer","title":"Created","description":"Unix timestamp of when the model was created","default":0},"owned_by":{"type":"string","title":"Owned By","description":"The organization that owns the model","default":"lightningrodlabs"},"name":{"type":"string","title":"Name","description":"Display name of the model","default":""},"description":{"type":"string","title":"Description","description":"Description of the model","default":""},"context_length":{"type":"integer","title":"Context Length","description":"Maximum context length in tokens","default":0},"max_completion_tokens":{"type":"integer","title":"Max Completion Tokens","description":"Maximum number of tokens to generate","default":0},"pricing":{"additionalProperties":true,"type":"object","title":"Pricing","description":"Per-token pricing"}},"type":"object","required":["id"],"title":"ModelObject"}}}}
```

## The ResearchOptions object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"ResearchOptions":{"properties":{"sources":{"items":{"type":"string","enum":["perplexity","google_news"]},"type":"array","title":"Sources","description":"Which research source providers to use. Each provider is billed separately."}},"type":"object","title":"ResearchOptions","description":"Opt-in research enrichment for forecasting requests.\n\nWhen set, the API fetches web-grounded context from the requested sources\nand injects it into the prompt before calling the model. Each successful\nsource produces a billable RESEARCH event."}}}}
```

## The ResponseMessage object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"ResponseMessage":{"properties":{"role":{"type":"string","title":"Role","description":"The role of the message author"},"content":{"type":"string","title":"Content","description":"The model's full response. When `answer_type` was set on the request, a machine-readable answer is embedded between `<answer></answer>` tags at the end (e.g. `<answer>0.62</answer>` for a binary probability). See the request's `answer_type` field for the per-type shapes."},"thinking":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thinking","description":"The model's reasoning/thinking chain, when returned by the model."},"annotations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/UrlCitationAnnotation"}},{"type":"null"}],"title":"Annotations","description":"Source citations from web research, present only when `research` ran. Each entry is a `url_citation` referencing a source the model used."}},"type":"object","required":["role","content"],"title":"ResponseMessage"},"UrlCitationAnnotation":{"properties":{"type":{"type":"string","const":"url_citation","title":"Type","description":"The annotation type. Always `url_citation`.","default":"url_citation"},"url_citation":{"$ref":"#/components/schemas/UrlCitation","description":"The cited source."}},"type":"object","required":["type","url_citation"],"title":"UrlCitationAnnotation"},"UrlCitation":{"properties":{"url":{"type":"string","title":"Url","description":"URL of the cited source."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Title of the cited source, when available."}},"type":"object","required":["url"],"title":"UrlCitation"}}}}
```

## The UrlCitationAnnotation object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"UrlCitationAnnotation":{"properties":{"type":{"type":"string","const":"url_citation","title":"Type","description":"The annotation type. Always `url_citation`.","default":"url_citation"},"url_citation":{"$ref":"#/components/schemas/UrlCitation","description":"The cited source."}},"type":"object","required":["type","url_citation"],"title":"UrlCitationAnnotation"},"UrlCitation":{"properties":{"url":{"type":"string","title":"Url","description":"URL of the cited source."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Title of the cited source, when available."}},"type":"object","required":["url"],"title":"UrlCitation"}}}}
```

## The UrlCitation object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"UrlCitation":{"properties":{"url":{"type":"string","title":"Url","description":"URL of the cited source."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Title of the cited source, when available."}},"type":"object","required":["url"],"title":"UrlCitation"}}}}
```

## The Usage object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"Usage":{"properties":{"prompt_tokens":{"type":"integer","title":"Prompt Tokens","description":"Number of tokens in the prompt"},"completion_tokens":{"type":"integer","title":"Completion Tokens","description":"Number of tokens in the completion"},"total_tokens":{"type":"integer","title":"Total Tokens","description":"Total number of tokens used"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd","description":"Lightning Rod total cost of the call in USD, summing inference and any research/classification costs."},"inference_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inference Cost Usd","description":"Lightning Rod cost in USD attributable to model inference."},"research_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Research Cost Usd","description":"Lightning Rod cost in USD for web research, when `research` was enabled. Each source is billed as a separate RESEARCH event."},"classification_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Classification Cost Usd","description":"Lightning Rod cost in USD for question classification, when `answer_type` was `auto`."}},"type":"object","required":["prompt_tokens","completion_tokens","total_tokens"],"title":"Usage","description":"Token counts plus Lightning Rod cost fields. The `*_cost_usd` fields are present when applicable (research and classification costs only appear when those steps ran)."}}}}
```

## The ValidationError object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}
```

## The MppTopupRequest object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"MppTopupRequest":{"properties":{"amount_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount Cents","description":"Top-up size in cents. Defaults to 500 ($5.00). Must be identical on the challenge call and the paid retry."}},"type":"object","title":"MppTopupRequest"}}}}
```

## The MppTopupResponse object

```json
{"openapi":"3.1.0","info":{"title":"LightningRod API","version":"1.0.0"},"components":{"schemas":{"MppTopupResponse":{"properties":{"organization_id":{"type":"string","title":"Organization Id"},"credited_cents":{"type":"integer","title":"Credited Cents"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key"},"api_key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key Id"}},"type":"object","required":["organization_id","credited_cents"],"title":"MppTopupResponse"}}}}
```


