Reference
Management API Reference
Create and update flags, targets, and targeting rules, and read the audit trail programmatically with scoped Bearer tokens.
Overview
The Management API lets you create and update feature flags, read and roll out targets, manage targeting rules, and read your account's audit trail — all at https://api.zenmanage.com under the /management/v1 path.
This is a distinct API from the public evaluation API: it authenticates with scoped Bearer tokens instead of platform keys, and it manages configuration rather than evaluating flags for a context. Use it to build internal tooling, CI/CD gates, or automation around your flag configuration.
Prerequisites
- A management API token generated in the Zenmanage admin app, with the scopes your integration needs.
- The project (and environment, for target/rule endpoints) key you're operating on.
- A plan for handling 429s and 422s — write traffic should back off and re-validate rather than retry blindly.
Authentication and scopes
Every request must include a management token as a Bearer token:
GET /management/v1/projects/your-project/flags HTTP/1.1
Host: api.zenmanage.com
Authorization: Bearer mgt_your_token_here
Tokens are scoped. A token missing the scope an operation requires gets a 403, even if the token itself is valid.
| Scope | Grants |
|---|---|
| flags:read | List and read flags. |
| flags:write | Create, update, and delete flags. |
| targets:write | Read and update targets and targeting rules — there is no separate read scope for these. |
| audit:read | Read the account audit trail. |
Rate limits
Each token is rate limited per minute; the limit depends on the token's tier.
| Tier | Requests / minute |
|---|---|
| standard | 60 |
| elevated | 300 |
| unlimited | No enforced ceiling |
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. Exceeding the limit returns a 429 with a Retry-After header and body {"status":"error","message":"Rate limit exceeded."}. Contact hello@zenmanage.com if your token needs a higher tier.
Error envelope
Most errors — auth failures, missing scopes, not-found resources, rate limits — share one envelope:
{
"status": "error",
"message": "Flag not found."
}
A missing-scope 403 adds a required_scope field alongside status/message.
422s on flag and targeting-rule bodies are the exception — those are request-validation failures, and instead return Laravel's field-keyed shape:
{
"message": "The key field is required.",
"errors": {
"key": ["The key field is required."]
}
}
Two operations don't follow that split: audit log query-parameter errors always use the standard envelope, and rollout updates can return either shape depending on what failed — a bad rollout_percentage uses the field-keyed shape, while "target isn't published" or "target has no active rollout" use the standard one.
Idempotency keys
POST and PUT requests accept an optional Idempotency-Key header, up to 255 characters. Replaying the same key with the same request body and token returns the original response instead of repeating the operation, marked with X-Idempotent-Replayed: true. Replays are honored for 24 hours; only successful and client-error responses are cached, so a 500 is never replayed.
Pagination
The flags list and audit logs list are cursor-paginated: pass the previous response's meta.next_cursor as the cursor query parameter to fetch the next page. A null cursor means there are no more results. per_page defaults to 25 and is capped at 100. Targets and targeting rules are returned as full, unpaginated arrays — each is a bounded set scoped to one target.
OpenAPI specification
Zenmanage publishes an OpenAPI v3 document for the Management API at https://api.zenmanage.com/management/v1/api-docs. Use it for client generation, schema validation, and endpoint exploration. This page mirrors that spec — if the two ever disagree, treat the spec as authoritative.
Endpoint catalog
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /projects/{projectKey}/flags | flags:read | List flags in a project, paginated. |
| GET | /projects/{projectKey}/flags/{flagKey} | flags:read | Read a single flag. |
| POST | /projects/{projectKey}/flags | flags:write | Create a flag. |
| PUT | /projects/{projectKey}/flags/{flagKey} | flags:write | Update a flag's name, description, or platform inclusion. Key and type are immutable. |
| DELETE | /projects/{projectKey}/flags/{flagKey} | flags:write | Delete a flag. |
| GET | .../targets | targets:write | List targets for a flag in an environment. |
| GET | .../targets/{targetUlid} | targets:write | Read a single target. |
| PUT | .../targets/{targetUlid}/rollout | targets:write | Update a published target's rollout percentage. |
| GET | .../targets/{targetUlid}/rules | targets:write | List targeting rules for a target, in evaluation order. |
| POST | .../targets/{targetUlid}/rules | targets:write | Create a targeting rule. |
| PUT | .../targets/{targetUlid}/rules/{ruleUlid} | targets:write | Replace a targeting rule's value, description, and criteria. |
| DELETE | .../targets/{targetUlid}/rules/{ruleUlid} | targets:write | Delete a targeting rule. |
| GET | /audit-logs | audit:read | List audit log entries for the account, paginated and filterable. |
All target and target-rule paths are prefixed with /projects/{projectKey}/flags/{flagKey}/environments/{environmentKey}, shortened above for width. All paths shown are relative to https://api.zenmanage.com/management/v1.
Example requests
Create a flag. key must be lowercase alphanumeric with hyphens/underscores, unique within the project. include_in_mobile/include_in_client both default to true.
{
"key": "new-checkout",
"name": "New Checkout",
"type": "boolean",
"description": "Rolls out the redesigned checkout flow."
}
{
"status": "success",
"data": {
"ulid": "flg_01hzy9m2qj1q1jz3sd4xg9n1vb",
"key": "new-checkout",
"name": "New Checkout",
"type": "boolean",
"description": "Rolls out the redesigned checkout flow.",
"permanent": false,
"include_in_mobile": true,
"include_in_client": true,
"created_at": "2026-07-28T12:00:00+00:00",
"updated_at": "2026-07-28T12:00:00+00:00"
}
}
List flags. Also supports type and search filters.
{
"status": "success",
"data": [
{ "ulid": "flg_01hzy9m2qj1q1jz3sd4xg9n1vb", "key": "new-checkout", "name": "New Checkout", "type": "boolean", "description": null, "permanent": false, "include_in_mobile": true, "include_in_client": true, "created_at": "2026-07-28T12:00:00+00:00", "updated_at": "2026-07-28T12:00:00+00:00" }
],
"meta": {
"per_page": 25,
"next_cursor": null,
"prev_cursor": null
}
}
Update a rollout percentage. The target must already be published and have an active rollout — otherwise this returns a 422 with the standard error envelope rather than a validation error.
{ "rollout_percentage": 25 }
{
"status": "error",
"message": "Rollout can only be updated on published targets."
}
Create a targeting rule. comparer depends on selector: context and segment selectors only accept equal, notequal, in, notin; attribute additionally accepts gt, gte, lt, lte, isnull, notnull, contains, notcontains, startswith, endswith, notstartswith, notendswith. Sending a comparer that doesn't match the selector returns a validation-shape 422. values is required unless comparer is isnull/notnull.
{
"value_ulid": "val_01hzy9m2qj1q1jz3sd4xg9n1vb",
"description": "US enterprise accounts",
"criteria": {
"selector": "attribute",
"comparer": "equal",
"sub_selector": "country",
"values": ["US"]
}
}
List audit log entries. Filterable by from/to, result, subject_type/subject_ulid, management_token_ulid, and actor_ulid. action filtering currently only covers auth and flag actions (not target/target-rule actions) — those entries still appear in unfiltered results.
{
"status": "success",
"data": [
{
"ulid": "aud_01hzy9m2qj1q1jz3sd4xg9n1vb",
"actor": { "type": "user", "ulid": "usr_...", "name": "Jane Doe", "email": "jane@example.com" },
"token": { "ulid": "mgt_...", "name": "CI deploy token" },
"http_method": "PUT",
"http_path": "/management/v1/projects/your-project/flags/new-checkout/environments/staging/targets/.../rollout",
"action": "target.rollout_updated",
"subject_type": "target",
"subject_ulid": "tgt_...",
"subject_label": "new-checkout / staging",
"result": "success",
"status_code": 200,
"created_at": "2026-07-28T12:05:00+00:00"
}
],
"meta": {
"per_page": 25,
"sort": "created_at_desc",
"next_cursor": null
}
}
Common errors
400 Bad Request: the Idempotency-Key header exceeds 255 characters.
401 Unauthorized: the Bearer token is missing, invalid, revoked, or expired.
403 Forbidden: the token is valid but lacks the required scope, or lacks a grant for the project/environment.
404 Not Found: the project, environment, flag, target, or rule in the path doesn't exist, or the token has no grant for it.
422 Unprocessable Entity: request body or query parameters failed validation — see the error envelope section above for the exact shape.
429 Too Many Requests: the token's rate limit was exceeded — back off using the Retry-After header.
Next step
Take the next integration step in your own stack.
Start with the quickstart that matches your runtime, then return to the reference pages when you need exact request and payload details.