Auth header
Issue tokens at Settings → Developer. Tokens look like mvs_live_<prefix>_<secret>; the 8-character prefix is also surfaced in the dashboard so you can identify a key without revealing the secret half. The token is shown once at creation; AgentHub stores only the prefix and a SHA-256 hash of the secret.
Every request must carry the token in an Authorization header:
Authorization: Bearer mvs_live_a1b2c3d4_<secret>
- Missing header → HTTP 401 with no body details.
- Revoked or unknown token → HTTP 401.
- Valid token but missing scope → HTTP 403 with the missing scope name.
- Cross-tenant
:orgIdmismatch → HTTP 403.
Pagination
Listing endpoints use cursor pagination. Pass limit (default 25, max 100) and cursor on the URL. Responses include data[] and next_cursor; when the cursor is null, you have reached the end of the collection. Cursors are stable across writes and safe to URL-encode.
# Page through every run in a workspace curl -H "Authorization: Bearer $TOKEN" \ "https://app.mvsagents.ai/api/v1/orgs/$ORG_ID/runs?limit=50" # Follow the next page curl -H "Authorization: Bearer $TOKEN" \ "https://app.mvsagents.ai/api/v1/orgs/$ORG_ID/runs?limit=50&cursor=$NEXT_CURSOR"
Errors
Every error response uses the same JSON envelope. The HTTP status carries the category; the body carries a stable code, a human-readable message, and an optional structured payload for validation errors.
{
"error": {
"code": "validation_failed",
"message": "input.customer_id is required",
"details": [
{ "path": ["input", "customer_id"], "message": "Required" }
]
},
"request_id": "req_01HZF5K3..."
}Always log request_id — support uses it to look up the exact request in the gateway logs.
Rate limits
Reads are limited to a few hundred requests per minute per token. Authentication failures and unknown prefixes count against the bucket so probing is expensive. Every response sets these headers; back off when X-RateLimit-Remaining hits zero.
X-RateLimit-Limit: 600 X-RateLimit-Remaining: 412 X-RateLimit-Reset: 1716148931
Responses are also marked Cache-Control: no-store — never cache them in a shared cache.
Idempotency
Mutating endpoints accept an Idempotency-Key request header. Use a UUIDv4 per logical operation. The first request with a given key executes; subsequent requests with the same key replay the original response without re-executing. Keys live for 24 hours, then expire.
# Start a run with an idempotency key
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"input": {"customer_id": "cus_123"}}' \
"https://app.mvsagents.ai/api/v1/orgs/$ORG_ID/agents/$AGENT_ID/runs"Scope catalog
Each key declares an explicit list of scopes at creation time. Wildcards are not supported — least privilege is the only mode.
read:runs
List and inspect agent runs.
write:runs
Start runs and replays.
read:approvals
List pending approvals.
write:approvals
Approve or reject requests.
read:knowledge
List documents and chunks.
write:knowledge
Upload, retire, or quarantine documents.
read:agents
List agents and installed versions.
read:audit
List and export audit-log entries.
Quick start
# 1. Issue a key in Settings → Developer # 2. Export your token and org id export TOKEN="mvs_live_..." export ORG_ID="org_..." # 3. List recent runs curl -H "Authorization: Bearer $TOKEN" \ "https://app.mvsagents.ai/api/v1/orgs/$ORG_ID/runs?limit=10" # 4. Inspect one curl -H "Authorization: Bearer $TOKEN" \ "https://app.mvsagents.ai/api/v1/orgs/$ORG_ID/runs/$RUN_ID"