Skip to content

Matricxon API

Matricxon serves an HTTP API on port 8420, with JSON requests and streamed replies. The examples below use curl against a local server:

Terminal window
export MATRICXON_URL=http://localhost:8420
Endpoint Notes
POST /api/chat Streaming NDJSON chat, with tools and images. A request_id lets you cancel just this reply
POST /api/generate Raw-prompt completion, no chat template
POST /api/embeddings, POST /api/embed Mean-pooled, L2-normalized vectors (single and list input)
POST /api/rerank Scores documents against a query with a reranker model
Terminal window
curl -N $MATRICXON_URL/api/chat \
-H 'Content-Type: application/json' \
-d '{
"model": "hf.co/unsloth/Llama-3.2-3B-Instruct-GGUF:Llama-3.2-3B-Instruct-Q3_K_M",
"messages": [
{"role": "system", "content": "Answer in one sentence."},
{"role": "user", "content": "What is a GGUF file?"}
],
"options": {"temperature": 0.7, "num_ctx": 4096}
}'

The reply streams as one JSON object per line. The last line has "done": true and the timings, in nanoseconds:

{"message":{"content":"A GGUF"},"done":false}
{"message":{"content":" file is"},"done":false}
...
{"message":{"content":""},"done":true,"prompt_eval_count":31,"eval_count":24,"total_duration":5120000000}
  • -N turns off curl’s buffering, so the words appear as they arrive.
  • Replies always stream. "stream": false is accepted but not supported yet.
  • options: temperature (0.8), top_p (0.9), top_k (40), repeat_penalty (1.1), num_ctx (2048), num_predict (-1, no limit) and seed. Defaults in brackets.
  • A model the server hasn’t loaded yet loads on the first call, which can take a while on a CPU.

keep_alive is a whole number of seconds (Ollama’s "5m" form is not accepted). It applies to this model from this call on. Without it, the server’s default applies.

Terminal window
# Load the model and keep it for 24 hours, without generating anything
curl $MATRICXON_URL/api/generate -H 'Content-Type: application/json' \
-d '{"model": "hf.co/unsloth/Llama-3.2-3B-Instruct-GGUF:Llama-3.2-3B-Instruct-Q3_K_M", "keep_alive": 86400}'
# Unload it now: no messages and keep_alive 0
curl $MATRICXON_URL/api/chat -H 'Content-Type: application/json' \
-d '{"model": "hf.co/unsloth/Llama-3.2-3B-Instruct-GGUF:Llama-3.2-3B-Instruct-Q3_K_M", "messages": [], "keep_alive": 0}'

Give a reply your own request_id. The same empty call with that id stops only that reply: the model stays loaded and other users’ replies go on.

Send "model_role": "vision" when the model is used only to read an image (pAIring’s default vision model). It then doesn’t count toward MATRICXON_MAX_LOADED_MODELS, like embedding and reranker models, so it never unloads a chat model.

Terminal window
curl -N $MATRICXON_URL/api/chat -H 'Content-Type: application/json' \
-d '{"model": "hf.co/unsloth/Llama-3.2-3B-Instruct-GGUF:Llama-3.2-3B-Instruct-Q3_K_M",
"messages": [{"role": "user", "content": "Write a long story."}],
"request_id": "reply-42"}'
# From another terminal
curl $MATRICXON_URL/api/chat -H 'Content-Type: application/json' \
-d '{"model": "hf.co/unsloth/Llama-3.2-3B-Instruct-GGUF:Llama-3.2-3B-Instruct-Q3_K_M",
"messages": [], "keep_alive": 0, "request_id": "reply-42"}'

Sends the prompt as written, without the model’s chat template:

Terminal window
curl -N $MATRICXON_URL/api/generate -H 'Content-Type: application/json' \
-d '{"model": "hf.co/unsloth/Llama-3.2-3B-Instruct-GGUF:Llama-3.2-3B-Instruct-Q3_K_M",
"prompt": "The three primary colors are", "options": {"num_predict": 20}}'

Each line carries a response piece instead of message.

Terminal window
curl $MATRICXON_URL/api/embed -H 'Content-Type: application/json' \
-d '{"model": "hf.co/leliuga/all-MiniLM-L6-v2-GGUF:Q8_0", "input": ["first text", "second text"]}'
{"embeddings": [[-0.0184, 0.0551, 0.0097, ...], [...]]}

/api/embed takes one text or a list and returns embeddings. The older /api/embeddings takes one prompt and returns one embedding.

Orders documents by how well they answer a query, for example the results of a knowledge-base search:

Terminal window
curl $MATRICXON_URL/api/rerank -H 'Content-Type: application/json' \
-d '{"model": "hf.co/ggml-org/Qwen3-Reranker-0.6B-Q8_0-GGUF:Q8_0",
"query": "How do I run a model on a CPU?",
"documents": ["Matricxon runs GGUF models on an ordinary CPU.", "Bananas are rich in potassium."],
"top_n": 2}'
{"model":"hf.co/ggml-org/Qwen3-Reranker-0.6B-Q8_0-GGUF:Q8_0",
"results":[{"index":0,"relevance_score":0.9976,"document":null},
{"index":1,"relevance_score":0.00004,"document":null}]}

index points into your documents list. Add "return_documents": true to get each text back. Up to 1000 documents per call.

Endpoint Notes
POST /api/pull Downloads hf.co/<repo>:<file> from Hugging Face with progress and a sha256 check. Admin
GET /api/tags, POST /api/show, GET /api/ps Installed models with their capabilities, model details, loaded models with expiry
DELETE /api/delete, POST /api/copy, POST /api/create Remove, duplicate, re-tag (create supports only FROM <tag>). Admin
POST /api/infer-capabilities Matricxon-only: what a file would be able to do, before it is downloaded
POST /api/push Always refused. Matricxon has no registry to push to

Pulling resolves only hf.co/<repo>:<file> tags.

Terminal window
# What is installed, and what each model can do
curl $MATRICXON_URL/api/tags
# One model's details, with the RAM it needs
curl $MATRICXON_URL/api/show -H 'Content-Type: application/json' \
-d '{"model": "hf.co/leliuga/all-MiniLM-L6-v2-GGUF:Q8_0"}'
{"capabilities":["embedding"],"details":{"family":"bert","parameter_size":"unknown","context_length":512},"estimated_ram_gb":0.05}
Terminal window
# What is loaded now, and when each model unloads
curl $MATRICXON_URL/api/ps
{"models":[{"name":"hf.co/leliuga/all-MiniLM-L6-v2-GGUF:Q8_0","size":25008064,"size_vram":0,"expires_at":"2026-10-20T05:50:43+00:00"}]}

Capabilities are completion, tools, vision, embedding and rerank. Pull, delete, copy and create are admin calls (signed when a secret is set, below):

Terminal window
mx_admin POST /api/pull '{"model": "hf.co/leliuga/all-MiniLM-L6-v2-GGUF:Q8_0"}'
mx_admin POST /api/copy '{"source": "hf.co/leliuga/all-MiniLM-L6-v2-GGUF:Q8_0", "destination": "minilm"}'
mx_admin DELETE /api/delete '{"model": "minilm"}'

A pull streams its progress, one JSON line per step (status, then completed and total bytes while downloading).

Endpoint Notes
GET /api/health Matricxon-only: supported architectures, quantizations, MoE and vision lists
GET /api/version Version string
GET /api/storage Matricxon-only: each storage folder, its role, size and free space
PUT /api/runtime-settings Matricxon-only: change settings without a restart. Admin
Terminal window
curl $MATRICXON_URL/api/version
# {"version":"0.1.0"}
# Keep models loaded for 24 hours after their last use, from now on
mx_admin PUT /api/runtime-settings '{"default_keep_alive_seconds": 86400}'
# {"applied_now":["default_keep_alive_seconds"],"applied_next_load":[]}

A live change lasts until the server restarts. To keep it, also set it in .env (see Configuration).

See Prompt cache.

Endpoint Notes
GET /api/cache/persistence Show the limits and how much is stored
PUT /api/cache/persistence Change enabled, budget_mb or ttl_hours. Admin
DELETE /api/cache/persistence Delete every saved cache. Admin
DELETE /api/cache/persistence/chats/{tag} Delete the saved caches of one chat. Admin
Terminal window
curl $MATRICXON_URL/api/cache/persistence
{"enabled":true,"budget_mb":4096,"ttl_hours":168,"files":15,"chats":15,"used_bytes":601308576,"folder":"/mnt/shared/prompt_cache","shared":true}
Terminal window
# Keep saved caches for 3 days; omitted fields stay as they are
mx_admin PUT /api/cache/persistence '{"ttl_hours": 72}'

The cluster and consensus endpoints are used by pAIring. See Cluster.

Routes that change models, caches, settings or the cluster are admin routes: pull, push, delete, copy, create, the cache changes and runtime settings above, and the cluster routes.

  • With MATRICXON_ADMIN_SECRET set, each admin call must be signed with it. The signature covers the method, path, body, a timestamp and a one-time value, so a captured call cannot be changed or replayed. pAIring signs its calls for you.
  • With no secret, admin routes are open. Then protect the network instead.

The signature does not hide the content. Use TLS, or a trusted network, for that.

Each signed call carries three headers:

Header Value
X-Matricxon-Time Unix time in seconds; accepted within 2 minutes of the server’s clock
X-Matricxon-Nonce A random value, used once
X-Matricxon-Signature HMAC-SHA256, in hex, of the five lines below

The key is the SHA-256 of matricxon-admin| followed by the secret. The signed text is five lines: the time, the nonce, the method in capitals, the path with its query, and the SHA-256 (hex) of the body exactly as sent.

This shell function, used in the examples above, signs and sends a call with curl and openssl:

mx_admin.sh
# Usage: mx_admin METHOD PATH [JSON-BODY]
# Needs MATRICXON_URL and MATRICXON_ADMIN_SECRET in the environment.
mx_admin() {
local method=$1 path=$2 body=${3-}
local stamp nonce key body_hash sig
stamp=$(date +%s)
nonce=$(openssl rand -hex 12)
key=$(printf 'matricxon-admin|%s' "$MATRICXON_ADMIN_SECRET" | openssl dgst -sha256 -r | cut -d' ' -f1)
body_hash=$(printf '%s' "$body" | openssl dgst -sha256 -r | cut -d' ' -f1)
sig=$(printf '%s\n%s\n%s\n%s\n%s' "$stamp" "$nonce" "$method" "$path" "$body_hash" \
| openssl dgst -sha256 -mac HMAC -macopt "hexkey:$key" -r | cut -d' ' -f1)
curl -sS -X "$method" "$MATRICXON_URL$path" \
-H 'Content-Type: application/json' \
-H "X-Matricxon-Time: $stamp" \
-H "X-Matricxon-Nonce: $nonce" \
-H "X-Matricxon-Signature: $sig" \
${body:+--data-raw "$body"}
}

An unsigned or wrongly signed call is refused with 401:

{"detail":"admin request not signed with the admin secret"}