Skip to content

Projects API

Projects are keyed by slug (URL-safe, 2..63 chars), not by UUID, in every project-scoped path. The UUID still exists as project_id in payloads, but the path parameter and the Z4J agent config both use the slug.

GET /api/v1/projects

Returns only projects the authenticated user has a role in. When the caller is authenticated via a project-scoped bearer key, the response is filtered to only that bound project.

[
{
"id": "...",
"slug": "billing-prod",
"name": "Billing (production)",
"description": null,
"environment": "production",
"timezone": "UTC",
"retention_days": 30,
"is_active": true,
"default_scheduler_owner": "z4j-scheduler",
"allowed_schedulers": null,
"created_at": "...",
"updated_at": "..."
}
]
GET /api/v1/projects/{slug}

Role: viewer. Returns the same ProjectPublic shape.

POST /api/v1/projects

Role: admin of an existing project (or the first admin on a fresh install). CSRF-protected.

{
"slug": "billing-prod",
"name": "Billing (production)",
"description": null,
"environment": "production",
"timezone": "UTC",
"retention_days": 30,
"default_scheduler_owner": "z4j-scheduler",
"allowed_schedulers": null
}

Field rules:

  • slug: 2..63 chars, URL-safe.
  • environment: 1..40 chars, lowercase letters / digits / hyphens / underscores; canonical values are production, staging, development, test but free-form is accepted so existing rows like staging-eu continue to work.
  • retention_days: 1..3650. Default 30. Per-project override of the events retention window.
  • default_scheduler_owner: the scheduler that owns new schedules when the caller did not pick one. Free-form (40 char cap, lowercase pattern). Default z4j-scheduler.
  • allowed_schedulers: optional allow-list of scheduler names. null means unrestricted. Capped at 32 entries.
PATCH /api/v1/projects/{slug}

Role: admin. CSRF-protected. Any subset of the create fields (including the slug itself).

DELETE /api/v1/projects/{slug}

Role: admin. CSRF-protected. Cascades agents, tasks, events, schedules, memberships. The audit log retains the rows with the original project_id for traceability.