API Reference

Programmatic access to XMOX transcription and AI analysis.

Enterprise plan required  ·  Get API key →

Overview

The XMOX REST API lets you upload audio files, poll for transcription status, retrieve full transcripts, ask natural-language questions about audio content, and delete jobs — all programmatically.

API access requires an active Enterprise subscription. Create and manage API keys from your API Keys page.

Base URL

Base URL https://xmox.ai/api/external/v1

Authentication

Pass your API key in the X-API-Key header on every request. Keys are shown only once when created — store them in a secrets manager or environment variable.

X-API-Key: xm_your_api_key_here
{ "success": false, "error": "Invalid or missing API key." }
{ "success": false, "error": "API access requires an Enterprise subscription." }

Endpoints

POST /process Upload an audio or video file to start a transcription job. Returns a <code>job_id</code> immediately; poll the status endpoint to check when it finishes.

Upload an audio or video file to start a transcription job. Returns a job_id immediately; poll the status endpoint to check when it finishes.

HeaderValue
X-API-Key string requiredrequired
Content-Type multipart/form-data requiredrequired
FieldTypeDescription
file binary Audio or video file (MP3, WAV, M4A, FLAC, OGG, OPUS, MP4, MOV, WEBM, MKV). Max 500 MB. required
curl -X POST https://xmox.ai/api/external/v1/process \ -H "X-API-Key: xm_your_key" \ -F "file=@meeting.mp3"
{ "success": true, "job_id": 4821, "status": "processing" }
  • 202Job created; use job_id to poll for completion.
  • 400Missing or empty file.
  • 402Monthly quota reached.
  • 401Invalid API key.
  • 403Not on Enterprise plan.
GET /jobs/{job_id} Retrieve the current status and metadata of a transcription job.

Retrieve the current status and metadata of a transcription job.

ParameterTypeDescription
job_id integer ID returned by POST /process. required
curl https://xmox.ai/api/external/v1/jobs/4821 \ -H "X-API-Key: xm_your_key"
{ "success": true, "job": { "job_id": 4821, "status": "completed", /* processing | completed | failed */ "filename": "meeting.mp3", "duration_s": 3642, "created_at": "2026-07-27T09:14:22Z" } }
  • 200Job found. Check job.status: processing — transcription in progress, completed — transcript ready, failed — see error field.
  • 404Job not found or belongs to a different account.
GET /jobs/{job_id}/transcript Retrieve the full transcript text of a completed job.

Retrieve the full transcript text of a completed job.

ParameterTypeDescription
job_id integer ID of a completed job. required
curl https://xmox.ai/api/external/v1/jobs/4821/transcript \ -H "X-API-Key: xm_your_key"
{ "success": true, "job_id": 4821, "transcript": "Good morning everyone. Today we'll be reviewing..." }
  • 200Transcript text returned in transcript field.
  • 400Job is not yet completed or has no transcript.
  • 404Job not found.
POST /jobs/{job_id}/question Ask a natural-language question about a completed job. The AI reads the transcript and returns a concise answer.

Ask a natural-language question about a completed job. The AI reads the transcript and returns a concise answer.

FieldTypeDescription
question string Natural-language question about the audio content. required
curl -X POST https://xmox.ai/api/external/v1/jobs/4821/question \ -H "X-API-Key: xm_your_key" \ -H "Content-Type: application/json" \ -d '{"question": "What action items were agreed upon?"}'
{ "success": true, "job_id": 4821, "answer": "Three action items were agreed upon: (1) Alice will send the revised proposal by Friday..." }
  • 200AI answer returned in answer field.
  • 400Missing question field, or job not yet completed.
  • 404Job not found.
DELETE /jobs/{job_id} Permanently delete a job and its associated audio file and transcript.

Permanently delete a job and its associated audio file and transcript.

ParameterTypeDescription
job_id integer ID of the job to delete. required
curl -X DELETE https://xmox.ai/api/external/v1/jobs/4821 \ -H "X-API-Key: xm_your_key"
{ "success": true, "message": "Job deleted." }
  • 200Job and all associated data deleted.
  • 404Job not found.

Error Codes

All error responses share the same shape. The HTTP status code indicates the class of error; the error field contains a human-readable message.

{ "success": false, "error": "Human-readable description of what went wrong." }
HTTP Status Meaning
400 Bad request — missing required field or invalid value.
401 Unauthorized — API key missing, invalid, or revoked.
402 Quota error (402): returned when you have reached the monthly file or minute limit for your plan.
403 Forbidden — account does not have an active Enterprise plan.
404 Not found — the job does not exist or belongs to a different account.
500 Server error — unexpected failure; retry with exponential back-off.

Claude Code & MCP Integration

Enterprise subscribers can connect Claude Code agents directly to XMOX using the official xmox-mcp npm package — an MCP (Model Context Protocol) server that exposes all five API endpoints as native Claude tools.

Install the package once, add your API key to the config, and Claude agents can process_audio, get_job_status, get_transcript, ask_question, and delete_job without writing any code.

npx xmox-mcp
{ "mcpServers": { "xmox": { "command": "npx", "args": ["xmox-mcp"], "env": { "XMOX_API_KEY": "your_api_key_here" } } } }
ToolAPI endpoint
process_audioPOST /api/external/v1/process
get_job_statusGET /api/external/v1/jobs/{job_id}
get_transcriptGET /api/external/v1/jobs/{job_id}/transcript
ask_questionPOST /api/external/v1/jobs/{job_id}/question
delete_jobDELETE /api/external/v1/jobs/{job_id}

Direct REST API (Custom Agents)

If your agent runs inside an MCP-compatible host — including Claude, Cursor, OpenAI Agents SDK, or Gemini — use the xmox-mcp package above. If you are building a custom agent without MCP support, or simply prefer direct HTTP calls, use the REST API below. The API is provider-agnostic: pass your key in the X-API-Key header and use standard HTTP.

import requests, time API_KEY = "your_api_key_here" BASE = "https://api.xmox.ai/api/external/v1" HEADERS = {"X-API-Key": API_KEY} # 1. Upload with open("recording.mp3", "rb") as f: r = requests.post(f"{BASE}/process", headers=HEADERS, files={"file": f}) job_id = r.json()["job_id"] # 2. Poll until done while True: status = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS).json()["job"]["status"] if status == "completed": break if status == "failed": raise RuntimeError("Transcription failed") time.sleep(5) # 3. Get transcript transcript = requests.get(f"{BASE}/jobs/{job_id}/transcript", headers=HEADERS).json()["transcript"] # 4. Ask a question answer = requests.post( f"{BASE}/jobs/{job_id}/question", headers=HEADERS, json={"question": "Was the customer satisfied?"} ).json()["answer"]
const API_KEY = "your_api_key_here"; const BASE = "https://api.xmox.ai/api/external/v1"; const headers = { "X-API-Key": API_KEY }; // 1. Upload const form = new FormData(); form.append("file", fs.createReadStream("recording.mp3")); const { job_id } = await fetch(`${BASE}/process`, { method: "POST", headers, body: form }).then(r => r.json()); // 2. Poll until done let status; do { await new Promise(r => setTimeout(r, 5000)); ({ status } = (await fetch(`${BASE}/jobs/${job_id}`, { headers }).then(r => r.json())).job); } while (status === "processing" || status === "pending"); // 3. Get transcript const { transcript } = await fetch(`${BASE}/jobs/${job_id}/transcript`, { headers }).then(r => r.json()); // 4. Ask a question const { answer } = await fetch(`${BASE}/jobs/${job_id}/question`, { method: "POST", headers: { ...headers, "Content-Type": "application/json" }, body: JSON.stringify({ question: "Was the customer satisfied?" }) }).then(r => r.json());