Create guardrails and assign them to your API keys — budgets, model and provider lists, and content filters.
A guardrail is a set of rules you put on your API keys: a budget in DA, the models that may run, the providers that may serve, zero data retention per lab, and content filters. It binds only the keys it is assigned to.
Every guardrail route is free and takes a management key. The openai SDK has no guardrails resource, so call the routes with httpx.
import os
import httpx
headers = {"Authorization": f"Bearer {os.environ['OPENDUNES_MANAGEMENT_KEY']}"}
resp = httpx.post(
"https://opendunes.com/v1/guardrails",
headers=headers,
json={
"name": "Souk Bot production",
"limit": 500, # budget in DA
"reset_interval": "monthly",
"allowed_models": ["anthropic/claude-sonnet-5"],
"content_filter_builtins": [{"slug": "email", "action": "redact"}],
},
)
guardrail = resp.json()["data"] # 201Keys are named by their hash — the hash the API keys routes return.
httpx.post(
f"https://opendunes.com/v1/guardrails/{guardrail['id']}/assignments/keys",
headers=headers,
json={"key_hashes": [key_hash]},
)
# → { "assigned_count": 1 }…/assignments/keys/remove takes the same body and unassigns.
A request the guardrail blocks fails before it reaches a model, and nothing is charged:
from openai import OpenAI, APIStatusError
client = OpenAI(base_url="https://opendunes.com/v1", api_key=os.environ["OPENDUNES_API_KEY"])
try:
client.chat.completions.create(
model="openai/gpt-5.6-luna", # not in allowed_models
messages=[{"role": "user", "content": "Marhba!"}],
)
except APIStatusError as e:
print(e.status_code) # 403 — blocked; 402 with limit_source "guardrail" once the budget is spent