Policies
/v1/policies/{tenant_id}/{app_id}/{agent_id}/{env}Upsert Policy
Create or update full policy for a scope. Creates a new version each time. Returns the created version. **Authorization**: API key must be allowed to modify this app_id.
Authentication
Send either Authorization: Bearer <token> or X-API-Key: <token>. The caller must hold the "policy:write" role on the organization. Any org token with sufficient scope. Create tokens from the console or the /v1/orgs/{org_id}/tokens endpoints. Requests without a valid credential are rejected with 401.
SDK install
pip install znyx-sdknpm install @znyx/sdkCode samples
Request
curl -X PUT "$ZNYX_API_URL/v1/policies/00000000-0000-0000-0000-000000000000/00000000-0000-0000-0000-000000000000/00000000-0000-0000-0000-000000000000/prod" \
-H "Authorization: Bearer $ZNYX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"change_reason": "Updated PII policy for compliance",
"policy": {
"jailbreak": {
"enabled": true,
"threshold": 50
},
"pii": {
"action": "BLOCK",
"enabled": true
}
}
}'Response
Successful Response
{
"tenant_id": null,
"app_id": "string",
"agent_id": "string",
"env": "string",
"version_number": 0,
"policy": {},
"created_at": "string",
"created_by": "string"
}Schema: object
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| tenant_id#path | string | required | - |
| app_id#path | string | required | - |
| agent_id#path | string | required | - |
| env#path | string | required | - |
Header parameters
| Name | Type | Required | Description |
|---|---|---|---|
| x-created-by#header | string | optional | - |
| X-API-Key#header | string | null | optional | - |
| authorization#header | string | null | optional | - |
Request bodyrequired
| Field | Type | Required | Description |
|---|---|---|---|
| policy | object | required | Full policy JSON configuration |
| change_reason | string | null | optional | Reason for this change |
Responses
| Status | Description |
|---|---|
| 200 | Successful Response |
| 422 | Validation Error |
Response schema
Errors & what triggers them
| Code | Trigger | Fix |
|---|---|---|
| 403 | Caller is not authorized for this app_id (X-API-Key or JWT scope mismatch). | - |
| 422 | Policy JSON failed schema validation - unknown detector, bad threshold. | - |
| 500 | Database contention while writing the new version. | Retry once with fresh `If-Match` if your client sends it. |
Notes & examples
How versioning works
Every call creates a new PolicyVersion row with version_number = latest + 1 and flips it to active. The previous version is retained for rollback — you can always go back with POST .../rollback/{version}.
Authoring flow
1. GET ...?resolved=true to see the current merged policy. 2. Edit the JSON locally (or in the Console's Configure page). 3. PUT the new version with a change_reason — this shows up in the audit log and the UI's Version History drawer. 4. The runtime picks up the new policy within ~60s (or immediately if you use the /v1/bundles/latest ETag poll).
Change reason
Always set change_reason. A month from now you'll want to know *why* PII was upgraded from REDACT to BLOCK. Examples of useful values:
- "Tightened PII for EU customers — legal review ticket LEG-4312"
- "Disabled hallucination for /support agent — too many false positives"
- "Enabled toxicity for marketing bot — compliance requirement"
Related
PATCH .../detector/{name}— change one detector only. Less blast radius.GET .../history— version history.POST /v1/orgs/.../bundles/publish— bake the current policies into a signed bundle for runtimes.