AI-GENERATED · DISCLAIMER
Almanex
Docs / API reference

HTTP API

Five endpoints, Bearer auth, structured JSON. Cloudflare edge served. Read the spec and try every endpoint live below — your key never leaves the browser.

◆ 1 / Authentication

Bearer keys

Every request must carry an API key in the Authorization header. Generate one at /account.

Authorization: Bearer alm_live_a1b2c3…

Keys are hashed at rest; if you lose one, generate a new one and revoke the old. Never commit a key to source control.

◆ 2 / Rate limits

Monthly request caps

Quotas are enforced per calendar month (UTC). Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers so you can self-throttle.

Plan Monthly cap Note
developer 1,000 / month $0. Generous free tier — every signup gets one.
builder 10,000 / month $29/mo. The default for shipping products.
scale 100,000 / month $199/mo. Production agent traffic at volume.
◆ 3 / Endpoints

Reference

Each endpoint includes a live Try it widget. Click it, paste your key (kept only in sessionStorage), and you'll see the real response.

GET /api/v1/reports

List reports with filters and pagination. Body content NOT included.

◆ Parameters
Name In Description
ticker query Comma-separated tickers (e.g. AAPL,MSFT).
sector query GICS sector slug (e.g. health-care).
q query Substring match against title/company/summary.
limit query Rows per page, default 20, max 100.
offset query Row offset, default 0.
◆ Example
curl "https://almanex.ai/api/v1/reports?limit=3" \
  -H "Authorization: Bearer alm_live_…"
◆ Response (200)
{
  "reports": [
    { "ticker": "NVDA", "slug": "q4-fy26-earnings", "title": "…",
      "company": "NVIDIA Corporation", "quarter": "Q4 FY26",
      "report_type": "earnings-update", "rating": "Buy",
      "price_target": "$185", "summary": "…",
      "as_of_date": "2026-05-02", "generated_at": 1746230400,
      "generated_by": "claude-opus-4", "web_url": "https://almanex.ai/…",
      "tags": ["sector:information-technology", "industry:semis"] }
  ],
  "total": 503,
  "limit": 3,
  "offset": 0
}
◆ Try it

Live request, your browser, your key.

GET /api/v1/reports/{ticker}

All reports for one ticker, newest first.

◆ Parameters
Name In Description
ticker path Uppercase symbol, 1–10 chars (e.g. NVDA, BRK.B).
◆ Example
curl https://almanex.ai/api/v1/reports/NVDA \
  -H "Authorization: Bearer alm_live_…"
◆ Response (200)
{
  "ticker": "NVDA",
  "reports": [
    { "ticker": "NVDA", "slug": "q4-fy26-earnings", "title": "…",
      "summary": "…", "as_of_date": "2026-05-02", … }
  ],
  "count": 1
}
◆ Try it

Live request, your browser, your key.

GET /api/v1/reports/{ticker}/{slug}

Full report content as JSON: metadata + body markdown + sources.

◆ Parameters
Name In Description
ticker path Uppercase symbol.
slug path Report slug, lowercase kebab.
◆ Example
curl https://almanex.ai/api/v1/reports/NVDA/q4-fy26-earnings \
  -H "Authorization: Bearer alm_live_…"
◆ Response (200)
{
  "ticker": "NVDA",
  "slug": "q4-fy26-earnings",
  "title": "NVIDIA — Q4 FY26 Earnings Update",
  "summary": "…",
  "rating": "Buy",
  "price_target": "$185",
  "as_of_date": "2026-05-02",
  "sources": [{ "title": "…", "url": "…", "type": "earnings-release" }],
  "tags": ["sector:information-technology"],
  "body_md": "## Quarter at a glance\n\n…"
}

If you don't know the slug, hit /latest first (next endpoint).

◆ Try it

Live request, your browser, your key.

GET /api/v1/reports/{ticker}/latest

Newest report for a ticker. Same response shape as the slug endpoint.

◆ Parameters
Name In Description
ticker path Uppercase symbol.
◆ Example
curl https://almanex.ai/api/v1/reports/NVDA/latest \
  -H "Authorization: Bearer alm_live_…"
◆ Response (200)
{
  "ticker": "NVDA",
  "slug": "q4-fy26-earnings",
  "title": "NVIDIA — Q4 FY26 Earnings Update",
  "summary": "…",
  "as_of_date": "2026-05-02",
  "sources": [ … ],
  "body_md": "…"
}
◆ Try it

Live request, your browser, your key.

GET /api/v1/whoami

Return the calling key's user, plan, and current quota.

◆ Example
curl https://almanex.ai/api/v1/whoami \
  -H "Authorization: Bearer alm_live_…"
◆ Response (200)
{
  "user_id": "user_…",
  "email": "you@example.com",
  "plan": "pro",
  "api_plan": "builder",
  "key_id": "key_…",
  "key_prefix": "alm_live_a1b2",
  "quota": { "period": "2026-05", "limit": 10000,
             "used": 47, "remaining": 9953, "resets_at": 1748736000 }
}
◆ Try it

Live request, your browser, your key.

◆ 4 / Bring your own model

BYOM & the inference contract

Almanex is the corpus, not the model. Plug in any inference provider — Anthropic, Gemini, OpenAI, or any OpenAI-compatible endpoint (Together, Groq, OpenRouter, vLLM, Ollama). Set one BYOK header to override the managed provider for a single request, or set several to enable cascading fallback (anthropic → gemini → openai → openai-compat).

Keys are read from request headers and forwarded verbatim to the upstream provider. They are never persisted, never logged in full, and never stored anywhere in our infra. BYOK shifts the inference bill off Almanex — _meta.inference_cost_cents comes back as null on those calls.

Header Shape Purpose
X-Anthropic-Keysk-ant-…Anthropic Messages API key.
X-Gemini-KeyAIza<35 chars>Google Generative Language (v1beta) API key.
X-OpenAI-Keysk-… / sk-proj-…OpenAI Chat Completions API key.
X-Model-Provideranthropic | gemini | openai | openai-compatForce a single provider for this request — disables cascading.
X-Model-Endpointhttps://…Required for openai-compat. Base URL of the chat-completions service.
X-Model-Key<any>Required for openai-compat. Auth token for the custom endpoint.
X-Model-Name<any>Override the default model id (e.g. claude-haiku-4-5-20251001, gemini-2.5-flash, qwen2.5-72b).
◆ openai-compat protocol

Anything that speaks the OpenAI Chat Completions wire format works. The agent posts to {X-Model-Endpoint}/chat/completions (or to the endpoint directly if it already includes the path) with Authorization: Bearer {X-Model-Key}. Tool calls use the standard tool_calls[] shape.

# Run the comparison agent against a Together-hosted Llama
curl https://almanex.ai/api/agent/compare \
  -H "Authorization: Bearer alm_live_…" \
  -H "X-Model-Endpoint: https://api.together.xyz/v1" \
  -H "X-Model-Key: $TOGETHER_API_KEY" \
  -H "X-Model-Name: meta-llama/Llama-3.3-70B-Instruct-Turbo" \
  -H "Content-Type: application/json" \
  -d '{"tickers":["NVDA","AMD"],"dimension":"growth"}'

Cost reporting falls back to $0.00 for unknown models — you own the bill on your provider's side.

◆ Cascading fallback

When more than one BYOK key is set (and X-Model-Provider is not), the agent tries each provider in order (anthropic → gemini → openai → openai-compat) and falls forward on 5xx, 429, or network error. It does not fall through on a 4xx auth failure or a content-policy refusal — those mean the same prompt would fail elsewhere. Every attempt (success or failure) shows up in _meta.providers_tried.

◆ 5 / Errors

Structured error responses

All errors are returned as JSON with a stable error field your code can switch on.

  • 401 unauthorized
    { "error": "unauthorized", "reason": "missing|malformed|not_found|revoked", "detail": "…" }
  • 429 rate_limited
    { "error": "rate_limited", "plan": "…", "limit": N, "used": N, "remaining": N, "resets_at": <unix> }
  • 400 bad_request
    { "error": "bad_request" }
  • 404 not_found
    { "error": "not_found" }
◆ 6 / Schema

Report shape

The full report response (from the slug and /latest endpoints) as a TypeScript-style interface:

interface Report {
  ticker: string;             // "NVDA"
  slug: string;               // "q4-fy26-earnings"
  title: string;
  company: string;
  quarter: string | null;     // "Q4 FY26"
  report_type:                // canonical enum
    | "earnings-update" | "earnings-preview"
    | "initiation" | "thesis"
    | "one-pager" | "comps" | "dcf" | "other";
  rating: string | null;      // "Buy" / "Hold" / "Sell" / null
  price_target: string | null;
  summary: string;
  as_of_date: string;         // ISO date "YYYY-MM-DD"
  generated_at: number;       // unix seconds
  generated_by: string;       // model id
  web_url: string;            // canonical web page
  tags: string[];             // e.g. "sector:information-technology"
  sources: Source[];
  body_md: string;            // markdown
}

interface Source {
  title: string;
  url: string;
  type?: string;              // "earnings-release", "10-K", …
}