# Axion API Reference

Programmatic access to Axion's forecasting platform. Send a question; Axion runs an orchestrator and a team of research agents (web search, market data, SEC filings, Fermi estimates) that reason in public, cite their evidence, and return graded probabilistic forecasts.

## Getting started

1. **Create an account** at [axion.eternis.ai](https://axion.eternis.ai), then create an API key on the API Keys page. Any Axion account can create keys. No paid subscription tier required.
2. **Add credits** before your first call. API usage is billed separately from the Axion monthly plan, in prepaid credits, and new accounts start at a zero balance. Purchases are self-serve via Stripe: $1 buys 100 credits, $50 minimum.
3. **Call the API** with your key as a Bearer token (see Authentication). A positive credit balance is required to start a forecast.

## Authentication

All endpoints require an API key passed as a Bearer token in the `Authorization` header:

```
Authorization: Bearer axn_sk_...
```

API keys are created and managed on the API Keys page. Any signed-in account can create a key. No paid plan required. Keys are shown once at creation and cannot be retrieved later.

## Base URL

```
https://api.axion.eternis.ai
```

## Credits

API usage is billed separately from the Axion monthly plan. Users pre-purchase credits before usage.

- $1 = 100 credits
- Minimum purchase: $50 (5,000 credits)
- Credits are deducted per message based on token usage across all models

| Model | Input rate | Output rate | Cached rate |
| --- | --- | --- | --- |
| Opus 4.8 | 750 | 3,750 | 75 |
| Sonnet 4.6 | 450 | 2,250 | 45 |

Rates are per 1M tokens. A single thread may use multiple models (coordinator + agents), so costs accumulate across all calls. Negative balances are allowed to guarantee delivery of in-progress results.

## Limits

- Maximum 10 concurrent in-progress threads per user

## Coding agents

This reference is built to drop straight into a coding agent (Claude Code, Cursor, and similar). At the top of this page, use **Copy as Markdown** to copy the full reference formatted for LLMs, or **Copy as Text** for a plain-text version. Paste it into your agent's context and it has everything it needs to write a correct integration: authentication, request and response shapes, polling, and error handling.

A prompt that works well:

```
Here are the Axion API docs. Write a <language> client that creates a
forecast, polls until it completes, and prints each forecast with its
probability. Read the API key from an AXION_API_KEY environment variable.
```

## POST /forecasts

Start a new forecast thread, or send a follow-up message to an existing one. Requires a positive API credit balance.

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| input | string | required | The question or analysis prompt. |
| id | string | optional | Existing thread ID for follow-up messages. |
| max_forecasts | integer | optional | Number of forecasts to generate (1-10). Default 1. |
| effort | string | optional | Analysis depth: low, medium, or high. Default medium. |
| webhook_url | string | optional | URL to receive a POST callback on completion or failure. |

```json
{
  "input": "Will NVIDIA's data center revenue exceed $40B in Q1 2026?",
  "max_forecasts": 3,
  "effort": "high"
}
```

### Response (201)

```json
{
  "id": "thread_abc123",
  "input": "Will NVIDIA's data center revenue exceed $40B in Q1 2026?",
  "preliminary_result": null,
  "status": "starting"
}
```

## GET /forecasts/{thread_id}

Poll the status and results of a forecast thread.

Status values: `starting`, `in_progress`, `completed`, `failed`.

### Response (200)

```json
{
  "id": "thread_abc123",
  "input": "Will NVIDIA's data center revenue exceed $40B in Q1 2026?",
  "preliminary_result": "Early read: data-center momentum and hyperscaler capex point above $40B, but HBM supply is the swing factor. Refining with filings and channel checks…",
  "status": "completed",
  "result": "NVIDIA's data-center segment has grown for six straight quarters, reaching $35.6B in Q4 FY25. The Blackwell ramp and committed hyperscaler capex support a Q1 2026 figure above $40B; the main downside is HBM3E supply. On balance the threshold is more likely than not to be cleared…",
  "credits_consumed": 4231,
  "agents_progress": [
    { "slug": "web-search", "progress": 1.0, "turn": 12, "action": "done" },
    { "slug": "sec-filings", "progress": 1.0, "turn": 8, "action": "done" }
  ],
  "forecasts": [
    {
      "forecast_text": "NVIDIA data center revenue will exceed $40B in Q1 2026",
      "probability": 0.72,
      "confidence_lower": 0.55,
      "confidence_upper": 0.85,
      "resolution_date": "2026-07-15",
      "reasoning": "Q4 FY25 data-center revenue was $35.6B (+16% QoQ). Blackwell shipments and hyperscaler capex guidance imply continued double-digit sequential growth, placing $40B within reach absent a supply shock…",
      "concludes_at": "2026-07-15",
      "is_concluded": false,
      "outcome": null,
      "outcome_reasoning": null,
      "created_at": "2026-04-14T10:30:00Z"
    }
  ],
  "artifacts": [
    { "component_name": "RevenueChart", "props": "{\"data\": [...]}" }
  ]
}
```

## GET /forecasts

List all forecast threads for your account.

### Response (200)

```json
{
  "forecasts": [
    {
      "id": "thread_abc123",
      "input": "Will NVIDIA's data center revenue...",
      "status": "completed",
      "credits_consumed": 4231,
      "created_at": "2026-04-14T10:30:00Z"
    }
  ]
}
```

## POST /forecasts/{thread_id}/stop

Cancel an in-progress forecast. Credits consumed up to cancellation are still charged.

### Response (200)

```json
{ "success": true }
```

## POST /forecasts/{thread_id}/share

Make a forecast thread publicly viewable. Returns a relative share URL.

### Response (200)

```json
{ "success": true, "share_url": "/share/thread_abc123" }
```

## POST /forecasts/{thread_id}/unshare

Revoke public access to a previously shared forecast thread.

### Response (200)

```json
{ "success": true }
```

## DELETE /forecasts/{thread_id}

Delete a forecast thread.

### Response (200)

```json
{ "success": true }
```

## GET /account/balance

Returns your current credit balance.

### Response (200)

```json
{ "credits": 3750 }
```

## POST /account/credits/purchase

Create a Stripe Checkout session for a one-time credit purchase. Minimum amount is $50.

### Request body

```json
{ "amount": 50 }
```

### Response (200)

```json
{ "checkout_url": "https://checkout.stripe.com/c/pay/cs_..." }
```

## Webhooks

If `webhook_url` is provided when creating a forecast, Axion sends a POST request to that URL when the thread reaches a terminal state (`completed` or `failed`). The payload matches the `GET /forecasts/{thread_id}` response.

Delivery is best-effort with up to 3 retries. Poll as a fallback if you need guaranteed delivery.

## Errors

All errors return a JSON body with an `error` field:

```json
{ "error": "insufficient credits" }
```

| Status | Meaning |
| --- | --- |
| 400 | Invalid request |
| 401 | Invalid or missing API key |
| 402 | Insufficient credits |
| 404 | Thread not found |
| 422 | Invalid request body |
| 429 | Too many concurrent threads (max 10) |
| 500 | Internal error |

## Example: poll until complete

```python
import requests
import time

API_KEY = "axn_sk_..."
BASE = "https://api.axion.eternis.ai"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Create
r = requests.post(f"{BASE}/forecasts", headers=headers, json={
    "input": "Will the Fed cut rates in June 2026?",
    "effort": "high"
})
thread_id = r.json()["id"]

# Poll
while True:
    r = requests.get(f"{BASE}/forecasts/{thread_id}", headers=headers)
    data = r.json()
    print(f"Status: {data['status']}")
    if data["status"] in ("completed", "failed"):
        break
    time.sleep(5)

# Result
for f in data["forecasts"]:
    print(f"{f['forecast_text']}: {f['probability']}")
```
