VibeInfra API
One REST API over the VibeInfra incident catalog, the infrastructure glossary, live sandbox capacity and a learner's own progress. The catalog surface is unauthenticated — it is the platform's public index, and crawlers and agents are meant to read it.
Base URL
https://api.vibeinfra.id/api/v1Responses are JSON. The machine-readable contract for everything on this page is /openapi.json (YAML), an OpenAPI 3.1 document you can feed straight to a client generator or an agent.
Quickstart
# Every incident and course in the catalog
curl -s https://api.vibeinfra.id/api/v1/courses
# One incident, in full
curl -s https://api.vibeinfra.id/api/v1/courses/incident-22-k8s-crashloop
# Live sandbox capacity, before you tell someone to start a lab
curl -s https://api.vibeinfra.id/api/v1/labs/capacity
Prefer a client? npm install @vibeinfra/sdk or pip install vibeinfra.
Driving this from an AI agent? Use the
MCP server instead of raw HTTP.
Authentication
Catalog and platform endpoints take no credentials at all. Learner-scoped endpoints need the
session JWT minted by the GitHub or Google OAuth callback, presented either as the
vibe_jwt HttpOnly cookie (browsers should send
credentials: "include") or as a bearer header for non-browser clients:
Authorization: Bearer <session-jwt>
GET /auth/me never fails on a missing session: it answers
{"authenticated": false}, so it is safe to call unconditionally.
Endpoints
Auth is none for open endpoints,
optional where signing in changes the answer but is not required, and
session where a session is required.
Catalog
| Endpoint | Auth | Returns |
|---|---|---|
GET /courses | none | List every course and incident in the catalog |
GET /courses/{courseId} | none | Fetch one course blueprint |
GET /glossary | none | Infrastructure glossary |
GET /credits/packs | none | List purchasable VibeCredits packs |
Platform
| Endpoint | Auth | Returns |
|---|---|---|
GET /health | none | Liveness probe |
GET /settings/public | none | Public feature flags |
GET /labs/capacity | none | Live sandbox capacity |
GET /telemetry/public | none | Public platform counters |
GET /labs/leaderboard | none | XP leaderboard and hall of fame |
Growth
| Endpoint | Auth | Returns |
|---|---|---|
POST /waitlist | none | Join the early-access waitlist |
GET /events/2am-live/status | none | 2AM Live event status |
Labs
| Endpoint | Auth | Returns |
|---|---|---|
POST /labs/start | optional | Provision an incident sandbox |
POST /labs/check | session | Grade the current sandbox state |
POST /labs/destroy | session | Tear down the caller's sandbox |
GET /labs/aar | session | After-action report for a finished session |
Account
| Endpoint | Auth | Returns |
|---|---|---|
GET /auth/me | optional | Describe the current session |
GET /auth/logout | session | Clear the session cookie |
GET /user/profile | session | The signed-in learner's profile |
GET /user/completions | session | Incidents this learner has completed |
Core response shapes
Course summary
What GET /courses returns for each entry. GET /courses/{courseId}
adds the authored teaching content — objectives, and chapters on
step-graded courses.
{
"id": "incident-22-k8s-crashloop",
"title": "Kubernetes Microservices CrashLoopBackOff",
"type": "lab",
"category": "Kubernetes",
"difficulty": "Advanced",
"domain": "Kubernetes",
"rung": 6,
"duration_minutes": 45,
"xp_reward": 300,
"description": "Trace and fix pod CrashLoopBackOff causing an HTTP 503 outage at the Ingress gateway.",
"tech_stack": ["Kubernetes", "Ingress", "CrashLoopBackOff", "kubectl"],
"status": "enabled",
"credit_cost": 1,
"is_free": false
}Capacity
{
"total": 3,
"mode2": 1,
"mode2_cpu": 2.5,
"free_lab_cpu": 0.5,
"queue_length": 7
}
A non-zero queue_length means POST /labs/start will queue the
request rather than provision immediately.
Errors and rate limits
Failures carry a JSON body of the form {"error": "..."}. The statuses worth
handling explicitly are 401 (no valid session), 404 (unknown
course ID) and 429 (rate limited).
| Endpoint | Limit | Keyed by |
|---|---|---|
POST /labs/start | 5 / minute | user, falling back to IP |
POST /labs/check | 12 / minute | user |
POST /waitlist | 5 / minute | IP |
GET /auth/github, GET /auth/google | 10 / minute | IP |
Read endpoints are unmetered within reason. Sandbox starts are limited because each one provisions real containers.
Next
- Developer portal — every resource in one place
- MCP server — the same catalog as agent tools
- openapi.json — the machine-readable contract
- /.well-known/ard.json — agent discovery manifest