understudydocs

control plane api

Projects

Projects are addressed by slug — the immutable, org-unique identity that travels on x-understudy-project. Names are display-only and freely renameable; deletion is soft and frees the slug for reuse.

Endpoints

method & pathdoes
GET /admin/v1/orgs/:org_id/projectsList live projects. Cursor-paginated (limit 1–100, default 20).
POST /admin/v1/orgs/:org_id/projectsCreate. Body: { "slug", "name" }. 409 if the slug is taken by a live project.
POST /admin/v1/orgs/:org_id/projects/defaultIdempotently ensure the default rehearsal project (and its main workload) exists; returns it either way.
GET /admin/v1/orgs/:org_id/projects/:slugFetch one by slug. 404 if absent or soft-deleted.
PATCH /admin/v1/orgs/:org_id/projects/:slugRename. Body: { "name" }. The slug itself is immutable.
DELETE /admin/v1/orgs/:org_id/projects/:slugSoft-delete: drops out of listings, stops resolving on the gateway, slug becomes reusable. Captures already written remain in storage.

The project object

shape
{
  "id": "proj_...",              // stable internal id (used in workload routes)
  "org_id": "org_...",
  "slug": "concierge",           // immutable; the header identity
  "name": "Concierge",           // display only
  "created_at": "2026-06-12T00:00:00Z",
  "settings": {},                // reserved
  "deleted_at": null
}

Note the two identifiers: slug addresses projects in these URLs and in the scoping header; id is what workload and capture endpoints take. GET by slug is the bridge between them.