API & OpenAPI
The backend is spec-first: backend/openapi.yaml is the source of truth for
the REST API. The server handlers and the typed frontend client are generated
from it — you change the spec first, then regenerate code, never the other way
around.
Multi-file spec layout
Section titled “Multi-file spec layout”The spec is split across multiple files so it stays maintainable:
backend/ openapi.yaml # root: info, servers, components, tags, and $ref index paths/<domain>.yaml # operations, one file per tag/domain schemas/<domain>.yaml # schemas, one file per domainThe convention is one tag = one paths/ file = one schemas/ file.
Resource groups
Section titled “Resource groups”The API is organised into these domains (one paths/*.yaml file each):
| Group | Group |
|---|---|
activities | admin |
agents | api-keys |
artifacts | attachments |
auth | backoffice |
blueprints | comments |
embedding-providers | feeds |
github | github-app-config |
health | invitations |
memories | metadata |
model-providers | notifications |
projects | prompts |
relations | search |
support | team-email-provider |
team-settings | teams |
types | user |
webhooks |
Shared schema definitions live in schemas/common.yaml; other schemas/*.yaml
files mirror the path domains.
Instance-admin API
Section titled “Instance-admin API”The admin domain (paths/admin.yaml) is the instance-admin surface at
/api/v1/admin/*: getAdminStats, listAdminUsers, getAdminUser,
listAdminTeams, and getAdminTeam. It is instance-admin-only. The routes
are mounted behind optional auth plus an instance-admin check, so non-admins and
unauthenticated callers alike get 404. The surface is not advertised.
Resource comments
Section titled “Resource comments”The comments domain (paths/comments.yaml) is new in v0.7.0 and REST-only
(no MCP). It is team-scoped under /api/v1/{team_id}/comments and lets users
comment on resources.
Typed resource relations
Section titled “Typed resource relations”The relations domain (paths/relations.yaml) is team-scoped under
/api/v1/{team_id}/relations and records typed links between prompts,
blueprints, memories and artifacts. Unlike comments, it has both a REST and an
MCP surface: AI tools create links through the vibexp_io_link_resources tool
rather than through the endpoints.
Five operations: listRelations (a resource’s relations), createRelation,
confirmRelation (promote an AI-suggested link to confirmed), deleteRelation,
and seedRelations (backfill suggestions from embedding similarity).
Resource reads carry the result: a GET on a prompt, blueprint, memory or
artifact gains related (typed links) and similar (embedding neighbours). See
Relations for the relation types, the type-constraint
matrix and the suggested-vs-confirmed trust tiers.
Bundling
Section titled “Bundling”The multi-file source is bundled into a single artifact with Redocly before linting, docs, and code generation:
make backend-bundle-openapi# → backend/dist/openapi.bundled.yamlAlways consume the bundle (dist/openapi.bundled.yaml), not the source tree.
Served at runtime
Section titled “Served at runtime”Since v0.5.0 every running instance serves its own bundled spec at
GET /openapi.yaml and GET /openapi.json. The bytes come from a committed,
go:embed-ed bundle in internal/server/openapispec/:
make backend-generate-openapi-bundle # regenerate the embedded bundle (redocly)make backend-openapi-bundle-check # regenerate, then fail on driftCI and pre-commit run the drift check, so regenerate and commit the embedded bundle whenever the spec changes.
Validation & linting
Section titled “Validation & linting”make backend-validate-openapi # structural validation (swagger-cli)make backend-lint-openapi # ruleset linting (vacuum, Spectral-format ruleset)CI runs both, so run them locally before committing.
Code generation
Section titled “Code generation”The bundle drives oapi-codegen, which produces the strict-server bindings and shared types. The generated code is committed and must never be hand-edited:
make backend-generate-openapi-serverSee Code Generation for the full set of generators (oapi-codegen, Wire, mockery) and the golden rules around them.
The API-change flow
Section titled “The API-change flow”A change to the API ripples through the codebase in order:
- Update the spec. Edit
backend/paths/*.yaml/backend/schemas/*.yaml, then regenerate the server (make backend-generate-openapi-server) and implement the handler/service/repository logic. Validate and lint the spec. - The typed clients publish automatically. Merging a spec change to
maintriggers thepublish-api-client.ymlworkflow (path-filtered tobackend/openapi.yaml,backend/paths/**, andbackend/schemas/**), which auto-publishes both generated clients from the spec:@vibexp/api-client(npm, source inapi-client-js) andapi-client-go(Go module, source inapi-client-go). Each downstream repo computes its own next version and generates fromvibexp/vibexp@main. - Bump the frontend dependency. Update the frontend to the new
@vibexp/api-clientversion and use the new endpoints/types.