Reference
Base URL
| Environment | Base URL |
|---|---|
| Production | https://www.vantageai.cc/api/runtimeai/v1 |
Workflow
You must quote before submit. Each quote_id is one-time use.
The quote_id comes from the quote response — not generated client-side.
Use your personal rai_live_… key as TOKEN below (request one via
Request API key). Operators may use RUNTIMEAI_API_TOKEN instead.
Authentication
All routes except GET /health and the key-request endpoints require a Bearer token.
Get a key (recommended)
- Open /runtimeai/api/request-key and enter your email.
- Click the confirmation link in your inbox (valid 48 hours).
- Receive your personal
rai_live_…key by email — one key per email address.
Authorization: Bearer rai_live_…
Missing or invalid tokens return 401 with code UNAUTHORIZED.
Trial allowance (self-serve keys)
Customer rai_live_… keys have a trial allowance
per account
(acct_… / account_id on the key row — the same subject as attestation).
Rotating a key does not reset it. Master RUNTIMEAI_API_TOKEN is exempt (operator).
The allowance can be raised on request — email
hello@vantageai.cc with your
acct_ id and what you're evaluating. Defaults:
| Cap | Limit | HTTP | code |
|---|---|---|---|
| Daily evaluation submits | 10 per UTC day per account | 429 | QUOTA_DAILY_RUNS |
| Monthly eval spend | $2.00 USD quoted per UTC month per account | 429 | QUOTA_MONTHLY_USD |
| Concurrent in-flight evaluations | 3 per account | 429 | QUOTA_CONCURRENT_RUNS |
| Quote requests | 30 per rolling minute per account | 429 | RATE_QUOTES |
| Status polls | 120 per rolling minute per account | 429 | RATE_POLLS |
| Models per evaluation | 1–5 unique trial-sample ids | 400 | INVALID_REQUEST |
A documented 5-model 12-turn comparison is ~$0.21 (trial-sample quote) to
~$0.34 (engage-draft bakeoff). $2/month is about 9 such comparisons —
enough for a real evaluation, not a research programme. Email
hello@vantageai.cc with your
acct_ id and what you're evaluating — we raise trial
allowances for people doing real work.
Quoted eval-run USD (not the production execution projection) counts toward
the monthly allowance at POST /evaluations. Master token is exempt.
Env overrides: RUNTIMEAI_QUOTA_DAILY_RUNS,
RUNTIMEAI_QUOTA_MONTHLY_USD,
RUNTIMEAI_QUOTA_CONCURRENT_RUNS,
RUNTIMEAI_RATE_QUOTES_PER_MINUTE,
RUNTIMEAI_RATE_POLLS_PER_MINUTE,
RUNTIMEAI_RATE_ATTESTATIONS_PER_HOUR,
plus per-account maps RUNTIMEAI_QUOTA_*_ACCT=acct_xxx:value.
Operator key management
Master RUNTIMEAI_API_TOKEN works on all routes and is required to manually
create or revoke keys in the operator UI.
| Method | How |
|---|---|
| Self-serve (customers) | /runtimeai/api/request-key — email confirm → key emailed |
| Web UI (operators) | /runtimeai/api/keys — master token, label, copy key once |
| CLI (Render shell) | python -m runtimeai_api.keys_cli create --label "Customer" |
| API | POST /api/runtimeai/v1/admin/api-keys with master Bearer token |
Error envelope
{
"error": "Human-readable message",
"code": "QUOTE_EXPIRED",
"details": {}
}
Endpoints
GET/health
Unauthenticated smoke check. Returns ok, product, version, api_path.
GET/scenarios/catalog
Public scenario metadata (no auth) — same fields as /scenarios. Used by the docs playground and landing UI.
GET/scenarios
Lists RuntimeAI public catalog scenarios (id, title, roles, default_persona, family, optional industry_domain). Routing scenarios are runnable by id but omitted from the public list; numbers start at 1 for visible scenarios.
Public catalog returned by GET /scenarios and GET /scenarios/catalog (same rows). Each item includes id, title, roles, default_persona, family, and optional industry_domain. Routing and Platform & spend scenarios are runnable by id but omitted from the public list.
Analytical · Engineering & analytics
| Code | scenario_id | Title | Roles |
|---|---|---|---|
rai001 | ds_train_serve_skew_v1 | Train/Serve Skew | ML Engineer ↔ Engineering counterpart |
rai002 | ds_feature_leakage_v1 | Feature Leakage Review | Data Scientist ↔ Engineering counterpart |
rai003 | de_lineage_impact_v1 | Lineage Impact Review | Data Engineer ↔ Engineering counterpart |
rai004 | de_pipeline_incident_v1 | Pipeline Incident Triage | Data Engineer ↔ Engineering counterpart |
rai005 | de_freshness_sla_v1 | Freshness SLA Breach | Data Engineer ↔ Engineering counterpart |
rai006 | de_dbt_test_failure_v1 | dbt Test Failure | Data Engineer ↔ Engineering counterpart |
rai007 | de_sql_optimization_v1 | SQL Optimization | Data Engineer ↔ Engineering counterpart |
rai008 | de_schema_drift_v1 | Schema Drift Review | Data Engineer ↔ Engineering counterpart |
rai009 | de_null_rate_alert_v1 | Null Rate Alert | Data Engineer ↔ Engineering counterpart |
rai010 | de_sql_partition_fix_v1 | Partition Filter Fix | Data Engineer ↔ Engineering counterpart |
rai011 | ds_experiment_readout_v1 | Experiment Readout | Data Scientist ↔ Engineering counterpart |
Conversational · Customer-facing
| Code | scenario_id | Title | Roles |
|---|---|---|---|
rai101 | sales_discovery_v1 | Discovery Call | Sales rep ↔ Prospect |
rai102 | support_escalation_v1 | Support Escalation | Support Agent ↔ Customer |
rai103 | billing_refund_policy_v1 | Billing Refund Dispute | Support Agent ↔ Customer |
rai104 | bug_triage_screening_v1 | Bug Triage Initial Screening for Product Backlog | Product Manager ↔ Head of Support |
Industry · Fintech & compliance
| Code | scenario_id | Title | Roles |
|---|---|---|---|
rai106 | fintech_kyc_compliance_v1 | Fintech KYC Compliance | Compliance Ops ↔ Relationship Manager |
rai108 | fintech_suspicious_wire_v1 | Fintech Suspicious Wire | Payments Compliance ↔ Relationship Manager |
rai109 | fintech_dispute_chargeback_v1 | Fintech Chargeback | Disputes Ops ↔ Merchant Owner |
Industry · Healthcare
| Code | scenario_id | Title | Roles |
|---|---|---|---|
rai107 | healthcare_scheduling_ops_v1 | Healthcare Scheduling | Scheduling Agent ↔ Patient |
rai110 | healthcare_prior_auth_v1 | Healthcare Prior Authorization | Care Navigation ↔ Patient |
rai111 | healthcare_refill_routing_v1 | Healthcare Refill Routing | Pharmacy Routing ↔ Patient |
GET/models
Lists trial sample models made available as part of your trial for a scenario. Pick up to five for a parallel comparison quote.
POST/evaluations/quote
Check readiness and cost before submit. Returns quote_id (15-minute TTL), per-model
ready / unavailable status, summary.est_cost_usd_total, and
summary.cost_groups with separate scenario development/test and execution buckets,
each marked estimated or not_estimated. Execution uses scenario defaults unless
you send execution_assumptions.
In the docs playground, step 4 quotes automatically when you click Run.
{
"scenario_id": "support_escalation_v1",
"models": ["openai/gpt-4o-mini"],
"turns": 12,
"provider": "openrouter",
"preflight": false,
"execution_assumptions": {
"interactions_per_biz_day": 5000,
"biz_days_per_month": 22
}
}
models: 1–5 unique ids from GET /models.
turns: 1–24 (playground uses the scenario's recommended count). preflight: optional probe (slower).
POST/evaluations202
Submit after quote. confirm must be true. Starts parallel agent runs.
Returns evaluation_id, runs[], poll_url, and quoted cost
including grouped cost buckets.
Optional results_email sends a summary when the evaluation finishes (no need to keep polling).
{
"quote_id": "qt_…",
"confirm": true,
"callback_url": null,
"results_email": "you@example.com"
}
GET/evaluations/{evaluation_id}
Poll every 3–5 seconds. Aggregate status: running, completed,
partial, or failed. When ended, each run includes score and
links.scorecard (JSON file download) and links.pdf (PDF download).
With 2+ models, top-level links.comparison and links.comparison_pdf point to
the consolidated batch report. In the playground above, use Download JSON /
Download PDF after polling — those buttons use your browser session automatically.
GET/evaluations/{evaluation_id}/comparison
Bearer-authenticated JSON comparison (best for curl, Python, and Postman). Same payload as the batch
comparison report. Available when aggregate status is not running and the evaluation has 2+ models.
GET/evaluations/{evaluation_id}/comparison.pdf
Bearer-authenticated PDF comparison download. Returns application/pdf with an attachment filename.
POST/attestations
Countersign a local runtimeai.decision/v1 digest. The decision body
(scores, rubrics, prompts, transcripts) never leaves the customer machine. Returns a detached
runtimeai.attestation/v1 envelope. Verify is free and offline in
vantage-core verify; this route is the only issuance path.
Public keyring: /runtimeai/attestation/keys.json.
Issuance is live. CLI: vantage-core attest RECORD.json
(RUNTIMEAI_API_KEY). Verify stays free and offline
(vantage-core verify).
Countersignature is free while in preview.
We will give at least 90 days' notice before that changes.
Any self-serve rai_live_ key can issue. Paid currently buys nothing.
Countersignature is not a paywall. History and the chain are in development.
Abuse prevention: 60 issuances per rolling hour per account
(429 RATE_ATTESTATIONS). Master token is exempt.
subject is server-assigned and cannot be supplied by the client
(extra=forbid).
{
"digest": "64-hex payload_sha256",
"algorithm": "sha256",
"schema": "runtimeai.decision/v1",
"canonicalization": "runtimeai-py-json-v1",
"pins": {
"model": "openai/gpt-4o-mini",
"scenario_id": "sample.acme_release_v1",
"runner": "vantage-core",
"runner_version": "0.1.18",
"suite_id": "sample.acme_release_v1"
},
"suite_sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"client_ts": "2026-08-01T15:00:00Z"
}
Request shape matches AttestationIssueRequest.
Allowed pins: model, scenario_id, runner,
runner_version (required), plus optional suite_id and
scenario_sha256.
suite_sha256 is a top-level signed field (not a pin):
the client copies it from the local decision; the issuer signs whatever arrived
(null if omitted / no suite). Do not put suite_sha256 inside
pins. Do not send subject, seq,
prev_digest, signed_at, or kid.
Use vantage-core 0.1.18 (latest on PyPI). Attest/verify need
0.1.10+; prefer current.
GET/api/run/{session_id}/scorecard
Per-run scorecard JSON (browser or script). Add ?download=1 to receive a
.json file (Content-Disposition: attachment). Without download=1,
returns JSON when the client sends Accept: application/json. Requires the same browser viewer
session as the playground (fd_viewer_runtimeai cookie) or a signed-in RuntimeAI profile —
not the API Bearer token.
GET/api/run/{session_id}/scorecard.pdf
Per-run scorecard PDF (score breakdown + transcript). Use from the same browser session as the evaluation, or download via the playground Download PDF button.
GET/api/run/batch/{evaluation_id}/comparison
Side-by-side JSON comparison at the site root (not under /api/runtimeai/v1). Add
?download=1 for a .json file download. Lists each model with scores, dimensions,
and per-model report links. Requires the same browser viewer session as the playground — use
GET /evaluations/{id}/comparison with Bearer auth for scripts instead.
GET/api/run/batch/{evaluation_id}/comparison.pdf
Batch comparison PDF (summary table + dimension breakdown). Same browser-session rules as individual
scorecard PDFs. For automation, prefer GET /evaluations/{id}/comparison.pdf with Bearer auth.
Quick start — curl
Set your base URL and token once (rai_live_… customer key or operator RUNTIMEAI_API_TOKEN):
export BASE='https://www.vantageai.cc/api/runtimeai/v1' export TOKEN='rai_live_your_key_here'
curl -sS "$BASE/health" | python3 -m json.tool
Full quote → submit → poll (curl)
# 1. Quote curl -sS -X POST "$BASE/evaluations/quote" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "scenario_id": "support_escalation_v1", "models": ["openai/gpt-4o-mini"], "turns": 12, "provider": "openrouter", "preflight": false }' | python3 -m json.tool export QUOTE_ID='qt_from_response' # 2. Submit (starts real LLM run — uses OpenRouter credits) curl -sS -X POST "$BASE/evaluations" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{\"quote_id\":\"$QUOTE_ID\",\"confirm\":true}" | python3 -m json.tool export EVAL_ID='evaluation_id_from_response' # 3. Poll until status ≠ running while true; do curl -sS "$BASE/evaluations/$EVAL_ID" \ -H "Authorization: Bearer $TOKEN" | python3 -m json.tool sleep 5 done # 4. Download reports (Bearer auth — works from curl/scripts) curl -sS -o "comparison.json" \ -H "Authorization: Bearer $TOKEN" \ "$BASE/evaluations/$EVAL_ID/comparison" curl -sS -o "runtimeai-comparison.pdf" \ -H "Authorization: Bearer $TOKEN" \ "$BASE/evaluations/$EVAL_ID/comparison.pdf" # Per-run scorecard from poll response runs[].links (example RUN_ID) curl -sS -o "scorecard.json" \ -H "Accept: application/json" \ "https://www.vantageai.cc/api/run/RUN_ID/scorecard?download=1" curl -sS -o "scorecard.pdf" \ "https://www.vantageai.cc/api/run/RUN_ID/scorecard.pdf"
Python example
Requires requests. Submit uses real OpenRouter credits when the server has OPENROUTER_API_KEY set.
import os
import time
import json
import requests
from pathlib import Path
BASE = os.environ.get(
"RUNTIMEAI_API_BASE",
"https://www.vantageai.cc/api/runtimeai/v1",
)
TOKEN = os.environ["RUNTIMEAI_API_TOKEN"] # or rai_live_… customer key
def api(method: str, path: str, **kwargs):
headers = {"Authorization": f"Bearer {TOKEN}"}
if kwargs.get("json") is not None:
headers["Content-Type"] = "application/json"
url = f"{BASE}{path}"
resp = requests.request(method, url, headers=headers, timeout=120, **kwargs)
resp.raise_for_status()
return resp.json()
# Smoke (no auth)
print(requests.get(f"{BASE}/health", timeout=30).json())
scenarios = api("GET", "/scenarios")
print("scenarios:", [s["id"] for s in scenarios["scenarios"]])
quote = api(
"POST",
"/evaluations/quote",
json={
"scenario_id": "support_escalation_v1",
"models": ["openai/gpt-4o-mini"],
"turns": 12,
"provider": "openrouter",
"preflight": False,
},
)
quote_id = quote["quote_id"]
print("quote_id:", quote_id, "est_total:", quote["summary"]["est_cost_usd_total"])
submit = api(
"POST",
"/evaluations",
json={"quote_id": quote_id, "confirm": True},
)
eval_id = submit["evaluation_id"]
print("evaluation_id:", eval_id)
while True:
status = api("GET", f"/evaluations/{eval_id}")
print("status:", status["status"], status.get("progress"))
if status["status"] != "running":
for run in status.get("runs", []):
if run.get("links"):
print("scorecard json:", run["links"].get("scorecard"))
print("scorecard pdf:", run["links"].get("pdf"))
if status.get("links"):
print("comparison json:", status["links"].get("comparison"))
print("comparison pdf:", status["links"].get("comparison_pdf"))
break
time.sleep(5)
# Download comparison reports with Bearer auth
cmp = requests.get(
f"{BASE}/evaluations/{eval_id}/comparison",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=120,
)
cmp.raise_for_status()
Path("comparison.json").write_text(json.dumps(cmp.json(), indent=2), encoding="utf-8")
pdf = requests.get(
f"{BASE}/evaluations/{eval_id}/comparison.pdf",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=120,
)
pdf.raise_for_status()
Path("runtimeai-comparison.pdf").write_bytes(pdf.content)
Postman
Download RuntimeAI-v1.postman_collection.json
Setup
- Open Postman → Import → File → select the collection JSON (or use the download link above).
- Create environment RuntimeAI Production with variables:
| Variable | Value | Notes |
|---|---|---|
baseUrl | https://www.vantageai.cc/api/runtimeai/v1 | No trailing slash |
token | Your RUNTIMEAI_API_TOKEN | Mark as secret |
quote_id | (empty) | Auto-filled by collection script after quote |
evaluation_id | (empty) | Auto-filled after submit |
Run in order
| Step | Request | Auth | Expected |
|---|---|---|---|
| 1 | 01 Health | None | 200, ok: true |
| 2 | 02 List scenarios | Bearer {{token}} | Scenario list |
| 3 | 03 Quote evaluation | Bearer | 200, quote_id (playground step 4 quotes on Run) |
| 4 | 04 Submit evaluation | Bearer | 202, evaluation_id |
| 5 | 05 Poll evaluation status | Bearer | Repeat until not running |
Collection-level Bearer auth uses {{token}} — set it once in the environment.
Typical completion time: 3–10 minutes for one model at 12 turns.
Postman troubleshooting
| Symptom | Fix |
|---|---|
| 401 Unauthorized | token must match server RUNTIMEAI_API_TOKEN exactly |
| 404 on health | Check RUNTIMEAI_API_ENABLED=1 and redeploy |
| 410 Quote expired | Quote older than 15 min — run quote again |
| 422 Quote consumed | Quote already submitted — run quote again |
| 403 on scorecard PDF/JSON | Use playground Download buttons (browser session), Bearer /evaluations/{id}/comparison, or sign in on RuntimeAI before opening /api/run/… links |
| 429 Daily / monthly allowance | Self-serve account hit 10 evals/UTC day or $2 quoted/UTC month — email hello@vantageai.cc with your acct_ id and what you're evaluating. We raise trial allowances for people doing real work. Rotating a key does not reset it. |
| 400 on submit | Body must include "confirm": true |
Error codes
| HTTP | code | Meaning |
|---|---|---|
| 400 | INVALID_REQUEST | Bad body, missing confirm, invalid scenario |
| 401 | UNAUTHORIZED | Missing or wrong Bearer token |
| 404 | NOT_FOUND | Unknown quote or evaluation id |
| 409 | INVALID_REQUEST | Models changed since quote |
| 410 | QUOTE_EXPIRED | Quote older than 15 minutes |
| 422 | QUOTE_CONSUMED | Quote already used for submit |
| 429 | QUOTA_DAILY_RUNS | 10 evaluation submits per UTC day per account (self-serve keys) |
| 429 | QUOTA_MONTHLY_USD | $2.00 quoted eval USD per UTC month per account (self-serve keys). 429 invites hello@vantageai.cc. |
| 429 | QUOTA_CONCURRENT_RUNS | 3 in-flight evaluations per account (self-serve keys) |
| 429 | RATE_QUOTES | 30 quote requests per rolling minute per account |
| 429 | RATE_POLLS | 120 status polls per rolling minute per account |
| 429 | RATE_ATTESTATIONS | 60 attestation issuances per rolling hour per account (self-serve keys) |
| 503 | PROVIDER_UNAVAILABLE | Missing OpenRouter key or server issue |
Related
- Request API key — self-serve email workflow
- How To — sandbox UI walkthrough
- RuntimeAI sim — interactive evaluation UI