Build
API
Call Frames F1 with any OpenAI SDK: keys, endpoints, runs, streaming and budgets.
The Frames API lets your code use Frames F1, or pull data from the catalog directly. It works with OpenAI's SDKs, so most apps only need a new base URL, an API key and the model name frames-f1.
Basics#
| Base URL | https://api.frames.ag/v1 |
| Authentication | Authorization: Bearer <your key>. Create keys in the dashboard under Settings → API Access; each key is shown once. |
| Model | frames-f1 |
| Budget | frames.budget_usd per request, capped at your plan's per-run cap. Without it, F1 uses a default budget within that cap. |
Endpoints#
| Method and path | What it does |
|---|---|
POST /v1/chat/completions | Ask F1 in the OpenAI Chat Completions format |
POST /v1/responses | The same in the OpenAI Responses format, with previous_response_id for follow-ups |
GET /v1/models | Lists model ids, no key needed. Use frames-f1. |
POST /v1/runs | Starts a run in Frames' own format |
GET /v1/runs/{id} | Gets a run's status, result and receipts |
POST /v1/runs/{id}/approve | Resumes a run paused for approval, with a max_usd |
POST /v1/runs/{id}/cancel | Stops a run |
GET /v1/runs/{id}/tool-results | Reads the full responses of a run's paid calls |
/v1/tools/* | Search, probe and invoke tools directly. See Tool endpoints. |
First request#
Put your key in the FRAMES_API_KEY environment variable, then send a question. budget_usd is in dollars, so 1 lets this request spend up to 1,000 credits.
curl https://api.frames.ag/v1/chat/completions \
-H "Authorization: Bearer $FRAMES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "frames-f1",
"messages": [{ "role": "user", "content": "Which fintech startups raised a Series A in the last 90 days? Include sources." }],
"frames": { "budget_usd": 1 }
}'# export FRAMES_API_KEY=<your key>
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.frames.ag/v1",
api_key=os.environ["FRAMES_API_KEY"],
)
resp = client.chat.completions.create(
model="frames-f1",
messages=[{"role": "user", "content": "Which fintech startups raised a Series A in the last 90 days? Include sources."}],
extra_body={"frames": {"budget_usd": 1}},
)
print(resp.choices[0].message.content)import OpenAI from "openai"
const client = new OpenAI({
baseURL: "https://api.frames.ag/v1",
apiKey: process.env.FRAMES_API_KEY,
})
const resp = await client.chat.completions.create({
model: "frames-f1",
messages: [{ role: "user", content: "Which fintech startups raised a Series A in the last 90 days? Include sources." }],
// @ts-expect-error Frames extension: per-request budget in USD
frames: { budget_usd: 1 },
})
console.log(resp.choices[0].message.content)import { createOpenAICompatible } from "@ai-sdk/openai-compatible"
import { generateText } from "ai"
const frames = createOpenAICompatible({
name: "frames",
baseURL: "https://api.frames.ag/v1",
apiKey: process.env.FRAMES_API_KEY,
})
const { text } = await generateText({
model: frames("frames-f1"),
prompt: "Which fintech startups raised a Series A in the last 90 days? Include sources.",
// Per-request budget in USD, keyed by the provider name above
providerOptions: { frames: { budget_usd: 1 } },
})
console.log(text)Each SDK sends the budget its own way: extra_body in Python, a frames field in the OpenAI Node SDK (with // @ts-expect-error, since it isn't in OpenAI's types) and providerOptions in the Vercel AI SDK.
Features#
Streaming#
Set "stream": true, or send Accept: text/event-stream on /v1/runs, and the answer streams as it's written, with progress as reasoning updates. Closing the stream doesn't stop the run; cancel it with the run id from the first chunk.
Structured output#
response_format with a JSON schema, or output_schema on /v1/runs, returns JSON in that shape.
Your own tools#
Pass OpenAI tools, and F1 can ask your code to run them through tool_calls, alongside the paid tools it runs itself.
Conversations#
Earlier messages in the request are used as context. On /v1/responses, pass previous_response_id instead of resending them.
Verification level#
frames.verification (or options.verification on /v1/runs) takes none, basic, standard or strict. standard is the default.
Safe retries#
Send an Idempotency-Key header on /v1/runs, and a retried request returns the same run instead of paying twice.
Approvals#
If a budget goes over your project's policy, the run is created paused with HTTP 402 and status: "requires_approval", holding no credits. Approve it with a max_usd (still capped by your plan) or cancel it.
What comes back#
The OpenAI endpoints add frames_usage and frames: { run_id, status, confidence } to the usual response. /v1/runs returns the full run: result, usage, payments, confidence and tools_used.