curl --request POST \
--url https://openrouter.ai/api/v1/guardrails \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"allowed_models": null,
"allowed_providers": [
"openai",
"anthropic",
"deepseek"
],
"description": "A guardrail for limiting API usage",
"enforce_zdr_anthropic": true,
"enforce_zdr_google": false,
"enforce_zdr_openai": true,
"enforce_zdr_other": false,
"enforce_zdr_xai": false,
"ignored_models": null,
"ignored_providers": null,
"limit_usd": 50,
"name": "My New Guardrail",
"reset_interval": "monthly"
}
'import requests
url = "https://openrouter.ai/api/v1/guardrails"
payload = {
"allowed_models": None,
"allowed_providers": ["openai", "anthropic", "deepseek"],
"description": "A guardrail for limiting API usage",
"enforce_zdr_anthropic": True,
"enforce_zdr_google": False,
"enforce_zdr_openai": True,
"enforce_zdr_other": False,
"enforce_zdr_xai": False,
"ignored_models": None,
"ignored_providers": None,
"limit_usd": 50,
"name": "My New Guardrail",
"reset_interval": "monthly"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
allowed_models: null,
allowed_providers: ['openai', 'anthropic', 'deepseek'],
description: 'A guardrail for limiting API usage',
enforce_zdr_anthropic: true,
enforce_zdr_google: false,
enforce_zdr_openai: true,
enforce_zdr_other: false,
enforce_zdr_xai: false,
ignored_models: null,
ignored_providers: null,
limit_usd: 50,
name: 'My New Guardrail',
reset_interval: 'monthly'
})
};
fetch('https://openrouter.ai/api/v1/guardrails', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://openrouter.ai/api/v1/guardrails",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'allowed_models' => null,
'allowed_providers' => [
'openai',
'anthropic',
'deepseek'
],
'description' => 'A guardrail for limiting API usage',
'enforce_zdr_anthropic' => true,
'enforce_zdr_google' => false,
'enforce_zdr_openai' => true,
'enforce_zdr_other' => false,
'enforce_zdr_xai' => false,
'ignored_models' => null,
'ignored_providers' => null,
'limit_usd' => 50,
'name' => 'My New Guardrail',
'reset_interval' => 'monthly'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://openrouter.ai/api/v1/guardrails"
payload := strings.NewReader("{\n \"allowed_models\": null,\n \"allowed_providers\": [\n \"openai\",\n \"anthropic\",\n \"deepseek\"\n ],\n \"description\": \"A guardrail for limiting API usage\",\n \"enforce_zdr_anthropic\": true,\n \"enforce_zdr_google\": false,\n \"enforce_zdr_openai\": true,\n \"enforce_zdr_other\": false,\n \"enforce_zdr_xai\": false,\n \"ignored_models\": null,\n \"ignored_providers\": null,\n \"limit_usd\": 50,\n \"name\": \"My New Guardrail\",\n \"reset_interval\": \"monthly\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://openrouter.ai/api/v1/guardrails")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"allowed_models\": null,\n \"allowed_providers\": [\n \"openai\",\n \"anthropic\",\n \"deepseek\"\n ],\n \"description\": \"A guardrail for limiting API usage\",\n \"enforce_zdr_anthropic\": true,\n \"enforce_zdr_google\": false,\n \"enforce_zdr_openai\": true,\n \"enforce_zdr_other\": false,\n \"enforce_zdr_xai\": false,\n \"ignored_models\": null,\n \"ignored_providers\": null,\n \"limit_usd\": 50,\n \"name\": \"My New Guardrail\",\n \"reset_interval\": \"monthly\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/guardrails")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"allowed_models\": null,\n \"allowed_providers\": [\n \"openai\",\n \"anthropic\",\n \"deepseek\"\n ],\n \"description\": \"A guardrail for limiting API usage\",\n \"enforce_zdr_anthropic\": true,\n \"enforce_zdr_google\": false,\n \"enforce_zdr_openai\": true,\n \"enforce_zdr_other\": false,\n \"enforce_zdr_xai\": false,\n \"ignored_models\": null,\n \"ignored_providers\": null,\n \"limit_usd\": 50,\n \"name\": \"My New Guardrail\",\n \"reset_interval\": \"monthly\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"allowed_models": null,
"allowed_providers": [
"openai",
"anthropic",
"google"
],
"created_at": "2025-08-24T10:30:00Z",
"description": "A guardrail for limiting API usage",
"enforce_zdr": null,
"enforce_zdr_anthropic": true,
"enforce_zdr_google": false,
"enforce_zdr_openai": true,
"enforce_zdr_other": false,
"enforce_zdr_xai": false,
"id": "550e8400-e29b-41d4-a716-446655440000",
"ignored_models": null,
"ignored_providers": null,
"include_byok_in_budgets": false,
"limit_usd": 50,
"name": "My New Guardrail",
"reset_interval": "monthly",
"updated_at": null,
"workspace_id": "0df9e665-d932-5740-b2c7-b52af166bc11"
}
}{
"error": {
"code": 400,
"message": "Invalid request parameters"
}
}{
"error": {
"code": 401,
"message": "Missing Authentication header"
}
}{
"error": {
"code": 403,
"message": "Only management keys can perform this operation"
}
}{
"error": {
"code": 500,
"message": "Internal Server Error"
}
}Create a guardrail
Create a new guardrail for the authenticated user. Management key required.
curl --request POST \
--url https://openrouter.ai/api/v1/guardrails \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"allowed_models": null,
"allowed_providers": [
"openai",
"anthropic",
"deepseek"
],
"description": "A guardrail for limiting API usage",
"enforce_zdr_anthropic": true,
"enforce_zdr_google": false,
"enforce_zdr_openai": true,
"enforce_zdr_other": false,
"enforce_zdr_xai": false,
"ignored_models": null,
"ignored_providers": null,
"limit_usd": 50,
"name": "My New Guardrail",
"reset_interval": "monthly"
}
'import requests
url = "https://openrouter.ai/api/v1/guardrails"
payload = {
"allowed_models": None,
"allowed_providers": ["openai", "anthropic", "deepseek"],
"description": "A guardrail for limiting API usage",
"enforce_zdr_anthropic": True,
"enforce_zdr_google": False,
"enforce_zdr_openai": True,
"enforce_zdr_other": False,
"enforce_zdr_xai": False,
"ignored_models": None,
"ignored_providers": None,
"limit_usd": 50,
"name": "My New Guardrail",
"reset_interval": "monthly"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
allowed_models: null,
allowed_providers: ['openai', 'anthropic', 'deepseek'],
description: 'A guardrail for limiting API usage',
enforce_zdr_anthropic: true,
enforce_zdr_google: false,
enforce_zdr_openai: true,
enforce_zdr_other: false,
enforce_zdr_xai: false,
ignored_models: null,
ignored_providers: null,
limit_usd: 50,
name: 'My New Guardrail',
reset_interval: 'monthly'
})
};
fetch('https://openrouter.ai/api/v1/guardrails', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://openrouter.ai/api/v1/guardrails",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'allowed_models' => null,
'allowed_providers' => [
'openai',
'anthropic',
'deepseek'
],
'description' => 'A guardrail for limiting API usage',
'enforce_zdr_anthropic' => true,
'enforce_zdr_google' => false,
'enforce_zdr_openai' => true,
'enforce_zdr_other' => false,
'enforce_zdr_xai' => false,
'ignored_models' => null,
'ignored_providers' => null,
'limit_usd' => 50,
'name' => 'My New Guardrail',
'reset_interval' => 'monthly'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://openrouter.ai/api/v1/guardrails"
payload := strings.NewReader("{\n \"allowed_models\": null,\n \"allowed_providers\": [\n \"openai\",\n \"anthropic\",\n \"deepseek\"\n ],\n \"description\": \"A guardrail for limiting API usage\",\n \"enforce_zdr_anthropic\": true,\n \"enforce_zdr_google\": false,\n \"enforce_zdr_openai\": true,\n \"enforce_zdr_other\": false,\n \"enforce_zdr_xai\": false,\n \"ignored_models\": null,\n \"ignored_providers\": null,\n \"limit_usd\": 50,\n \"name\": \"My New Guardrail\",\n \"reset_interval\": \"monthly\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://openrouter.ai/api/v1/guardrails")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"allowed_models\": null,\n \"allowed_providers\": [\n \"openai\",\n \"anthropic\",\n \"deepseek\"\n ],\n \"description\": \"A guardrail for limiting API usage\",\n \"enforce_zdr_anthropic\": true,\n \"enforce_zdr_google\": false,\n \"enforce_zdr_openai\": true,\n \"enforce_zdr_other\": false,\n \"enforce_zdr_xai\": false,\n \"ignored_models\": null,\n \"ignored_providers\": null,\n \"limit_usd\": 50,\n \"name\": \"My New Guardrail\",\n \"reset_interval\": \"monthly\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openrouter.ai/api/v1/guardrails")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"allowed_models\": null,\n \"allowed_providers\": [\n \"openai\",\n \"anthropic\",\n \"deepseek\"\n ],\n \"description\": \"A guardrail for limiting API usage\",\n \"enforce_zdr_anthropic\": true,\n \"enforce_zdr_google\": false,\n \"enforce_zdr_openai\": true,\n \"enforce_zdr_other\": false,\n \"enforce_zdr_xai\": false,\n \"ignored_models\": null,\n \"ignored_providers\": null,\n \"limit_usd\": 50,\n \"name\": \"My New Guardrail\",\n \"reset_interval\": \"monthly\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"allowed_models": null,
"allowed_providers": [
"openai",
"anthropic",
"google"
],
"created_at": "2025-08-24T10:30:00Z",
"description": "A guardrail for limiting API usage",
"enforce_zdr": null,
"enforce_zdr_anthropic": true,
"enforce_zdr_google": false,
"enforce_zdr_openai": true,
"enforce_zdr_other": false,
"enforce_zdr_xai": false,
"id": "550e8400-e29b-41d4-a716-446655440000",
"ignored_models": null,
"ignored_providers": null,
"include_byok_in_budgets": false,
"limit_usd": 50,
"name": "My New Guardrail",
"reset_interval": "monthly",
"updated_at": null,
"workspace_id": "0df9e665-d932-5740-b2c7-b52af166bc11"
}
}{
"error": {
"code": 400,
"message": "Invalid request parameters"
}
}{
"error": {
"code": 401,
"message": "Missing Authentication header"
}
}{
"error": {
"code": 403,
"message": "Only management keys can perform this operation"
}
}{
"error": {
"code": 500,
"message": "Internal Server Error"
}
}Authorizations
API key as bearer token in Authorization header
Body
Name for the new guardrail
1 - 200"My New Guardrail"
Array of model identifiers (slug or canonical_slug accepted)
1[
"openai/gpt-5.2",
"anthropic/claude-4.5-opus-20251124",
"deepseek/deepseek-r1-0528:free"
]
List of allowed provider IDs
1["openai", "anthropic", "deepseek"]
Builtin content filters to apply. Every builtin slug supports "block", "redact", and the detect-only "flag" action.
Show child attributes
Show child attributes
[
{
"action": "block",
"slug": "regex-prompt-injection"
}
]
Custom regex content filters to apply to request messages
Show child attributes
Show child attributes
[
{
"action": "redact",
"label": "[API_KEY]",
"pattern": "\\b(sk-[a-zA-Z0-9]{48})\\b"
}
]
Description of the guardrail
1000"A guardrail for limiting API usage"
Whether this guardrail allows free endpoints that publish prompts.
false
Whether this guardrail allows free endpoints that train on request data.
true
Whether this guardrail allows paid endpoints that train on request data.
true
Deprecated. Use enforce_zdr_anthropic, enforce_zdr_openai, enforce_zdr_google, enforce_zdr_xai, and enforce_zdr_other instead. When provided, its value is copied into any of those per-provider fields that are not explicitly specified on the request.
false
Whether to enforce zero data retention for Anthropic models. Falls back to enforce_zdr when not provided.
false
Whether to enforce zero data retention for Google models. Falls back to enforce_zdr when not provided.
false
Whether to enforce zero data retention for OpenAI models. Falls back to enforce_zdr when not provided.
false
Whether to enforce zero data retention for models that are not from Anthropic, OpenAI, Google, or xAI. Falls back to enforce_zdr when not provided.
false
Whether to enforce zero data retention for xAI models. Falls back to enforce_zdr when not provided.
false
Array of model identifiers to exclude from routing (slug or canonical_slug accepted)
1["openai/gpt-4o-mini"]
List of provider IDs to exclude from routing
1["azure"]
Whether BYOK (bring-your-own-key) inference spend counts toward this guardrail's limit_usd, in addition to OpenRouter credit spend. Defaults to false.
false
Spending limit in USD
50
Interval at which the limit resets (daily, weekly, monthly)
daily, weekly, monthly, null "monthly"
The workspace to create the guardrail in. When omitted, the guardrail is created in the default workspace; if that default has been deleted, the request returns a 400 and you must pass workspace_id explicitly.
"0df9e665-d932-5740-b2c7-b52af166bc11"
Response
Guardrail created successfully
The created guardrail
Show child attributes
Show child attributes
{
"allowed_models": null,
"allowed_providers": ["openai", "anthropic", "google"],
"content_filter_builtins": [
{
"action": "redact",
"label": "[EMAIL]",
"slug": "email"
}
],
"content_filters": null,
"created_at": "2025-08-24T10:30:00Z",
"description": "Guardrail for production environment",
"enable_free_model_publication": false,
"enable_free_model_training": true,
"enable_paid_model_training": true,
"enforce_zdr": null,
"enforce_zdr_anthropic": true,
"enforce_zdr_google": false,
"enforce_zdr_openai": true,
"enforce_zdr_other": false,
"enforce_zdr_xai": false,
"id": "550e8400-e29b-41d4-a716-446655440000",
"ignored_models": null,
"ignored_providers": null,
"include_byok_in_budgets": false,
"limit_usd": 100,
"name": "Production Guardrail",
"reset_interval": "monthly",
"updated_at": "2025-08-24T15:45:00Z",
"workspace_id": "0df9e665-d932-5740-b2c7-b52af166bc11"
}