AI policies
An AI policy is the set of AI controls one scope sets for itself: which models and modalities may run, whether the Layer agent and each subagent may run, the spend above which the agent asks before a job, and the parameter values a generation on a model starts from. The AI Policies endpoints let a workspace’s admins read and change them from a script, the same as Settings > AI Controls in the app. The same operations are on the management MCP server.
Scopes and precedence
Section titled “Scopes and precedence”A policy is attached to one scope, and holds only what that scope sets itself. Everything else is inherited from the less specific scopes, in this order:
- the workspace (and, for a workspace under another, the workspaces above it)
- a project in it, for work done in that project
- the groups the member belongs to
- the member: a user, service account or API key
The most specific scope that sets a value wins. Where a member’s groups disagree, the most permissive value wins: belonging to a stricter group never takes away what another group grants. Model defaults are the exception: groups that disagree on a default cancel out, and the member inherits it from the less specific scopes.
A workspace or project can lock a value. A locked value holds for every scope below the one that set it, which cannot override it. Group and member policies cannot lock.
The controls
Section titled “The controls”Every value is a setting, { "value": …, "locked": false }. Maps hold one setting per key, so each model, modality or subagent is inherited, overridden and locked on its own.
| Control | Value | What it does |
|---|---|---|
agent_enabled |
boolean | The Layer agent as a whole. |
agents |
map of principal id to boolean | Each subagent, by the principal it acts as. |
agent_confirm_above_cu |
number | The Creative Units above which the agent asks before running a job. |
modalities |
map of modality to boolean | IMAGE, VIDEO, THREE_D, AUDIO, TEXT on or off. |
new_models_enabled |
boolean | Whether a model models does not name may run: true makes models a deny list, false an allow list. |
models |
map of base model id to boolean | Each base model on or off. |
model_defaults |
map of base model id to a map of parameter to value | The parameter values a generation on the model starts from. |
nsfw_tolerance |
1 to 6 | How much NSFW content generations may produce: 1 is the strictest. Workspaces and projects only. |
reference_set_sharing_enabled |
boolean | Whether the workspace’s reference sets may be shared beyond it. Workspaces only. |
workflow_sharing_enabled |
boolean | Whether the workspace’s workflows may be shared beyond it. Workspaces only. |
Three more controls appear in reads and are kept when a policy is replaced or cleared:
| Control | Value | What it does |
|---|---|---|
usage_caps |
map of daily, weekly or monthly to {cu_limit, mode, warn_threshold_pct} |
The Creative Units each member may spend in the workspace per period. mode is warn or block; a null value lifts a cap set above. Set it with a patch, which takes the billing admin permission as well; a group’s cap can also be set with the group usage-limit endpoints. |
guardrails |
map of rule id to boolean | Input guardrail rules, written by their own feature. A patch that names it is refused. |
output_scoring |
map of rule id to boolean | Output scoring rules, written by their own feature. A patch that names it is refused. |
Read a scope’s policy
Section titled “Read a scope’s policy”Each scope has its policy at its own path:
| Scope | Path |
|---|---|
| Workspace | /v2/workspaces/{workspace_id}/ai-policy |
| Project | /v2/workspaces/{workspace_id}/projects/{project_id}/ai-policy |
| Group | /v2/workspaces/{workspace_id}/groups/{group_id}/ai-policy |
| Member | /v2/workspaces/{workspace_id}/members/{principal_id}/ai-policy |
curl https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/groups/$GROUP_ID/ai-policy \ -H "Authorization: Bearer $LAYER_TOKEN"The response holds the policy the scope sets itself and what it inherited from the less specific scopes, each inherited value with the source scope that set it and whether that scope locked it. A value with no source is the platform default. A scope that sets nothing returns an empty policy.
Change it
Section titled “Change it”-
Patch to change only what you name. The body is a JSON merge patch of the policy: a control or key you name is set, one you name as
nullis removed so the scope inherits it again, and anything you leave out stays as it is. A setting is replaced whole, value and lock.Terminal window curl -X PATCH https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/ai-policy \-H "Authorization: Bearer $LAYER_TOKEN" \-H "Content-Type: application/json" \-d '{"models": { "flux-2-pro": { "value": false, "locked": true }, "flux-2-dev": null },"model_defaults": { "flux-2-dev": { "inference_steps": { "value": 30 } } }}'This turns FLUX.2 Pro off for the whole workspace and locks it, returns FLUX.2 Dev to what the workspace inherits, and starts every FLUX.2 Dev generation at 30 steps, leaving every other control alone. Patches to one scope apply one after another, so two admins changing different models never undo each other.
A member’s monthly cap is raised the same way:
Terminal window curl -X PATCH https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/members/$PRINCIPAL_ID/ai-policy \-H "Authorization: Bearer $LAYER_TOKEN" \-H "Content-Type: application/json" \-d '{ "usage_caps": { "monthly": { "value": { "cu_limit": 1000, "mode": "block", "warn_threshold_pct": 80 } } } }' -
Replace with
PUTto set the whole policy at once. Anything the body leaves out is inherited, except guardrails, output scoring and usage caps, which are kept. Read the policy first and send it back with your change, or prefer a patch. -
Clear with
DELETEto remove every control the scope sets, so it inherits them. Guardrails, output scoring and usage caps are kept. It answers204.
A patch or replacement that sets nothing removes the policy, as a clear does. A patch that changes nothing writes nothing.
List a workspace’s policies
Section titled “List a workspace’s policies”GET /v2/workspaces/{workspace_id}/ai-policies lists every policy stored in the workspace, oldest first, each with its scope, its policy, and when and by whom it was last written. Filter by scope with kind=workspace, project, group or member, and page with cursor as on the other list endpoints.
Read the policy in force
Section titled “Read the policy in force”GET /v2/workspaces/{workspace_id}/effective-ai-policy resolves every scope’s policy into the controls in force for a member’s work, each value with the scope that set it. Name a project_id for work in a project, and a principal_id for another member; without one it resolves for the caller.
curl "https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/effective-ai-policy?project_id=$PROJECT_ID" \ -H "Authorization: Bearer $LAYER_TOKEN"The maps hold only what some policy names. A model, modality or subagent they leave out takes the platform default: allowed, unless new_models_enabled is false, in which case a model only runs when models turns it on.
Permissions
Section titled “Permissions”Reading or changing a policy takes the role that edits it in the app: the settings admin permission in the workspace, or for a project’s policy, the permission to edit its content policy. The list endpoint takes settings admin. Any member may read the policy in force for their own work; reading another member’s takes settings admin.
An access token needs the workspace:read scope to read and workspace:write to change a policy.
Errors
Section titled “Errors”| Status | Code | When |
|---|---|---|
402 |
AI_POLICY_REQUIRES_ENTERPRISE |
A control the scope can only set on the Enterprise plan. |
404 |
AI_POLICY_SCOPE_NOT_FOUND |
The project, group or member is not live in the workspace. |
422 |
AI_POLICY_LOCK_NOT_ALLOWED |
A group or member policy that locks a setting. |
422 |
AI_POLICY_CONTROL_NOT_AT_SCOPE |
A control the scope kind cannot set, such as sharing on a project. |
422 |
AI_POLICY_MIRROR_GROUP |
A group that mirrors another workspace’s group: set the policy on the source group. |
422 |
AI_POLICY_INVALID_MODEL_DEFAULT |
A parameter the model cannot default, or a value it does not accept. |
422 |
INVALID_LIMIT |
A usage cap that is not positive, or above 10,000,000 Creative Units. |
422 |
INVALID_WARN_THRESHOLD |
A usage cap whose warn_threshold_pct is outside 1 to 100. |