API reference
Foxy Pro answers questions about stocks, ETFs, commodities, rates, macro and crypto in plain language. For each request it decides what to look at, gathers live market, fundamentals, positioning and macro data, scores the instrument, draws charts and returns one clear answer or a full research note.
Base URL: https://foxy-api.bottomup.app. JSON in, JSON out. Information only: Foxy Pro does not execute orders or give investment advice.
Authentication
Create keys in the workspace under API. Send the key in the x-api-key header (or as a Bearer token). Keys belong to your organisation and draw on its token balance; keep them server side.
curl https://foxy-api.bottomup.app/v1/models -H "x-api-key: fp_live_..."
Models
| foxy-pro-1-fast | tier | Lowest latency. Quotes, single-metric questions, summaries. Up to 2 data rounds. |
| foxy-pro-1 | default | Multi-factor analysis of assets and the market. Up to 5 analysis rounds. |
| foxy-pro-1-deep | tier | Extended reasoning for complex questions and research notes. Up to 8 analysis rounds. |
GET /v1/models returns each tier with its current price in Foxy tokens per million input and output tokens, the fee per data call, and the hold placed while a request runs. Holds are released when the request finishes; you pay only what it used, and failed requests are free. Balances and prices are in Foxy tokens, the billing unit; in API responses these fields keep the name credits so they are not confused with model token counts such as input_tokens.
Messages
POST /v1/messages. Stateless: send the conversation so far, ending with a user turn.
| model | string | One of the model ids. Default foxy-pro-1. |
| messages | array | Up to 40 turns of {role: "user" | "assistant", content: string}. The last must be from the user. |
| max_tokens | integer | Cap on the written answer. Defaults per tier. |
| stream | boolean | Stream server-sent events (see below). |
| language | string | Force the response language, for example "Spanish". Default: the language of the question. |
| instructions | string | Your house preferences (focus, tone, format). They cannot override Foxy Pro policy. |
curl https://foxy-api.bottomup.app/v1/messages \
-H "x-api-key: $FOXY_PRO_API_KEY" -H "content-type: application/json" \
-d '{
"model": "foxy-pro-1",
"messages": [{"role": "user", "content": "Gold outlook for the next month, with the levels that matter"}],
"instructions": "Write for a bank risk committee. Keep it under 300 words."
}'{
"id": "msg_9xQ...",
"type": "message",
"role": "assistant",
"model": "foxy-pro-1",
"content": [{ "type": "text", "text": "Outlook: Positive. Foxy Score 68/100 (data coverage 92%). Gold holds above its 50-day average while real yields ease ..." }],
"data_as_of": "2026-10-08T12:00:03Z",
"usage": { "input_tokens": 18234, "output_tokens": 612, "cache_read_input_tokens": 9120, "tool_calls": 5, "credits": 2.41 },
"prompt_version": "foxy-pro-prompt-2026-10-08",
"policy_version": "foxy-pro-policy-1",
"disclaimer": "Market information only. Not investment advice, no order execution."
}Streaming
With "stream": true the response is text/event-stream. Events, in order:
| status | {stage} | gathering or writing. |
| step | {id, name, asset, state} | What Foxy Pro is analysing, for example technicals for NVDA; state is running, done or failed. |
| text_delta | {text} | A piece of the answer as it is written. |
| message | object | The complete message, identical to the non-streamed response. Last event. |
| error | {type, message} | The request failed after the stream opened. No tokens are charged for failed requests. |
Reports
Long-form research notes run in the background. POST /v1/reports with prompt, depth (standard or deep) and optional language and instructions returns 202 with the report id. Poll GET /v1/reports/:id until status is succeeded or failed; GET /v1/reports lists them. A report carries a markdown content, its title, the time of the data it used and usage. Standard notes take one to three minutes, deep notes up to six.
curl https://foxy-api.bottomup.app/v1/reports -H "x-api-key: $FOXY_PRO_API_KEY" -H "content-type: application/json" \
-d '{"prompt": "Three-month outlook for Brent with scenarios and the levels that matter", "depth": "deep"}'
# => {"id": "rpt_...", "status": "running", ...}Options data
BTC and ETH options positioning from public options data, the same numbers as the Options map. Each call is paid from the token balance (plan allowance first) only when it succeeds; the price is in the x-foxy-tokens-charged response header. Available once Foxy Options is open to your organisation; until then these routes answer 403 with reason: feature_off.
| GET /v1/options/:coin/levels | 0.1 tokens | Call OI ceiling and Put OI floor (overall and near spot), Gamma flip, net gamma, Top gamma strikes, 1-day and 7-day expected range, Vol regime with its reasons. |
| GET /v1/options/:coin/gamma | 0.2 tokens | Gamma profile by price (all expiries and the next one) and call/put open interest, net gamma and net delta exposure by strike. |
| GET /v1/options/:coin/vol | 0.1 tokens | Vol regime, ATM IV at 7 and 30 days, term structure, smiles by delta at 7 and 30 days, 25-delta risk reversal and butterfly, realized volatility, IV percentile. |
| GET /v1/options/:coin/history?days=30 | 0.2 tokens | Daily snapshots (1 to 365 days): spot, levels, Gamma flip, net gamma, ATM IV, realized volatility, Vol regime. |
:coin is BTC or ETH. Gamma and delta exposure are a model under a stated assumption (dealers long calls and short puts), returned with each answer as assumption; they are estimates, not known dealer positions. Every answer carries as_of and the venues it was built from.
curl https://foxy-api.bottomup.app/v1/options/BTC/levels -H "x-api-key: $FOXY_PRO_API_KEY"
# => {"coin": "BTC", "as_of": "2026-10-17T08:15:02Z", "spot": 64210.5, "venues": ["deribit", "okx"],
# "levels": {"call_ceiling": 70000, "call_ceiling_above_spot": 66000, "put_floor": 60000, ...},
# "gamma": {"model": "convention", "net_gamma": "positive", "gamma_flip": 62480, ...},
# "expected_range_1d": {"low": 62690, "high": 65730, ...}, "vol_regime": {"label": "normal", ...}}AI assistants (MCP)
Foxy Pro is a Model Context Protocol server at POST /mcp (Streamable HTTP, JSON responses). Claude, ChatGPT, Cursor and other clients with MCP authorization sign in with a Foxy Pro account (OAuth 2.1 with PKCE, discovery at /.well-known/oauth-protected-resource/mcp). Grok Bot and other clients connect with an API key in the Authorization: Bearer or x-api-key header. Each tool goes through the same key check, rate limit, billing and data checks as the endpoints above. No tool places, changes or cancels an order. prepare_order only drafts a card the person confirms in Foxy Pro. Nothing is sent.
| ask_foxy | question, detail?, summary_id?, language? | A market question. detail "summary" (default) is a short answer with a summary id. detail "full" with that id is the complete analysis. The older depth argument still works. |
| start_report | prompt, depth?, language? | Starts a research report; returns its id. |
| get_report | id | Status, and the full report once it has succeeded. |
| options_levels | coin | BTC or ETH options levels, as GET /v1/options/:coin/levels. Estimates, not dealer positions. |
| portfolio_snapshot | days? | Read-only organisation and usage. Live OKX balances stay in the Foxy Pro app. Never places orders. |
| prepare_order | instrument, side, size, note? | Drafts an order card. sent is false. The person confirms it in Foxy Pro. Nothing is sent. |
| token_balance | days? | Organisation, balance and usage. |
curl $FOXY_PRO_URL/mcp \
-H "Authorization: Bearer $FOXY_PRO_API_KEY" \
-H "content-type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {"name": "ask_foxy", "arguments": {"question": "Is gold crowded right now?"}}}'Data freshness
Every answer and report carries data_as_of, the time of the most recent market data behind it. Foxy Pro works only from data it retrieves at request time, never from memory, and says plainly in the answer when part of the picture is unavailable.
Account and usage
| GET /v1/organization | Organisation, token balance and partner. | |
| GET /v1/usage?days=30 | Daily totals, usage by model and by key, and recent requests. | |
| GET /status | Service status: operational, degraded or unavailable. No key needed. |
Errors and limits
{ "type": "error", "error": { "type": "insufficient_credits_error", "message": "...", "required_credits": 25, "balance_credits": 3 }, "request_id": "..." }| 400 | invalid_request_error | The body is malformed or out of range. |
| 401 | authentication_error | Missing, invalid, revoked or expired key. |
| 402 | insufficient_credits_error | Balance is below the hold for this request. |
| 403 | permission_error | The organisation is suspended. |
| 429 | rate_limit_error | 120 requests per minute per key, 4 concurrent requests per organisation. |
| 502 | upstream_error | The request could not be completed. Nothing was charged. |
Coverage
Equities and ETFs on exchanges worldwide (with reported financials, filings and peer valuation), indices, government bond yields, precious and industrial metals, energy and agricultural commodities (with futures positioning, curves and inventories), central-bank macro for the US, Turkey, Latin America, the Gulf and beyond, and crypto (derivatives, flows and on-chain activity). Stocks and commodities get a Foxy Score with an outlook. Coverage expands over time without changes to the API.
Questions or volume pricing: [email protected].