API Reference
The Metrum Insights API is a PostgREST-fronted REST interface backed by a set of versioned RPC functions for write operations and database views for reads.
This page covers:
- Base URL and authentication
- Calling conventions
- RPC endpoints - the write surface (create jobs, mutate state)
- View endpoints - the read surface (results, status, telemetry)
- Pagination, filtering, and ordering
- Errors
- v3 → v4 column mapping
If you're integrating from scratch, start with the Quickstart. If you're migrating from v3.x, jump to v3 → v4 column mapping.
An OpenAPI 3.0 schema is published at
/openapi.jsonfrom the same base URL. Most generated clients (openapi-generator, openapi-typescript, etc.) consume it directly.
Base URL and authentication
Base URL
The runtime API in v4.0 is mounted under /api/ on the configured control-plane domain. Configure docs builds with DOCS_CONTROL_PLANE_URL; set DOCS_API_BASE_URL only when the API is served from a separate public base URL.
- Configured control plane:
https://<your-control-plane> - Configured API base URL:
https://<your-control-plane>/api - Self-hosted placeholder:
https://<your-control-plane>/api
Authentication
Two supported credential types:
- JWT (preferred for service-to-service). Issued by your workspace's identity provider via the standard Auth0 client-credentials flow. Pass as
Authorization: Bearer <token>. - API key (for scripts and CI). Generate via the planned Profile -> API keys panel (Engineer+; API only in v4.0). Pass as
Authorization: Bearer <key>. Keys are scoped to the issuing user's roles and respect RBAC.
Every request must include Authorization ~ there is no anonymous endpoint.
export METRUM_TOKEN="eyJhbGc..."
export METRUM_BASE="https://<your-control-plane>/api"
Identity context
Most write operations need to know which workspace you're acting on behalf of (the data model still uses org_id). Get your account and memberships first:
curl -X POST "$METRUM_BASE/rpc/get_current_user_context" \
-H "Authorization: Bearer $METRUM_TOKEN" \
-H "Content-Type: application/json"
Response includes your account_id and a list of org_id values you're a member of, each with its RBAC role. You'll pass p_owner_account_id and p_org_id to most RPCs.
Calling conventions
Write operations - RPCs
Writes go through stored procedure RPCs at POST /rpc/<function_name>. Bodies are JSON, parameters are prefixed with p_:
curl -X POST "$METRUM_BASE/rpc/<function_name>" \
-H "Authorization: Bearer $METRUM_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "p_param_one": "...", "p_param_two": 42 }'
RPCs return JSON. Most return the affected entity's ID(s) on success.
Read operations - views
Reads go against PostgREST-exposed views at GET /<view_name>. Use query parameters for filtering, ordering, and pagination:
curl "$METRUM_BASE/v_benchmark_results?order=created_at.desc&limit=20" \
-H "Authorization: Bearer $METRUM_TOKEN"
PostgREST filter syntax applies - see Pagination, filtering, and ordering.
Content types
- Requests:
Content-Type: application/json. - Responses:
application/jsonfor both RPCs and views.
Quickstart (API version)
The five-call sequence to submit a job and read its results:
1. Authenticate
curl -X POST "$METRUM_BASE/rpc/get_current_user_context" \
-H "Authorization: Bearer $METRUM_TOKEN" \
-H "Content-Type: application/json"
Capture account_id and pick an org_id (workspace ID in the live UI) from the returned memberships.
2. Submit a job
curl -X POST "$METRUM_BASE/rpc/create_metrumbench_llm_job" \
-H "Authorization: Bearer $METRUM_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"p_owner_account_id": "ORG_UUID",
"p_project_name": "API Quickstart",
"p_job_name": "llama-70b-vllm-c10",
"p_framework_code": "vllm",
"p_version": "0.6.3",
"p_model_code": "llama-3.1-70b-instruct",
"p_org_id": "ORG_UUID",
"p_config_code": "gpu-config-h200-x1",
"p_server_hostname": "gpu-server-01.internal",
"p_concurrency": 10,
"p_input_sequence_length": 512,
"p_output_sequence_length": 256
}'
Returns the job_id (integer).
3. Poll status
curl -X POST "$METRUM_BASE/rpc/get_job_status" \
-H "Authorization: Bearer $METRUM_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "p_job_id": 42 }'
Status values: pending, queued, running, completed, failed, cancelled. Poll every 5-15 seconds; status doesn't change faster than that.
4. Read results
curl "$METRUM_BASE/v_benchmark_results?job_id=eq.42" \
-H "Authorization: Bearer $METRUM_TOKEN"
5. (Optional) Read telemetry
curl "$METRUM_BASE/v_telemetry_job_summary?job_id=eq.42" \
-H "Authorization: Bearer $METRUM_TOKEN"
That's the whole flow. Everything else is variations on these five calls.
RPC endpoints
The most commonly used write RPCs. The full RPC surface is much larger (the platform exposes 100+ RPCs across job submission, server management, KYAI, cloud provisioning, etc.); the OpenAPI document is the authoritative list.
Identity
get_current_user_context
Returns the calling user's account, identity, and org memberships.
| Parameter | Type | Required | Description |
|---|---|---|---|
| none |
curl -X POST "$METRUM_BASE/rpc/get_current_user_context" \
-H "Authorization: Bearer $METRUM_TOKEN" \
-H "Content-Type: application/json"
list_organizations
List workspaces (the data model still calls them organizations) available to an account.
| Parameter | Type | Required | Description |
|---|---|---|---|
p_account_id | uuid | yes | Account whose workspaces to list |
Jobs
create_metrumbench_llm_job - LLM benchmark
Submits an LLM benchmark job using the metrumbench-llm tool.
| Parameter | Type | Required | Description |
|---|---|---|---|
p_owner_account_id | uuid | yes | Workspace-account owning the project |
p_project_name | text | yes | Project name (created if not present) |
p_job_name | text | yes | Unique-within-run job name |
p_framework_code | text | yes | One of vllm, sglang, trt-llm |
p_version | text | yes | Framework version, e.g. 0.6.3 |
p_model_code | text | yes | From the model catalog, e.g. llama-3.1-70b-instruct |
p_org_id | uuid | yes | Workspace under which to run |
p_config_code | text | yes | Server config code (v_server_current_status.config_code) |
p_server_hostname | text | yes | Target server hostname |
p_concurrency | integer | yes | In-flight request count |
p_input_sequence_length | integer | yes | ISL in tokens |
p_output_sequence_length | integer | yes | OSL in tokens |
p_quantization_code | text | no | e.g. fp16, fp8, int8; default fp16 |
Returns: job_id (integer).
create_metrumbench_vlm_job - VLM benchmark
Same shape as create_metrumbench_llm_job, with the addition of image-related parameters. See OpenAPI for the full signature.
create_metrumbench_asr_job - ASR benchmark
Same shape, with p_audio_duration_bucket replacing input sequence semantics.
get_job_status
| Parameter | Type | Required | Description |
|---|---|---|---|
p_job_id | integer | yes | Job ID |
Returns: current status, status timestamp, error message (if any).
list_jobs_filtered
| Parameter | Type | Required | Description |
|---|---|---|---|
p_project_id | integer | no | Restrict to project |
p_status_code | text | no | Restrict to a single status |
p_owner_account_id | uuid | no | Restrict to workspace |
p_limit | integer | no | Default 50, max 500 |
cancel_job
| Parameter | Type | Required | Description |
|---|---|---|---|
p_job_id | integer | yes | Job ID |
Best-effort. Jobs in running are signalled; jobs in pending/queued are aborted immediately.
Servers
record_server_config_instance_heartbeat
Called by the server agent - included here for self-hosted agent implementations.
| Parameter | Type | Required | Description |
|---|---|---|---|
p_server_config_instance_id | integer | yes | Server ID |
Sizer
estimate_model_memory_requirements
Lightweight version of the full Sizer call - predicts memory requirements for a (model, quantization, gpu) tuple.
| Parameter | Type | Required | Description |
|---|---|---|---|
p_model_code | text | yes | e.g. llama-3.1-70b-instruct |
p_quantization_code | text | yes | e.g. fp16, fp8 |
p_gpu_code | text | yes | e.g. h100, h200, b200, mi355x |
The full Sizer flow goes through dedicated sizer_* RPCs - see OpenAPI for the current set.
KYAI
KYAI exposes its own RPC surface for endpoint and judge configuration, evaluation submission, and result retrieval. The most common entry points:
create_kyai_evaluation- submit a candidate × judge × prompt-set evaluation.list_kyai_candidate_endpoints- list configured candidates.list_kyai_judge_configs- list configured judges.
Full signatures in OpenAPI; the User Guide → KYAI covers the conceptual flow.
View endpoints
All views are accessible at GET /<view_name> and support PostgREST filtering. The most useful:
Job and run status
| View | What it returns |
|---|---|
v_job_current_status | Latest status per job |
v_job_status_history | Full status timeline per job |
v_run_jobs_with_params | Run jobs joined with their parameters |
v_project_run_current_status | Latest run status per project |
v_run_cost_summary | Aggregated cost per run |
v_run_health_checks | Pre/post-validation outcomes for a run |
Results
| View | What it returns |
|---|---|
v_benchmark_results | Full benchmark results across all tools |
v_metrumbench_llm_outputs | LLM result detail |
v_metrumbench_vlm_outputs | VLM result detail |
v_metrumbench_asr_outputs | ASR result detail |
v_inferencex_outputs | InferenceX capacity estimates |
Comparison and leaderboards
| View | What it returns |
|---|---|
v_throughput_leaderboard | Ranked leaderboard |
v_model_comparison | Cross-model performance comparison |
v_framework_comparison | Cross-framework comparison |
v_quantization_comparison | Quantization impact analysis |
v_concurrency_scaling | Concurrency vs throughput/latency |
v_cost_efficiency | tokens/$ and tokens/hour |
v_hardware_utilization | Aggregated telemetry per job |
Telemetry
| View | What it returns |
|---|---|
v_telemetry_with_server | Time-series telemetry joined with server info |
v_telemetry_job_summary | Aggregated telemetry per job |
v_telemetry_per_gpu_summary | Per-GPU breakdown |
v_tpu_telemetry_job_summary | TPU-specific aggregates |
KYAI
| View | What it returns |
|---|---|
v_kyai_jobs | KYAI job listing |
v_kyai_outputs | Scored outputs (instruction × response × score) |
v_kyai_generation_outputs | Phase-1 generations |
v_kyai_results | Aggregated KYAI results |
v_kyai_leaderboard | KYAI ranking |
v_kyai_builtin_sets_with_prompt_count | Built-in prompt set catalog |
Cloud and audit
| View | What it returns |
|---|---|
v_cloud_provisioning_requests | Cloud provisioning request status |
v_cloud_resource_lifecycle | Cloud resource state transitions |
v_audit_logs | Audit trail (90-day retention) |
Pagination, filtering, and ordering
Views use PostgREST conventions.
Filtering
# Equality
curl "$METRUM_BASE/v_benchmark_results?status_code=eq.completed"
# Comparison
curl "$METRUM_BASE/v_kyai_outputs?score=gte.8"
# IN list
curl "$METRUM_BASE/v_benchmark_results?framework_code=in.(vllm,sglang)"
# Substring match
curl "$METRUM_BASE/v_benchmark_results?job_name=like.*llama*"
Ordering
curl "$METRUM_BASE/v_throughput_leaderboard?order=tokens_per_sec.desc"
curl "$METRUM_BASE/v_benchmark_results?order=created_at.desc,job_name.asc"
Limit and offset
curl "$METRUM_BASE/v_benchmark_results?limit=20&offset=40"
Range-based pagination (preferred for large result sets)
The Benchmarks page uses range headers, which are faster than offset on large tables:
curl "$METRUM_BASE/v_benchmark_results?order=created_at.desc" \
-H "Range-Unit: items" \
-H "Range: 0-19"
Response includes Content-Range: 0-19/12345. Increment the range for the next page.
Rate limits and quotas
| Surface | Default limit | Notes |
|---|---|---|
| RPCs | 60/min per token | Burstable to 120/min for 30 seconds |
| View reads | 600/min per token | Higher for paginated reads |
| Job submissions | 20/min per workspace | Hard cap; queue jobs locally if needed |
| KYAI evaluations | 5 concurrent per workspace | Per-workspace concurrency, not a rate limit |
Hitting a rate limit returns 429 Too Many Requests with a Retry-After header. Quotas (monthly GPU-hours, judge tokens) are surfaced via the planned Settings -> Billing panel (API only in v4.0) and enforced at job-creation time, not request time.
Errors
All errors are JSON.
Shape
{
"code": "validation_failed",
"message": "Server config 'gpu-config-h200-x1' does not have enough GPU memory for the requested model at fp16.",
"details": {
"required_gb": 140,
"available_gb": 80,
"suggestion": "Try quantization_code=fp8 or select a server with >= 160 GB GPU memory."
},
"hint": "See /docs/hardware-compatibility for memory floors."
}
Common codes
| Code | HTTP | Meaning |
|---|---|---|
unauthenticated | 401 | Missing or invalid token |
forbidden | 403 | Token valid but lacks role to perform the action |
not_found | 404 | Entity (project, server, job) doesn't exist or isn't visible to you |
validation_failed | 400 | Pre-run validation rejected the request |
conflict | 409 | E.g. job name duplicate within a run |
rate_limited | 429 | See Retry-After header |
quota_exceeded | 402 | Workspace has hit a billing quota |
server_unavailable | 503 | Target server is offline or has no heartbeat |
internal | 500 | Unexpected error ~ file via your account team with the error ID |
Every error response includes an X-Request-Id header. Quote it when filing support tickets.
v3 to v4 column mapping
The most common breaking changes when migrating from v3.x:
| v3 table | v4 view | Notable column changes |
|---|---|---|
benchmark_results | v_benchmark_results | tokens_per_sec (unchanged); latency_p50_ms -> ttft_p50_ms and tpot_p50_ms split |
inferencemax_outputs | v_inferencex_outputs | New confidence_interval_lower/upper columns |
kyai_outputs (v1) | v_kyai_outputs | judge_score -> score; judge_explanation -> judge_response |
server_status | v_server_current_status | last_seen -> last_heartbeat_at |
telemetry_summary | v_telemetry_job_summary | Per-metric columns; EAV underneath |
The v3 endpoints return 410 Gone after May 15, 2026. Generate v4 API keys and re-point clients before the cutover.
SDKs and tooling
- OpenAPI ~
https://<your-control-plane>/api/openapi.json(requires authentication) - Python client ~
pip install metrum-insights-client(auto-generated from OpenAPI) - TypeScript client ~
npm install @metrum/insights-client(auto-generated)
Both clients are thin wrappers ~ if you don't want the dependency, calling the API directly with curl or requests/fetch is perfectly reasonable.
See also
- Quickstart ~ UI version of the same flow.
- User Guide ~ workflows that combine multiple API calls.
- Feature Reference ~ per-feature configuration details.
- Admin Guide - RBAC ~ what each role can call.