API & CLI — code examples

Practical recipes for integrating MatrixAI into your own code. Each section shows a complete, runnable example — Python, curl, and CLI — covering the full development workflow from training to production.

Prerequisites: Studio running (see Up and running in 5 minutes). For production serving and CLI tools, you also need the matrixai package — it is pre-installed inside the Studio Docker container. Run CLI commands with docker exec matrixai matrixai <command>.
SetupAuth & healthPredictTrain (CLI)RegistryToolingRefinementTest index

012 min

Setup — two ways to access the API

MatrixAI exposes two HTTP surfaces that you interact with from code:

  • Studio API — the web interface backend, accessible at http://localhost:8080/api/ when Studio is running. Use this for training jobs, playground, and model management from the browser or scripts.
  • Production serve API — a dedicated lightweight server you start with matrixai serve after training. This is what your application calls in production.

Start a production server from a trained model:

# Inside the Studio container (models live in /data/):
docker exec matrixai matrixai serve /data/my_model.mxai \
  --params /data/my_model_params.json \
  --api-key "$(openssl rand -hex 20)" \
  --port 9000 \
  --host 0.0.0.0
Map port 9000 in your Docker Compose if you want to call it from outside the container: add - "9000:9000" under matrixai: ports: in docker-compose.yml.

Or run it locally if you have pip install matrixai-core:

matrixai serve model.mxai --params params.json --api-key secret123 --port 9000
025 min

Auth & health check

All write endpoints require Authorization: Bearer <api-key>. The key is set when you start the server. You can also supply a read-only key for prediction-only clients.

# curl — health (no auth needed)
curl http://localhost:9000/api/v1/health
# → {"ok": true}

# curl — predict with auth
curl -X POST http://localhost:9000/api/v1/predict \
  -H "Authorization: Bearer secret123" \
  -H "Content-Type: application/json" \
  -d '{"features": [0.7, 1.2, 0.3, 2.1]}'

Python client setup (reuse this in every recipe):

import requests

BASE    = "http://localhost:9000"
API_KEY = "secret123"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

# Health check
r = requests.get(f"{BASE}/api/v1/health")
r.raise_for_status()
print(r.json())  # {"ok": true}

Two-key setup — read-only key for prediction clients, write key for CI:

matrixai serve model.mxai \
  --api-key "write-key-here"      \  # full access
  --api-key-read "read-only-key"  \  # predictions only
  --port 9000
A write key works on all endpoints including read ones. A read-only key is rejected on write operations (registry push, execute-action) with a 403.

Error schema — every error response has the same shape:

{
  "error":   true,
  "code":    "UNAUTHORIZED",
  "message": "Missing or invalid Authorization header"
}
0310 min

Single & batch predictions

POST /api/v1/predict accepts either a single object or an array. Sending an array returns a list of results in the same order.

Single prediction:

import requests

def predict(features: list[float]) -> dict:
    r = requests.post(
        f"{BASE}/api/v1/predict",
        headers=HEADERS,
        json={"features": features},
        timeout=10,
    )
    r.raise_for_status()
    return r.json()

result = predict([0.7, 1.2, 0.3, 2.1])
print(result)
# → {"prediction": "spam", "confidence": 0.94, "probabilities": {"spam": 0.94, "not_spam": 0.06}}

Batch prediction:

def predict_batch(rows: list[list[float]]) -> list[dict]:
    payload = [{"features": f} for f in rows]
    r = requests.post(
        f"{BASE}/api/v1/predict",
        headers=HEADERS,
        json=payload,
        timeout=30,
    )
    r.raise_for_status()
    return r.json()

results = predict_batch([
    [0.7, 1.2, 0.3, 2.1],
    [1.5, 0.8, 1.1, 0.4],
    [2.3, 0.2, 0.9, 1.8],
])
# → [{"prediction": "spam", ...}, {"prediction": "not_spam", ...}, ...]

Robust client with error handling:

import requests
from requests.exceptions import HTTPError, Timeout

class MatrixAIClient:
    def __init__(self, base_url: str, api_key: str):
        self.base = base_url.rstrip("/")
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        })

    def health(self) -> bool:
        try:
            r = self.session.get(f"{self.base}/api/v1/health", timeout=5)
            return r.ok and r.json().get("ok") is True
        except Exception:
            return False

    def predict(self, features: list[float]) -> dict:
        r = self.session.post(
            f"{self.base}/api/v1/predict",
            json={"features": features},
            timeout=10,
        )
        if r.status_code == 401:
            raise PermissionError("Invalid API key")
        if r.status_code == 422:
            raise ValueError(f"Bad payload: {r.json()}")
        r.raise_for_status()
        return r.json()

    def predict_batch(self, rows: list[list[float]]) -> list[dict]:
        payload = [{"features": f} for f in rows]
        r = self.session.post(
            f"{self.base}/api/v1/predict",
            json=payload,
            timeout=60,
        )
        r.raise_for_status()
        return r.json()


# Usage
client = MatrixAIClient("http://localhost:9000", "secret123")
assert client.health(), "Server not reachable"
print(client.predict([0.7, 1.2, 0.3, 2.1]))

Available endpoints at a glance:

MethodPathDescription
GET/api/v1/healthLiveness check — no auth required
POST/api/v1/predictSingle or batch inference
GET/api/v1/registryList models in registry
POST/api/v1/registry/pushPush a trained model to registry
GET/api/v1/registry/:name/:verPull a specific model version
POST/api/v1/registry/:name/:ver/predictPredict from a registry model
DELETE/api/v1/registry/:name/:verRemove a model version
POST/execute-actionRun an audited action (requires --contract)
GET/openapi.jsonOpenAPI spec
GET/docsInteractive API docs
0410 min

Train a model via CLI

The training workflow lives in the CLI. Use docker exec to run it inside the Studio container where your models and data are stored.

Step 1 — generate a model from a prompt:

# Generates model.mxai + model.mxtrain template inside the container
docker exec matrixai matrixai generate supervised \
  "classify emails as spam or not spam based on word count, link count, sender score and hour sent"

# Output files (inside container at /data/):
#   my_model.mxai    — model architecture
#   my_model.mxtrain — training configuration

Step 2 — train with your CSV:

# Copy your data into the container
docker cp emails.csv matrixai:/data/emails.csv

# Train
docker exec matrixai matrixai train supervised \
  --model /data/my_model.mxai \
  --dataset /data/emails.csv

# Output files written to the same directory:
#   params.json          — trained weights
#   training_trace.json  — epoch losses, best epoch, backend info
#   evaluation_report.json — accuracy / confusion matrix

Step 3 — evaluate on a hold-out set:

docker exec matrixai matrixai evaluate \
  --model /data/my_model.mxai \
  --params /data/params.json \
  --dataset /data/test_emails.csv

# JSON output:
# {
#   "accuracy": 0.94,
#   "confusion_matrix": [[480, 20], [12, 488]],
#   "rows": 1000,
#   "is_regression": false
# }
For regression models, the metrics are mae, rmse, and r2 instead of accuracy.

Read training output from Python:

import json, subprocess

# Read training_trace.json from the container
result = subprocess.run(
    ["docker", "exec", "matrixai", "cat", "/data/training_trace.json"],
    capture_output=True, text=True, check=True,
)
trace = json.loads(result.stdout)

print(f"Best epoch: {trace['best_epoch']}")
print(f"Final loss: {trace['epochs'][-1]['loss']:.4f}")
print(f"Backend: {trace['backend']}")

Generate a synthetic dataset (useful when you don't have data yet):

docker exec matrixai matrixai generate-dataset \
  --model /data/my_model.mxai \
  --training /data/my_model.mxtrain \
  --rows 500 \
  --seed 42 \
  --mode coherent       # or: random (pure noise)

# Writes emails_synthetic.csv + manifest with origin=synthetic
0510 min

Model registry — push, list, pull

The registry versioned model store. Push trained models after evaluation, pull them from any environment, and serve directly from registry without copying files around.

Push a trained model:

# CLI
docker exec matrixai matrixai registry push my-spam-detector \
  --run-dir /data/          # directory containing params.json + training_trace.json

# HTTP equivalent
curl -X POST http://localhost:9000/api/v1/registry/push \
  -H "Authorization: Bearer secret123" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-spam-detector", "run_dir": "/data/"}'

List and inspect models:

# List all models
docker exec matrixai matrixai registry list
docker exec matrixai matrixai registry list --json      # machine-readable
docker exec matrixai matrixai registry list --name spam  # filter by name prefix

# Show full manifest
docker exec matrixai matrixai registry show my-spam-detector

# Verify integrity (exit 0 = OK, non-zero = tampered)
docker exec matrixai matrixai registry verify my-spam-detector

Python — list and pull via HTTP:

import requests

BASE    = "http://localhost:9000"
HEADERS = {"Authorization": "Bearer secret123"}

# List models
r = requests.get(f"{BASE}/api/v1/registry", headers=HEADERS)
models = r.json()   # [{name, version, model_hash, ...}, ...]
print(f"Registry has {len(models)} model(s)")

# Pull a specific version
r = requests.get(f"{BASE}/api/v1/registry/my-spam-detector/1.0", headers=HEADERS)
manifest = r.json()

# Predict directly from registry (no local file needed)
r = requests.post(
    f"{BASE}/api/v1/registry/my-spam-detector/1.0/predict",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"features": [0.7, 1.2, 0.3, 2.1]},
)
print(r.json())

Compare two model versions:

docker exec matrixai matrixai registry diff \
  my-spam-detector/1.0 \
  my-spam-detector/2.0

# Shows: architecture changes, parameter delta, evaluation metric differences

Serve a model from registry directly (no --params needed):

docker exec matrixai matrixai serve \
  --registry /data/registry \
  --api-key secret123 \
  --port 9000
068 min

Model tooling — lint, format, graph, diagnose

The CLI ships a full toolchain for inspecting and maintaining model files. All commands accept --json for machine-readable output.

Lint — catch model errors before serving:

docker exec matrixai matrixai lint /data/my_model.mxai
# → OK  my_model.mxai

docker exec matrixai matrixai lint /data/my_model.mxai --json
# → {"ok": true, "errors": [], "warnings": []}

# Use in CI to block bad models:
docker exec matrixai matrixai lint /data/my_model.mxai && echo "PASS" || echo "FAIL"

Format — normalize and check formatting:

# Auto-format in place
docker exec matrixai matrixai format /data/my_model.mxai

# Check only (CI-safe, no writes)
docker exec matrixai matrixai format /data/my_model.mxai --check
# exits non-zero if file is not formatted

Graph — visualise model architecture:

# Print as Mermaid diagram
docker exec matrixai matrixai graph /data/my_model.mxai --mermaid

# JSON graph (nodes + edges)
docker exec matrixai matrixai graph /data/my_model.mxai --json

# Pipe Mermaid to a file for documentation
docker exec matrixai matrixai graph /data/my_model.mxai --mermaid > model_graph.md

Diagnose — runtime vs compiled output check:

docker exec matrixai matrixai diagnose /data/my_model.mxai
docker exec matrixai matrixai diagnose /data/my_model.mxai --json
# Catches mismatches between the IR and what the runtime actually computes.
# Useful after manual edits to a .mxai file.

Python — run lint as part of a model deployment pipeline:

import subprocess, json

def lint_model(container: str, model_path: str) -> dict:
    result = subprocess.run(
        ["docker", "exec", container,
         "matrixai", "lint", model_path, "--json"],
        capture_output=True, text=True,
    )
    return json.loads(result.stdout)

report = lint_model("matrixai", "/data/my_model.mxai")
if not report["ok"]:
    for err in report["errors"]:
        print(f"ERROR: {err}")
    raise RuntimeError("Model lint failed — blocking deployment")
078 min

LLM refinement — matrixai refine

Requires LLM mode. Set your API key in Studio Settings before using these commands. The matrixai refine command uses the LLM to propose architecture or prompt changes based on an evaluation report.

After training and evaluating a model, you can ask the LLM to improve it. Refinement takes an audit report (from matrixai evaluate) or anevaluation file and proposes changes.

Audit-driven refinement (most common):

# Basic: propose changes based on evaluation report
docker exec matrixai matrixai refine \
  "improve precision on the spam class" \
  --audit /data/evaluation_report.json

# Accept the proposal and write output files
docker exec matrixai matrixai refine \
  "improve precision on the spam class" \
  --audit /data/evaluation_report.json \
  --accept \
  --output-mxai /data/my_model_v2.mxai \
  --output-chain /data/chain.json

# Add a hint to guide the refinement
docker exec matrixai matrixai refine \
  "improve accuracy" \
  --audit /data/evaluation_report.json \
  --hint "the model struggles with short emails under 50 words" \
  --accept \
  --output-mxai /data/my_model_v2.mxai

Metric-driven refinement:

docker exec matrixai matrixai refine \
  "bring R² above 0.92 on the validation set" \
  --evaluation /data/evaluation_report.json

Multi-iteration refinement loop:

# Iteration 1
docker exec matrixai matrixai refine "improve F1 score" \
  --audit /data/eval_v1.json \
  --iteration 1 --max-iterations 5 \
  --accept \
  --output-mxai /data/model_v2.mxai \
  --output-chain /data/chain.json

# Retrain v2, evaluate, then iteration 2
docker exec matrixai matrixai train supervised \
  --model /data/model_v2.mxai --dataset /data/emails.csv

docker exec matrixai matrixai evaluate \
  --model /data/model_v2.mxai --params /data/params.json \
  --dataset /data/test.csv > /data/eval_v2.json

# Iteration 2 — chain file carries context from iteration 1
docker exec matrixai matrixai refine "continue improving F1" \
  --audit /data/eval_v2.json \
  --chain /data/chain.json \
  --iteration 2 --max-iterations 5 \
  --accept \
  --output-mxai /data/model_v3.mxai \
  --output-chain /data/chain_v2.json

Read prompt from stdin (useful in scripts):

echo "increase recall above 0.95 for class spam" | \
  docker exec -i matrixai matrixai refine - \
    --audit /data/evaluation_report.json \
    --accept \
    --output-mxai /data/model_refined.mxai
The output JSON from matrixai refine includes refinement_id, parent_hash, chain, and hints_applied. These fields form an audit trail linking each model version to the prompt that produced it.

Test suite — 19,625 tests

Grouped breakdown of the 42 functional sections covered by the test suite.

Download TEST_INDEX.md

CORE — 9,218 tests

Types and primitives
LayerKind, ActivationKind, Loss, Optimizer, float literals
Parameters
Parameter validation, bounds, defaults
Layers and call_layer
Layer construction, call semantics, stacking
Lowering and compilation
IR lowering, compiler pipeline, code generation
Backend Contract
stdlib and PyTorch backend interfaces
Parser and IR — Dense
Dense network parser and IR serialization (P18)
Parser and IR — Composite
Multi-network parser and IR (P19)
Shape inference and manifests
Tensor shape propagation, manifest generation
Forward pass Dense
Dense network forward computation
Forward pass Composite
Composite network forward computation
Backpropagation
Gradient computation, autograd
Training
Full training loop, scheduler, convergence
PyTorch
GPU-accelerated training via PyTorch backend
Evaluation and metrics
Accuracy, MAE, RMSE, R², confusion matrix
Network generators
DenseNetworkGenerator, LLM architect
Synthetic data
Dataset generation, coherent/random modes, S2 schema
ONNX and export
ONNX export, WASM compilation, cross-platform
Real actions (P20)
Real-action contract, dry-run, sandbox, HMAC traces
Registro de modelos (P21)
Registry push/pull/list, versioning, signing
Aprendizaje continuo (P22)
Drift detection, concept drift, continual policy
CLI y tooling
matrixai lint, format, graph, diagnose, refine
Playground
Training jobs API, prediction engine, job status
Refinamiento
LLM-driven refinement, audit/metric-driven loops
LLM y multiprovider
OpenAI/Anthropic/Gemini integration, fallback
Seguridad y sandbox
Sandbox permissions, scope enforcement, risk
Deployment y producción
matrixai serve, /api/v1 contract, two-key auth
Snapshots y regresión
Output stability snapshots, IR serialization freeze
Otros
Integration, CLI E2E, cross-cutting regression

STUDIO — 6,542 tests

Runtime y dispatch
Studio request routing and dispatch layer
Scaffolding y generación
Studio type system, guided cases, model generation
Playground y modelos
Web playground training, job management, predict
P18 Studio
Dense network UI flow, model creation from prompt
P19 Studio
Composite architectures in the Studio UI
P20 Studio y servidor
Action contract UI, execute-action endpoint
P21 CLI Studio
Registry CLI from Studio, studio view, workbench
P22 CLI continuo
Continuous learning CLI integration
Exportación y configuración
Export formats, settings persistence
Infraestructura
License validation, health checks, activation flow
Routing y persistencia
API routing, data persistence, model storage
Tipos de datos y campos
Field types, one-hot encoding, date/id fields, S2
Escala de dominio
Domain scaling, large dataset handling
Smoke tests
End-to-end integration smoke tests

Go deeper

REST API reference
Complete endpoint documentation with all parameters and response schemas.
CLI reference
Every subcommand explained — serve, train, evaluate, registry, refine, and more.
Math functions
Every function MatrixAI can execute in a model — arithmetic, probability, semantic.
Studio tour
Visual walkthrough of the Studio UI from first prompt to trained model.