For developers

API reference

Start agent runs and media jobs from your own code, or use the OpenAI-compatible chat endpoint. Every call is paid from your workspace's prepaid API balance.

Quick start

  1. In Settings → Keys and API, make a key and add API balance. Keys are shown once.
  2. Send it as Authorization: Bearer mx_live_… to https://aimagicx.vercel.app/api/v1.
  3. Add an Idempotency-Key header (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.
Start a run (curl)
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

MethodPathKey scopeWhat it does
GET/modelsAnyModels with API prices
POST/quotesAnyEstimate and maximum for a chat call, run or media job
POST/chat/completionschatOpenAI-compatible chat: streaming, tools and images
POST/runsrunsStart an agent run
GET/runs/{id}runsRun status, answer, files and cost
GET/runs/{id}/eventsrunsFollow a run as server-sent events
POST/runs/{id}/cancelrunsStop a run
POST/mediamediaStart an image, video, voice, transcript, music or sound job
GET/media/{id}mediaJob status and download links
POST/filesmedia or chatUpload an image, recording or video
POST/files/uploads/{id}/completemedia or chatFinish an upload after the PUT
GET · DELETE/files/{id}media or chatA file with a download link, or delete it
GET/usageusageSpend by type and model for a period
GET/receiptsusageOne receipt per call, newest first
GET · POST/webhooksruns or mediaList or add webhook endpoints
DELETE/webhooks/{id}runs or mediaRemove an endpoint
GET/webhooks/{id}/deliveriesruns or mediaRecent deliveries
GET/openapi.jsonNoneOpenAPI 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.

JavaScript (openai)
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 ?? "");
Python (openai)
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.

Follow a run (curl)
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

Create media (curl)
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.

Upload a file (curl)
# 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.

Verify a signature (Node)
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 Code
claude mcp add --transport http aimagicx https://aimagicx.vercel.app/api/mcp \
  --header "Authorization: Bearer $MAGICX_API_KEY"
Cursor · .cursor/mcp.json
{
  "mcpServers": {
    "aimagicx": {
      "url": "https://aimagicx.vercel.app/api/mcp",
      "headers": { "Authorization": "Bearer YOUR_AI_MAGICX_KEY" }
    }
  }
}

Tools:

  • ask any 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":"…"}}.

  • 400 invalid request, 401 missing, revoked or expired key, 403 missing scope or model not offered through the API.
  • 402 not enough API balance, or past the key's monthly cap. 409 Idempotency-Key reused for a different request.
  • 429 too many requests: 120 a minute per key, and 60 a minute for calls that start work. Wait for Retry-After seconds.

Every response has an x-request-id; include it when you write to support.