Flag-namespace endpoints
Endpoints for flag-namespace lifecycle and namespace-admin membership.
| Endpoint | Auth | Status |
|---|---|---|
POST /api/v1/tenants/{tenant}/namespaces | tenant admin | v0 |
GET /api/v1/namespaces | authenticated principal | v0 |
GET /api/v1/tenants/{tenant}/namespaces/{namespace} | namespace read or higher | v0 |
DELETE /api/v1/tenants/{tenant}/namespaces/{namespace} | tenant admin | deferred |
GET /api/v1/tenants/{tenant}/namespaces/{namespace}/admins | namespace admin or higher | deferred |
PUT /api/v1/tenants/{tenant}/namespaces/{namespace}/admins/{user_id} | namespace admin or higher | deferred |
DELETE /api/v1/tenants/{tenant}/namespaces/{namespace}/admins/{user_id} | namespace admin or higher | deferred |
See conventions for the auth header, error envelope, pagination, and rate limits.
Slug uniqueness. Flag-namespace slugs are unique per-tenant, not globally. Two tenants on the same installation may both own a
paymentsnamespace; every namespace-scoped URL therefore carries the owning tenant in its path so the(tenant, slug)pair is unambiguous. The cross-tenantGET /api/v1/namespacesis the only namespace endpoint that is not tenant-scoped in the path; it is reserved for superadmin tooling.
POST /api/v1/tenants/{tenant}/namespaces
Create a new flag namespace in {tenant}. The creator is added as the first namespace admin. Namespace creation does NOT automatically issue service tokens — create explicit tokens afterward with POST /api/v1/tokens.
Auth required: tenant_admin for {tenant}, tenant-admin token bound to {tenant}, or superadmin. Permission: namespace.create.
Path parameters
| Parameter | Description |
|---|---|
tenant | The owning tenant slug. The principal must be authorized for this tenant. |
Request body
{
"slug": "payments",
"display_name": "Payments Team",
"description": "Feature flags for the payments service and checkout domain"
}
| Field | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Flag-namespace slug. Pattern [a-z][a-z0-9-]*, max 63 chars. Unique within {tenant}. Immutable. |
display_name | string | no | Human-readable name. Defaults to the slug. |
description | string | no | Free-form description. |
Response: 201 Created
{
"namespace": {
"tenant_slug": "acme",
"slug": "payments",
"display_name": "Payments Team",
"description": "Feature flags for the payments service and checkout domain",
"created_at": "2026-04-25T09:14:33Z",
"manifest_version": null,
"flag_count": 0,
"segment_count": 0
},
"request_id": "01HV5XK2GFQT8N3JRDCP7MW04B"
}
Example
curl -X POST https://exd.example.com/api/v1/tenants/acme/namespaces \
-H "Authorization: Bearer exd_tenant_5cNpQrStUvWxYzAbCdEfGhJkLmNoPqRsTuVwXz" \
-H "Content-Type: application/json" \
-d '{
"slug": "payments",
"display_name": "Payments Team",
"description": "Feature flags for the payments service and checkout domain"
}'
GET /api/v1/namespaces
List flag namespaces the authenticated principal has access to, across tenants.
Auth required: authenticated user, tenant-admin, superadmin, namespace-read, or namespace-write. List endpoints filter to the principal's visible scope:
- Tenant admins see all namespaces in their tenant.
- Namespace admins see namespaces where they hold that role.
- Namespace-scoped tokens see only their bound flag namespace.
- Superadmin tokens see every flag namespace in the installation.
This is the only flag-namespace endpoint NOT scoped under /api/v1/tenants/{tenant}/. It exists so superadmin tooling and cross-tenant principals can enumerate without iterating tenants.
Query parameters
| Parameter | Description |
|---|---|
tenant | Optional. Limit to a single tenant. Tenant- and namespace-scoped tokens are implicitly filtered to their bound scope and may not widen via tenant=. |
limit, after | Pagination. |
Response: 200 OK
{
"namespaces": [
{
"tenant_slug": "acme",
"slug": "payments",
"display_name": "Payments Team",
"description": "Feature flags for the payments service and checkout domain",
"created_at": "2026-04-25T09:14:33Z",
"manifest_version": 7,
"flag_count": 12,
"segment_count": 4,
"current_user_roles": ["tenant_admin"]
},
{
"tenant_slug": "acme",
"slug": "identity",
"display_name": "Identity & Auth Team",
"description": "Flags for login, MFA, and session management",
"created_at": "2026-03-10T14:22:11Z",
"manifest_version": 3,
"flag_count": 5,
"segment_count": 2,
"current_user_roles": ["namespace_admin"]
}
],
"next_cursor": null,
"request_id": "01HV5XK3RFQT8N3JRDCP7MW04C"
}
Example
curl https://exd.example.com/api/v1/namespaces \
-H "Authorization: Bearer exd_admin_2mNpQrStUvWxYzAbCdEfGhJkLmNoPqRsTuVwXy"
GET /api/v1/tenants/{tenant}/namespaces/{namespace}
Retrieve metadata for a single flag namespace.
Auth required: tenant_admin for {tenant}, namespace admin, tenant-admin token bound to {tenant}, superadmin, namespace-read, or namespace-write bound to (tenant, namespace). Permission: namespace.read.
Path parameters
| Parameter | Description |
|---|---|
tenant | The owning tenant slug. |
namespace | The flag-namespace slug, unique within {tenant}. |
Response: 200 OK
{
"namespace": {
"tenant_slug": "acme",
"slug": "payments",
"display_name": "Payments Team",
"description": "Feature flags for the payments service and checkout domain",
"created_at": "2026-04-25T09:14:33Z",
"manifest_version": 7,
"manifest_uploaded_at": "2026-04-25T11:30:00Z",
"flag_count": 12,
"segment_count": 4,
"telemetry_enabled": true,
"current_user_roles": ["namespace_admin"],
"environments": {
"development": { "display_name": "Development" },
"staging": { "display_name": "Staging" },
"production": { "display_name": "Production" }
}
},
"request_id": "01HV5XK4SFQT8N3JRDCP7MW04D"
}
Example
curl https://exd.example.com/api/v1/tenants/acme/namespaces/payments \
-H "Authorization: Bearer exd_read_4tRvBn9wKjMpXzQsUyAeCdFgHiJkLnOqRtWvYb"
DELETE /api/v1/tenants/{tenant}/namespaces/{namespace}
Deferred. Not implemented in v0.
Permanently delete a flag namespace and all its manifest history. This action is irreversible.
Auth required: tenant_admin for {tenant}, tenant-admin token bound to {tenant}, or superadmin. Permission: namespace.delete.
Request body
A confirmation token MUST be supplied to prevent accidental deletion.
{
"confirmation_token": "payments-delete"
}
confirmation_token must equal <namespace-slug>-delete. Mismatch → 400 invalid_request.
Response: 200 OK
{
"deleted": true,
"namespace": "payments",
"request_id": "01HV5XK5TFQT8N3JRDCP7MW04E"
}
Example
curl -X DELETE https://exd.example.com/api/v1/tenants/acme/namespaces/payments \
-H "Authorization: Bearer exd_admin_2mNpQrStUvWxYzAbCdEfGhJkLmNoPqRsTuVwXy" \
-H "Content-Type: application/json" \
-d '{"confirmation_token": "payments-delete"}'
GET /api/v1/tenants/{tenant}/namespaces/{namespace}/admins
Deferred. Not implemented in v0.
List explicit namespace admins of a flag namespace. Tenant admins have effective admin rights even when not listed here.
Auth required: tenant_admin for {tenant}, namespace admin, tenant-admin token bound to {tenant}, or superadmin. Permission: namespace.admin.read.
Response: 200 OK
{
"admins": [
{
"user_id": "usr_01HV5Z9R4Y0XJ7A2W8WJ9R7S3A",
"email": "owner@acme.example",
"added_at": "2026-04-25T09:14:33Z",
"added_by": "usr_01HV5Z8Q6WRQZF4C8A7Y3DSN9K"
}
],
"request_id": "01HV5XK5ZFQT8N3JRDCP7MW04Z"
}
PUT /api/v1/tenants/{tenant}/namespaces/{namespace}/admins/{user_id}
Deferred. Not implemented in v0.
Grant namespace-admin access to a user in {tenant}.
Auth required: tenant_admin for {tenant}, namespace admin, tenant-admin token, or superadmin. Permission: namespace.admin.manage.
Response: 204 No Content
DELETE /api/v1/tenants/{tenant}/namespaces/{namespace}/admins/{user_id}
Deferred. Not implemented in v0.
Revoke explicit namespace-admin access. The server rejects removal of the final explicit namespace admin unless the flag namespace belongs to an email-domain tenant (where all users are tenant admins by definition).
Auth required: tenant_admin for {tenant}, namespace admin, tenant-admin token, or superadmin. Permission: namespace.admin.manage.
Response: 204 No Content
See also
- tenants — flag namespaces nest under tenants.
- manifest — the next thing you push after creating a flag namespace.
- tokens — mint service tokens scoped to the new flag namespace.
- access-control § Namespace admin — what
namespace_admincan do. exd-server-admin namespace create— operator CLI alternative.