Quick start
- The API is included on the Pro and Max plans. In Settings → Keys and API, make a key and add API balance. Keys are shown once.
- Send it as
Authorization: Bearer mx_live_…tohttps://www.aimagicx.com/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://www.aimagicx.com/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"]}'Keys and scopes
Workspace owners and admins make keys. Each key belongs to one workspace and has the scopes you choose, an optional monthly spending cap and an optional expiry date. You can revoke a key at any time. A key stops working if the person who made it is no longer an owner or admin of the workspace, or if the workspace moves to the Free plan.
| Scope | What it allows |
|---|---|
| chat | Chat completions, and the MCP ask tool |
| runs | Agent runs, and the MCP task tools |
| media | Media jobs, and the MCP media tools |
| usage | Usage and receipts |
| files | MCP only: read your Library, projects and project knowledge |
GET /models and POST /quotes work with any key. Files need the media or chat scope, and webhooks need runs or media.
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, sound or voice cleanup 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 API price, and POST /quotes returns the estimate, the most a call can cost and your current API balance. That maximum is reserved before the work runs, and you're charged for what was actually used. If a call fails before any work is done, it costs nothing; work that was already done, such as a stopped run or a partial result, is charged for what it used. Every call has a receipt.
API calls are paid from API top-ups, from top-up mana bought in the app and from Legacy plan mana, never from other plans' monthly mana, gifts or promotional mana. API top-ups are bought in Settings → Keys and API and can only be spent through the API and MCP: $10.00 for 1,000 mana, $50.00 for 5,000 mana, $200.00 for 20,000 mana, each valid for 12 months. 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://www.aimagicx.com/api/v1" });
const stream = await client.chat.completions.create(
{ model: "gpt-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://www.aimagicx.com/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://www.aimagicx.com/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://www.aimagicx.com/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. Transcripts are returned in text.
A new job starts as queued and waits its turn with your workspace's other media work; your plan sets how many jobs run at once. The balance is reserved when the job starts running, after your key, scopes, plan and the quote are checked again. Poll GET /media/{id} or add a webhook to hear when it finishes.
Voice cleanup. The voice cleanup model removes background noise from a recording and keeps the speech. Its sourceId must be a recording in your Library that has been prepared in the Studio, or the output of an earlier cleanup, so its length is known before the price is set. The price is per minute of that recording.
Standard, Batch and Flex
Interactive requests use Standard processing. In the app, the batch workspace can group independent text tasks and use lower-cost Batch or Flex routes where the selected model supports them. Results may arrive later; the selected mode, estimate and maximum are shown before starting. API and app funding stay separate.
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://www.aimagicx.com/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://www.aimagicx.com/api/v1/files/uploads/UPLOAD_ID/complete -H "Authorization: Bearer $MAGICX_API_KEY"
# Small files in one go
curl https://www.aimagicx.com/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. Failed deliveries are retried after 30 seconds, 2 minutes, 10 minutes, 1 hour and 6 hours, then marked failed; GET /webhooks/{id}/deliveries shows recent attempts. One event is delivered at most once per endpoint. A workspace can have up to 10 endpoints, and the signing secret is shown only when the endpoint is created.
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://www.aimagicx.com/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://www.aimagicx.com/api/mcp \
--header "Authorization: Bearer $MAGICX_API_KEY"{
"mcpServers": {
"aimagicx": {
"url": "https://www.aimagicx.com/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://www.aimagicx.com/.well-known/oauth-authorization-server and https://www.aimagicx.com/.well-known/oauth-protected-resource/api/mcp; dynamic client registration, authorization code with PKCE (S256), refresh tokens that rotate and last 30 days (access tokens last an hour).
Errors and limits
Errors are JSON: {"error":{"type":"…","code":"…","message":"…"}}.
400invalid request, including a missingIdempotency-Keyon a call that starts work.401missing, unknown, revoked or expired key.403missing scope, a workspace that isn't on a plan with the API, a key whose maker can no longer manage keys, or a model not offered through the API.402not enough API balance or storage, or past the key's monthly cap.404unknown id or endpoint.409anIdempotency-Keyreused for a different request, or the first request with that key is still running. A repeated request with the same key and body returns the first result for 24 hours.413a JSON body over 4 MB.503a model that is paused or no longer available.500something went wrong on our side.429too many requests: 120 a minute per key (bursts up to 60), and 60 a minute for calls that start work (bursts up to 20). Also returned when your plan's limit on tasks or media jobs running at once is reached. Wait forRetry-Afterseconds when it's sent.
Every response has an x-request-id; include it when you write to support.