4.1 — API overview
On this page
4.1 — API overview
VibeMap exposes a REST API for everything you can do in the web app: create projects, read your spec, trigger regenerations, and watch tasks complete. Most users never touch it directly — the MCP server wraps it for IDE agents. But if you're building automations, dashboards, or your own integrations, this is where to look.
When to use the API directly
- Pulling spec data into another tool (Linear, Notion, your own dashboards)
- Automating project creation from an upstream source (a CRM, a sales-call transcriber, etc.)
- Custom CI workflows that need finer control than the MCP server gives
- Building a custom client UI on top of VibeMap
If you just want your IDE agent to work through a backlog, skip ahead to the MCP server — it's a much friendlier interface.
Base URL
| Environment | URL |
|---|---|
| Production | https://vibemap.ai |
Authentication
All API requests require an API key (we call them Personal Access Tokens, PATs). Generate one from Account → Developer in the web app: name the key, click Generate Key, and copy it before you close the dialog.
Pass it in the Authorization header:
curl -H "Authorization: Bearer vm_your_token_here" \
https://vibemap.ai/api/crud/projects
Treat the key like a password. Anyone with it can read and write to all your projects.
Response format
All responses are JSON. There is no wrapper object — a single entity comes back as the bare row.
A single entity (GET ?id=…, POST, PUT, DELETE):
{
"id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"name": "User Authentication",
"project_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-03-15T10:30:00Z"
}
A list — the rows sit under a key named after the entity, next to a meta pagination block:
{
"features": [{ "id": "f1a2b3c4-…", "name": "User Authentication" }],
"meta": { "total": 42, "limit": 100, "offset": 0, "hasMore": false }
}
Error:
{
"error": "Project not found"
}
Billing and conflict errors carry a machine-readable code alongside the message (PLAN_UPGRADE_REQUIRED, TOKEN_BUDGET_EXCEEDED, DUPLICATE_TASK, MODEL_NOT_ALLOWED). Branch on code, never on the message text — the copy changes.
API groups
| Group | Base Path | What it covers |
|---|---|---|
| CRUD | /api/crud/ | Read/write for every entity type (projects, features, user stories, ACs, personas, pages, schema) |
| Projects | /api/project/ | Project-level config and bulk operations |
| Tasks | /api/tasks/ | Submit, poll, retry and cancel AI generation tasks |
| Schema | /api/schema/ | Database schema operations |
| Billing | /api/billing/ | Subscription and usage |
| MCP | /api/mcp/ | The endpoints behind the MCP server — atomic blueprint, kanban, code map, agent |
HTTP status codes
Success
| Code | Meaning |
|---|---|
200 OK | Request succeeded — including DELETE, which returns a body describing what it removed |
201 Created | Resource created |
Client errors
| Code | Meaning |
|---|---|
400 Bad Request | Validation error — check the request body or query params |
401 Unauthorized | Missing or invalid API key |
402 Payment Required | A billing gate refused the request. code: "PLAN_UPGRADE_REQUIRED" means your plan doesn't include this capability; code: "TOKEN_BUDGET_EXCEEDED" means you're out of tokens for the window. There is no silent downgrade — the run is refused |
403 Forbidden | Authenticated, but not permitted to access this project. Also returned with code: "MODEL_NOT_ALLOWED" when you explicitly ask for a model your plan can't run |
404 Not Found | Resource doesn't exist or isn't accessible by your key |
409 Conflict | The write collides with something already there — a second generation of the same type while one is in flight (code: "DUPLICATE_TASK"), or an acceptance criterion whose Given/When/Then already exists on that story |
422 Unprocessable Entity | Body failed schema validation on a route that validates with a schema — the response carries { "error": "invalid_request", "issues": [...] } |
429 Too Many Requests | Rate limit hit — back off and retry |
Server errors
| Code | Meaning |
|---|---|
500 Internal Server Error | Unexpected server error — open a support ticket if it persists |
Rate limiting
Rate limiting is per-endpoint, not global. The blueprint family — /api/mcp/atomic-blueprint, /api/mcp/access-rules, /api/mcp/changesets — allows 60 calls per user per minute; over that you get a 429 with a Retry-After header and a resetAt timestamp in the body. The budget is keyed to the user, not the key, so two PATs belonging to the same account share it.
The CRUD and task endpoints aren't call-rate-limited. What bounds them is your token budget (402) and the one-in-flight-generation-per-type guard (409).
Conventions
- All IDs are UUIDs.
- Timestamps are ISO 8601 strings in UTC.
- Request bodies use
Content-Type: application/json. - Query parameters are snake_case, matching the column they filter on:
project_id,feature_id,story_id. Theinclude*expansion flags are the exception and are camelCase (includeRelationships,includeAnalysis). - Request bodies are snake_case too (
project_id), with one deliberate exception:/api/crud/schemais camelCase, because it mirrors VibeMap's internalSchemaJSONshape verbatim. - List endpoints support filtering via query parameters — see CRUD endpoints.
Where to go next
- Read/write entities → CRUD endpoints
- Trigger AI generation → Generation endpoints