Quick start
- In Settings → Keys and API, make a key and add API balance. Keys are shown once.
- Send it as
Authorization: Bearer mx_live_…tohttps://aimagicx.vercel.app/api/v1. - Add an
Idempotency-Keyheader (a UUID) to every call that starts work. If the network drops, send the same request with the same key: you get the first result and are charged once.
curl https://aimagicx.vercel.app/api/v1/runs \
-H "Authorization: Bearer $MAGICX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"model":"claude-sonnet-5-5","input":"Compare the three cheapest EV chargers in the UK and cite sources.","tools":["web"]}'Endpoints
| Method | Path | Key scope | What it does |
|---|---|---|---|
| GET | /models | Any | Models with API prices |
| POST | /quotes | Any | Estimate and maximum for a chat call, run or media job |
| POST | /chat/completions | chat | OpenAI-compatible chat: streaming, tools and images |
| POST | /runs | runs | Start an agent run |
| GET | /runs/{id} | runs | Run status, answer, files and cost |
| GET | /runs/{id}/events | runs | Follow a run as server-sent events |
| POST | /runs/{id}/cancel | runs | Stop a run |
| POST | /media | media | Start an image, video, voice, transcript, music or sound job |
| GET | /media/{id} | media | Job status and download links |
| POST | /files | media or chat | Upload an image, recording or video |
| POST | /files/uploads/{id}/complete | media or chat | Finish an upload after the PUT |
| GET · DELETE | /files/{id} | media or chat | A file with a download link, or delete it |
| GET | /usage | usage | Spend by type and model for a period |
| GET | /receipts | usage | One receipt per call, newest first |
| GET · POST | /webhooks | runs or media | List or add webhook endpoints |
| DELETE | /webhooks/{id} | runs or media | Remove an endpoint |
| GET | /webhooks/{id}/deliveries | runs or media | Recent deliveries |
| GET | /openapi.json | None | OpenAPI 3.1 spec |
The full schema is at /v1/openapi.json. Load it into your client generator or API tool.
Prices
Prices are in mana (1 mana = $0.01), plus 1 mana per agent run. GET /models lists each model's price, and POST /quotes returns the estimate and the most a call can cost. That maximum is reserved when the call starts, and you're charged for what was actually used. Failed work costs nothing.
API calls are paid from your API balance and top-up mana, never from plan mana. Each key can have a monthly cap; a call that would pass it is refused with 402.
Chat completions
Works with OpenAI client libraries: point the base URL at us and use a model id from /models. Send text, function tools, and images on models that support vision. Your code runs function calls; use agent runs when you want Magicx to do the steps for you.
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env.MAGICX_API_KEY, baseURL: "https://aimagicx.vercel.app/api/v1" });
const stream = await client.chat.completions.create(
{ model: "gpt-5.6-luna", messages: [{ role: "user", content: "Write a haiku about tea." }], stream: true },
{ headers: { "Idempotency-Key": crypto.randomUUID() } },
);
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? "");import os, uuid
from openai import OpenAI
client = OpenAI(api_key=os.environ["MAGICX_API_KEY"], base_url="https://aimagicx.vercel.app/api/v1")
reply = client.chat.completions.create(
model="claude-haiku-5-5",
messages=[{"role": "user", "content": "Summarise this in one line: ..."}],
extra_headers={"Idempotency-Key": str(uuid.uuid4())},
)
print(reply.choices[0].message.content, reply.usage.cost)The last chunk of a stream carries usage, including cost in mana. A repeated Idempotency-Key returns the finished completion as JSON.
Tools. Send OpenAI-style function tools (and optionally tool_choice). The model's calls come back in tool_calls with finish_reason: "tool_calls", streamed as deltas when stream is on. You run them and send each result as a role: "tool" message with its tool_call_id.
Images. Models with vision: true in GET /models take image_url parts (an https URL or a data:image/…;base64 URL up to 3.5 MB) and image_file parts with the id of an uploaded image.
Agent runs
A run plans, uses tools and answers. Choose tools with tools: web for search and reading pages, sandbox for code, files and charts. Runs never take actions that need a person's approval; those are declined and the agent carries on without them. Instead of asking for more budget, a run answers within what it reserved.
curl -N https://aimagicx.vercel.app/api/v1/runs/RUN_ID/events -H "Authorization: Bearer $MAGICX_API_KEY"
event: status
data: {"status":"running","steps":2,"tool_calls":3}
event: output
data: {"output":"Here's what I found…"}
event: done
data: {"id":"…","object":"run","status":"completed","output":"…","usage":{"cost":4.212}}The stream closes after 5 minutes; reconnect to keep following, or poll GET /runs/{id}. Files the run made are listed under files.
Media jobs
curl https://aimagicx.vercel.app/api/v1/media \
-H "Authorization: Bearer $MAGICX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"model":"gpt-image-2","input":{"prompt":"A paper crane on a desk, soft window light","aspect":"landscape","quality":"medium"}}'input takes the same settings as the Studio: prompt, aspect, quality, count, seconds, resolution, voice, style, speed, language, instrumental. Reference images and recordings are given by file id (referenceIds, sourceId): an uploaded file or the id of an earlier output. When a job is done, outputs have download links that last an hour; get the job again for fresh ones.
Files
Upload reference images (PNG, JPG, WebP, up to 20 MB) and recordings (MP3, M4A, WAV, OGG, FLAC, WebM, MP4, MOV, up to 25 MB). Ask for an upload URL, PUT the bytes to it, then complete the upload. Files under 4 MB can also go in one multipart request with a file field. Uploads count toward your plan's storage.
# 1. Ask for an upload URL
curl https://aimagicx.vercel.app/api/v1/files \
-H "Authorization: Bearer $MAGICX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"style.png","size":482113}'
# → {"object":"file.upload","id":"UPLOAD_ID","upload_url":"https://…","method":"PUT","headers":{"content-type":"image/png"}}
# 2. PUT the bytes
curl -X PUT "$UPLOAD_URL" -H "Content-Type: image/png" --data-binary @style.png
# 3. Complete it: the response is the file, with its id
curl -X POST https://aimagicx.vercel.app/api/v1/files/uploads/UPLOAD_ID/complete -H "Authorization: Bearer $MAGICX_API_KEY"
# Small files in one go
curl https://aimagicx.vercel.app/api/v1/files -H "Authorization: Bearer $MAGICX_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" -F "file=@style.png"Webhooks
Add an https endpoint in Settings or with POST /webhooks to hear about run.completed, run.failed, media.completed and media.failed. Each POST carries Magicx-Event, Magicx-Event-Id, Magicx-Delivery and Magicx-Signature: t=<unix>,v1=<hex>, where v1 is the HMAC-SHA256 of <t>.<raw body> with your endpoint's secret. Answer with any 2xx. We retry for about 7 hours, and one event is sent at most once per endpoint.
import crypto from "node:crypto";
export function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // older than 5 minutes
const want = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(want), Buffer.from(parts.v1 ?? ""));
}Use AI Magicx from your AI tools (MCP)
AI Magicx is also a remote MCP server, so Claude, ChatGPT, Cursor, VS Code and other MCP clients can use it as a set of tools. The server address is https://aimagicx.vercel.app/api/mcp(Streamable HTTP; protocol revisions 2025-11-25, 2025-06-18 and 2025-03-26).
- Clients that sign you in (claude.ai and Claude Desktop custom connectors, ChatGPT connectors): paste the address. The client registers itself, sends you to AI Magicx to sign in, and you choose the workspace, what it may do and a monthly limit. Remove it any time in Settings → Keys and API.
- Clients that take a key (Claude Code, Cursor, VS Code, scripts): send an API key as
Authorization: Bearer mx_live_…. Allow the Files scope if it should read your Library.
claude mcp add --transport http aimagicx https://aimagicx.vercel.app/api/mcp \
--header "Authorization: Bearer $MAGICX_API_KEY"{
"mcpServers": {
"aimagicx": {
"url": "https://aimagicx.vercel.app/api/mcp",
"headers": { "Authorization": "Bearer YOUR_AI_MAGICX_KEY" }
}
}
}Tools:
askany chat model (or Auto), with an optional effort level.start_task,get_task,cancel_task: agent tasks with web search and a code sandbox.create_image,create_video,get_media,create_voiceover,transcribe(a URL or a Library file),create_music,create_sound_effect.search_library,get_file,list_projects,list_models,quote,get_balance.
Your Library files and each project's knowledge are also available as MCP resources, and your Commands as MCP prompts. Every paid tool is charged from the API balance at API prices, exactly like the HTTP API, and each result says what it cost. Long tools send progress notifications when the client asks for them.
OAuth details for client builders: metadata at https://aimagicx.vercel.app/.well-known/oauth-authorization-server and https://aimagicx.vercel.app/.well-known/oauth-protected-resource/api/mcp; dynamic client registration, authorization code with PKCE (S256), refresh tokens that rotate (access tokens last an hour).
Errors and limits
Errors are JSON: {"error":{"type":"…","code":"…","message":"…"}}.
400invalid request,401missing, revoked or expired key,403missing scope or model not offered through the API.402not enough API balance, or past the key's monthly cap.409Idempotency-Key reused for a different request.429too many requests: 120 a minute per key, and 60 a minute for calls that start work. Wait forRetry-Afterseconds.
Every response has an x-request-id; include it when you write to support.