Bundles
/v1/orgs/{org_id}/projects/{project_id}/envs/{env_name}/bundles/publishPublish Bundle
Publish a new policy bundle for an environment.
Authentication
Send either Authorization: Bearer <token> or X-API-Key: <token>. The caller must hold the "bundle:publish" role on the organization. CI token — create via POST /v1/orgs/{org_id}/tokens/ci. Project-scoped, allows the bundle lifecycle. Requests without a valid credential are rejected with 401.
SDK install
pip install znyx-sdknpm install @znyx/sdkCode samples
Request
curl -X POST "$ZNYX_API_URL/v1/orgs/00000000-0000-0000-0000-000000000000/projects/00000000-0000-0000-0000-000000000000/envs/prod/bundles/publish" \
-H "Authorization: Bearer $ZNYX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"policies": {},
"scope_policies": null,
"include_agent_overrides": true,
"published_by": "ui"
}'Response
Successful Response
{
"id": "string",
"version": 0,
"policy_hash": "string",
"is_active": false,
"published_by": null,
"published_at": "string",
"scope_count": 0
}Schema: object
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org_id#path | string | required | - |
| project_id#path | string | required | - |
| env_name#path | string | required | - |
Header parameters
| Name | Type | Required | Description |
|---|---|---|---|
| X-API-Key#header | string | null | optional | - |
| authorization#header | string | null | optional | - |
Request bodyrequired
| Field | Type | Required | Description |
|---|---|---|---|
| policies | object | required | Default/env-level policy configuration |
| scope_policies | object | null | optional | Optional explicit map: 'tenant:app:agent:env' -> policy dict. When omitted and include_agent_overrides is true the server auto-collects per-agent overrides from policy_scopes. |
| include_agent_overrides | boolean | optional | If true and scope_policies is omitted, auto-collect all non-default agent overrides for this (org, project, env). |
| published_by | string | optional | - |
Responses
| Status | Description |
|---|---|
| 200 | Successful Response |
| 422 | Validation Error |
Response schema
Errors & what triggers them
| Code | Trigger | Fix |
|---|---|---|
| 403 | Token lacks the `bundle:publish` scope (runtime tokens are rejected). | Use a CI token (POST /v1/orgs/{org_id}/tokens/ci) or an admin token. |
| 404 | Project or environment does not exist in the org. | - |
| 422 | Bundle version quota (per plan) exceeded for the environment. | Delete old versions via the Bundles page or upgrade your plan. |
| 500 | Policy signing failed (missing or malformed signing key). | Contact support - this is an operator-side configuration issue. |
Notes & examples
Why bundles
Runtimes don't read policies directly from the database. They fetch signed bundles — a snapshot of the resolved policy for a specific (project, environment), stamped with a hash and signed. This gives you:
- Atomic rollouts — one publish == one version the runtime can pin to.
- Tamper evidence — the runtime verifies the signature.
- CI/CD friendliness — publish in CI, promote to staging, promote to prod on approval.
Typical CI flow
# After policy changes land on main:
curl -X POST \
https://api.znyx.ai/v1/orgs/$ORG/projects/$PROJ/envs/dev/bundles/publish \
-H "Authorization: Bearer $ZNYX_CI_TOKEN" \
-d '{ "policies": { ... }, "published_by": "ci" }'
# ...after smoke tests pass:
curl -X POST \
https://api.znyx.ai/v1/orgs/$ORG/projects/$PROJ/envs/dev/promote \
-H "Authorization: Bearer $ZNYX_CI_TOKEN"The promote endpoint flips dev → staging → prod. Direct activate is also available if you need to pin a specific older version.
Webhook events
Every publish/activate/promote emits a webhook event you can subscribe to. Use these for CI-to-CI handoff, Slack notifications, or feeding your SIEM.
bundle.publishedbundle.activatedbundle.promoted
Related
POST .../bundles/{version}/activate— pin a specific version.POST .../envs/{source}/promote— move active bundle forward (dev → staging → prod).GET /v1/bundles/latest— runtime fetch.