Skip to main content

Bundles

POST/v1/orgs/{org_id}/projects/{project_id}/envs/{env_name}/bundles/publish

Publish Bundle

Publish a new policy bundle for an environment.

CI tokenscope: bundle:publishoperation_id: bundles.publish

Authentication

Create via POST /v1/orgs/{org_id}/tokens/ci. Project-scoped, allows bundle lifecycle.

SDK install

pip install znyx-sdknpm install @znyx/sdk

Path parameters

NameTypeRequiredDescription
org_id#pathstringrequired
project_id#pathstringrequired
env_name#pathstringrequired

Header parameters

NameTypeRequiredDescription
X-API-Key#headerstring | nulloptional
authorization#headerstring | nulloptional

Request bodyrequired

FieldTypeRequiredDescription
policiesobjectrequiredThe resolved policy configuration
published_bystringoptional

Responses

StatusDescription
200Successful Response
422Validation Error

Response schema

idrequiredstring
versionrequiredinteger
policy_hashrequiredstring
is_activerequiredboolean
published_byrequiredstring | null
published_atrequiredstring

Errors & what triggers them

CodeTriggerFix
403Token lacks the `bundle:publish` scope (runtime tokens are rejected).Use a CI token (POST /v1/orgs/{org_id}/tokens/ci) or an admin token.
404Project or environment does not exist in the org.
422Bundle version quota (per plan) exceeded for the environment.Delete old versions via the Bundles page or upgrade your plan.
500Policy 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.published
  • bundle.activated
  • bundle.promoted
  • 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.

Request

curl -X POST 'https://api.znyx.ai/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": {},
  "published_by": "ui"
}'

Response

application/json

Successful Response

{
  "id": "string",
  "version": 0,
  "policy_hash": "string",
  "is_active": false,
  "published_by": null,
  "published_at": "string"
}

Schema: object