Attach Guardrail to a Scope
POST /environments/{env_id}/guardrails/{guardrail_id}/attachments
POST /environments/{env_id}/guardrails/{guardrail_id}/attachmentsInteractive request editor loads with JavaScript.
Authorization
BearerAdminToken Organization-scoped admin token. Read operations require a valid token, and write operations require a token with write permission.
In: header
Path Parameters
Environment ID that scopes the request.
uuidGuardrail ID within the environment.
uuidRequest Body
application/json
Attach a guardrail to a scope. scope_id is required for every
scope_type except env (which must omit it).
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "$AISIX_CP/environments/$ENV_ID/guardrails/$GUARDRAIL_ID/attachments" \ -H "Authorization: Bearer $AISIX_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "scope_type": "env" }'Created
{
"data": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"guardrail_id": "5ea4ad06-0022-46ca-b5a6-3795e32e6aa8",
"env_id": "3f917d0d-4dff-42f3-97c4-6a5455dfe8c2",
"scope_type": "env",
"scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f",
"priority": 0,
"enabled": true,
"created_at": "string"
},
"warnings": [
{
"code": "field_ignored",
"field": "string",
"min_dp_version": "string",
"affected_dp_count": 0,
"affected_dp_versions": [
"string"
]
}
]
}Request body or parameters failed validation.
{
"error": {
"code": "string",
"message": "string"
}
}Missing or invalid bearer.
{
"error": {
"code": "UNAUTHENTICATED",
"message": "no org context"
}
}Authenticated request is not permitted.
{
"error": {
"code": "CUSTOM_KEY_DISABLED",
"message": "custom API key values are disabled for this organization"
}
}Resource not found.
{
"error": {
"code": "NOT_FOUND",
"message": "provider key not found"
}
}Request conflicts with current resource state.
{
"error": {
"code": "CREDENTIAL_IN_USE",
"message": "models still reference this provider_key"
}
}Complete operation details and schema variants
POST /environments/{env_id}/guardrails/{guardrail_id}/attachments
Attach Guardrail to a Scope
Attach a guardrail to an env, model, api_key, or team scope.
scope_id is required for every scope except env (which must
omit it).
Parameters
env_id(path, string, required): Environment ID that scopes the request.guardrail_id(path, string, required): Guardrail ID within the environment.
Request body
Content type: application/json
-
scope_type(string, required): The resource dimension an attachment binds to.model,mcp_server, andpassthrough_routeselect dimensions a request carries only one of: an MCP tool call resolves no model, a model request routes to no MCP server, and passthrough-route traffic resolves neither. Amodel-scoped guardrail therefore never inspects MCP or passthrough traffic, anmcp_server-scoped one never inspects model traffic, and apassthrough_route-scoped one inspects only the traffic of that route. -
scope_id(string, optional): ID of the selected model, MCP server, caller API key, or team. Omit forenv; required for every other scope type. -
priority(integer, optional): Scope precedence for duplicate matches of this guardrail. Omit to use 100. -
enabled(boolean, optional): Whether the attachment participates in scope resolution; omit to enable it.
Responses
201: Createddata(object, required): Binds a guardrail to an environment, model, caller API key, or team so the gateway can select it for each request.
Attachments are the whole of a guardrail's scope. Deleting the last one leaves the guardrail enforced nowhere — it does not fall back to applying environment-wide.
-
data.id(string, required): Guardrail attachment ID. -
data.guardrail_id(string, required): Guardrail definition selected by this attachment. -
data.env_id(string, required): Environment that owns the guardrail and attachment. -
data.scope_type(string, required): The resource dimension an attachment binds to.model,mcp_server, andpassthrough_routeselect dimensions a request carries only one of: an MCP tool call resolves no model, a model request routes to no MCP server, and passthrough-route traffic resolves neither. Amodel-scoped guardrail therefore never inspects MCP or passthrough traffic, anmcp_server-scoped one never inspects model traffic, and apassthrough_route-scoped one inspects only the traffic of that route. -
data.scope_id(string, optional): ID of the model, MCP server, caller API key, or team selected byscope_type. Null for an environment-scoped attachment. -
data.priority(integer, optional): Precedence when the same guardrail matches through more than one attachment. Higher numbers win; equal priorities prefer api_key, then team, then model or mcp_server, then env scope. Model and MCP-server scopes share a rank because no single request can match both. -
data.enabled(boolean, required): Whether the gateway considers this attachment during scope resolution. -
data.created_at(string, optional): RFC3339 time when the attachment was created. -
warnings(array, optional): Present on create when some data plane nodes in the environment run a gateway version that will not execute the saved scope — anmcp_serverattachment, for example, is dropped whole by an older gateway. What that gateway then does depends on its version: one predating the scope applies the guardrail to the whole environment, because it read the row as having no attachment at all, while a current gateway leaves the guardrail inspecting nothing, because a guardrail's scope is its attachments and nothing else. Either way the saved scope is not what runs there. Never present on reads. -
warnings[].code(string, required): How affected nodes treat the saved resource.field_ignored: the resource stays in service on those nodes but the named field has no effect there — beware when the field is restrictive, since the restriction is silently not enforced.row_rejected: those nodes refuse the whole resource, so it stops serving there entirely (or, if a previously accepted version exists, they keep serving the old values). -
warnings[].field(string, required): Dot-separated path of the field that triggered the warning, as delivered to gateway nodes. -
warnings[].min_dp_version(string, required): Oldest gateway version that fully executes the field. The literal valueunreleasedmeans no released gateway version executes it yet. -
warnings[].affected_dp_count(integer, required): Number of currently registered nodes in the environment running an older gateway version thanmin_dp_version. -
warnings[].affected_dp_versions(array, required): Distinct gateway versions reported by the affected nodes, capped at five entries. Nodes that report no version appear asunknown. -
400: Request body or parameters failed validation. -
error(object, required): Error details. -
error.code(string, required): Machine-readable identifier. Examples:UNAUTHENTICATED,INVALID_REQUEST,MASTER_KEY_UNSET,INTERNAL. -
error.message(string, required): Human-readable explanation; safe to surface to operators. -
401: Missing or invalid bearer. Response fields (application/json): identical toPOST /environments/{env_id}/guardrails/{guardrail_id}/attachments, response 400 above. -
403: Authenticated request is not permitted. Response fields (application/json): identical toPOST /environments/{env_id}/guardrails/{guardrail_id}/attachments, response 400 above. -
404: Resource not found. Response fields (application/json): identical toPOST /environments/{env_id}/guardrails/{guardrail_id}/attachments, response 400 above. -
409: Request conflicts with current resource state. Response fields (application/json): identical toPOST /environments/{env_id}/guardrails/{guardrail_id}/attachments, response 400 above.
cURL
curl -X POST '$AISIX_CP/environments/{env_id}/guardrails/{guardrail_id}/attachments' -H 'Authorization: Bearer $AISIX_TOKEN'