Policy Management

Create and manage guardrails for your AI applications

Overview

Manage security policies for Cygnal. Create, list, update, and delete policies; export and import; view version history. Policies define rules, thresholds, modes, and optional scanner config used by Cygnal.


Authentication

All policy endpoints require a valid Gray Swan API key. You can pass it in either header:

  • Authorization: Bearer <api_key>
  • x-api-key: <api_key>

List, get, export, and version endpoints are available to any organization user. Create, update, delete, and import require an admin for the organization. Non-admin calls to those endpoints return 403 ADMIN_REQUIRED.


Endpoints

MethodPathDescriptionAdmin Required
GET/policiesList all policiesX
GET/policies/exportExport all policiesX
GET/policies/{policy_id}Get one policyX
GET/policies/{policy_id}/exportExport one policyX
GET/policies/{policy_id}/versionsList version historyX
GET/policies/{policy_id}/versions/{version_id}Get policy at versionX
POST/policiesCreate policy
POST/policies/importImport one policy
POST/policies/bulk-importBulk import (1–100)
PUT/policies/{policy_id}Update policy (no presets)
DELETE/policies/{policy_id}Delete policy (no presets)

List Policies

GET /policies

Returns policies for the organization, sorted by most recently updated. By default (no limit), returns all policies. When limit is provided, uses offset pagination.

Query Params

  • limit (integer, optional): Maximum number of policies to return. If omitted, returns all policies. Min 1, max 1000 when provided.
  • offset (integer, optional): Number of policies to skip. Default 0, min 0

Response

Returns a PolicyListResponse object:

  • policies: array of policy objects
  • total: total number of policies (regardless of limit)
  • limit: applied limit (null if no limit was applied)
  • offset: applied offset
  • has_more: boolean indicating if more results are available beyond the current page (only true when limit is applied and more results exist)
import os
import requests

# Get all policies (no pagination)
response = requests.get(
    "https://api.grayswan.ai/policies",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
    },
)
data = response.json()
print(f"Total policies: {data['total']}")
print(f"Policies returned: {len(data['policies'])}")

# Get paginated results
response = requests.get(
    "https://api.grayswan.ai/policies",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
    },
    params={
        "limit": 50,
        "offset": 0,
    },
)
data = response.json()
print(f"Has more: {data['has_more']}")

Export All Policies

GET /policies/export

import os
import requests

response = requests.get(
    "https://api.grayswan.ai/policies/export",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
    },
)

Get Policy by ID

GET /policies/{policy_id}

import os
import requests

policy_id = "YOUR_POLICY_ID"

response = requests.get(
    f"https://api.grayswan.ai/policies/{policy_id}",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
    },
)

Export Policy by ID

GET /policies/{policy_id}/export

import os
import requests

policy_id = "YOUR_POLICY_ID"

response = requests.get(
    f"https://api.grayswan.ai/policies/{policy_id}/export",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
    },
)

List Versions

GET /policies/{policy_id}/versions

import os
import requests

policy_id = "YOUR_POLICY_ID"

response = requests.get(
    f"https://api.grayswan.ai/policies/{policy_id}/versions",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
    },
)

Get Policy at Version

GET /policies/{policy_id}/versions/{version_id}

import os
import requests

policy_id = "YOUR_POLICY_ID"
version_id = "VERSION_ID"

response = requests.get(
    f"https://api.grayswan.ai/policies/{policy_id}/versions/{version_id}",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
    },
)

Create Policy

POST /policies

import os
import requests

response = requests.post(
    "https://api.grayswan.ai/policies",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
        "Content-Type": "application/json",
    },
    json={
        "name": "Strict policy",
        "description": "Blocks unsafe requests",
        "categories": {
            "self_harm": "Detect self-harm guidance",
            "illicit_behavior": "Detect criminal instructions"
        },
        "mode": "content_moderation",
        "pre_violation_threshold": 0.6
    },
)

Import Policy

POST /policies/import

import os
import requests

response = requests.post(
    "https://api.grayswan.ai/policies/import",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
        "Content-Type": "application/json",
    },
    json={
        "policy": {
            "name": "Imported policy",
            "description": "Imported from export payload",
            "categories": {"abuse": "Detect abusive content"},
            "mode": "content_moderation",
            "pre_violation_threshold": 0.5,
            "pre_jb_threshold": 0.3,
            "post_violation_threshold": 0.5,
            "post_violation_jb_threshold": 0.3
        }
    },
)

IDs in payload are ignored and new IDs are generated.


Bulk Import Policies

POST /policies/bulk-import

import os
import requests

response = requests.post(
    "https://api.grayswan.ai/policies/bulk-import",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
        "Content-Type": "application/json",
    },
    json={
        "policies": [
            {
                "name": "Policy A",
                "categories": {"harassment": "Detect harassment"},
                "mode": "content_moderation"
            },
            {
                "name": "Policy B",
                "categories": {"hate": "Detect hate speech"},
                "mode": "content_moderation"
            }
        ]
    },
)

Update Policy

PUT /policies/{policy_id}

import os
import requests

policy_id = "YOUR_POLICY_ID"

response = requests.put(
    f"https://api.grayswan.ai/policies/{policy_id}",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
        "Content-Type": "application/json",
    },
    json={
        "description": "Updated policy description",
        "post_violation_threshold": 0.45
    },
)

Delete Policy

DELETE /policies/{policy_id}

import os
import requests

policy_id = "YOUR_POLICY_ID"

response = requests.delete(
    f"https://api.grayswan.ai/policies/{policy_id}",
    headers={
        "Authorization": f"Bearer {os.environ.get('GRAYSWAN_API_KEY')}",
    },
)

On this page