Skip to content

Projects API

Document ID: API-008
File Path: docs/09-api/projects.md
Version: 1.2.0
Status: Draft
Owner: AI Platform Team
Last Updated: 2026-07-14


This document defines the API for managing the platform’s tenancy hierarchy — organizations, projects, and their settings, quotas, and members. These resources scope every other resource in the platform.

All endpoints inherit the API conventions and require authentication.


Tenant (billing/isolation boundary)
└── Organization
└── Project
└── resources (agents, workflows, memory, plugins, …)
ResourceDescription
organizationA company/group within a tenant
projectA workspace owning resources and config
membershipA user’s role within an org/project
quotaResource/cost limits for an org or project

Every resource in the platform carries tenant + project scoping (see Overview §5); isolation is enforced everywhere (e.g. Memory, Tool Runtime).


MethodPathScope
GET/api/v1/organizationsprojects:read
POST/api/v1/organizationsorg.admin
GET/api/v1/projectsprojects:read
POST/api/v1/projectsprojects:admin
GET/api/v1/projects/{id}projects:read
PATCH/api/v1/projects/{id}projects:admin
DELETE/api/v1/projects/{id}projects:admin
GET/api/v1/projects/{id}/membersprojects:read
POST/api/v1/projects/{id}/membersprojects:admin
DELETE/api/v1/projects/{id}/members/{uid}projects:admin
GET/api/v1/projects/{id}/quotaprojects:read
PATCH/api/v1/projects/{id}/quotaorg.admin

{
"id": "prj_01H...",
"object": "project",
"name": "support-bot",
"organization": "org_01H...",
"tenant": "acme",
"settings": {
"default_model_class": "balanced",
"marketplace_policy": { "require_verified": true }
},
"status": "active"
}

settings carry project-level defaults consumed by other subsystems — e.g. default routing class and marketplace policy.


Projects and organizations carry quotas enforced across subsystems:

{
"object": "quota",
"scope": "project",
"limits": {
"llm_cost_per_day_usd": 250,
"llm_tokens_per_day": 5000000,
"concurrent_agent_runs": 50,
"day_reset_offset_minutes": 330
}
}

All three are enforced at the agent-run admission boundary (X-Wovyr-Project): concurrent runs, the rolling day’s USD spend, and — RM-AIM-P2 SRV-202 — the rolling day’s token usage (llm_tokens_per_day, the vendor-bill-independent twin of the cost budget: a local model costs $0/token but still burns capacity). Breaches return 429/402 per the error model.

The “day” the daily budgets roll over on is configurable per quota (RM-AIM-P2 SRV-203): day_reset_offset_minutes places the reset boundary in minutes east of UTC (e.g. 330 resets at 00:00 IST, -300 at 00:00 EST; minutes rather than whole hours because real timezones include half- and quarter-hour offsets). Absent, budgets reset at 00:00 UTC exactly as before. The offset is clamped to ±24 h, and admission and usage-recording always resolve the same boundary, so usage never leaks across a tenant’s local midnight. Wall-clock is read only at the server boundary per the clock-free-core rule.

Two dimensions this section originally speculated (tool_executions_per_minute, memory_records) were removed in SRV-202 rather than enforced: they were declared but checked nowhere — dead config an operator could set and reasonably believe was protecting them. Tool executions happen inside the agent loop where no per-project window tracker exists (request-level abuse is the rate limiter’s job, which since SRV-202 also has an opt-in per-tenant tier, WOVYR_RATE_LIMIT_TENANT_PER_MIN), and memory records are tenant-namespaced while quotas are project-scoped, so “a project’s record count” was never well-defined. A stored quota still carrying the old fields deserializes fine — they are simply ignored.


Members are assigned roles (see Authentication §8) scoped to an org or project:

POST /api/v1/projects/prj_01H.../members
{ "user": "user_01H...", "role": "editor" }

A user’s effective permissions are the union of their memberships, intersected with any API-key scope restriction.


Organization settings (defaults)
│ overridden by
Project settings
│ overridden by
Per-request parameters

A project inherits org defaults and may override them; individual requests may override further within policy-allowed bounds.


  • Deleting a project soft-deletes it and schedules its resources for cleanup (memory archived/purged per retention, plugins disabled, runs cancelled).
  • Suspending a project blocks new operations while preserving data.

Emits project.created, project.updated, project.member.added, quota.updated, project.suspended to the Event Bus.


Uses the standard error envelope. Notable codes: forbidden (admin required), conflict (name exists), quota_exceeded.




VersionDateDescription
1.0.02026-06-27Initial Projects API specification
1.1.02026-07-14§5: llm_tokens_per_day budget added; dead tool_executions_per_minute/memory_records dimensions removed (RM-AIM-P2 SRV-202)
1.2.02026-07-14§5: tenant-configurable daily-reset boundary day_reset_offset_minutes (RM-AIM-P2 SRV-203)