API Reference
AiDren is a drop-in proxy. You keep using the OpenAI, Anthropic, or Mistral SDK you already have — you change the base URL to AiDren and use an AiDren proxy key in place of your provider key. Request and response bodies are unchanged. Every request is screened for prompt injection before it is forwarded; model-file downloads are scanned for malicious payloads.
Logged in already? The Set up AiDren page in the dashboard has copy-paste snippets pre-filled for your account.
- Base URLs
- Authentication
- Chat / messages
- Model-file scanning
- Model-scan controls
- Egress monitoring
- Output scanning & data-leak prevention
- Custom policies
- Shadow-testing a policy
- Attack test
- Monitor mode & alerts
- Team accounts
- Events API
- Errors & status codes
- Rate & usage limits
- Data handling
Runnable, tested examples for the OpenAI, Anthropic, LangChain and Vercel AI SDKs, plus curl and a blocked-request handler, are on GitHub: AiDren-Security/aidren-examples.
Base URLs
| Client style | Base URL |
|---|---|
| OpenAI-compatible | https://api.aidren.co.uk/v1 |
| Anthropic-compatible | https://api.aidren.co.uk (SDK appends /v1/messages) |
| Mistral-compatible | https://api.aidren.co.uk/v1 |
Which upstream provider a proxy key routes to is fixed when you create the key (Proxy Keys in the dashboard). Create one key per provider you use.
Authentication
Send your AiDren proxy key exactly where you would normally send the provider key — AiDren accepts either header:
Authorization: Bearer YOUR_AIDREN_KEY # OpenAI / Mistral style
x-api-key: YOUR_AIDREN_KEY # Anthropic style
The full key is shown once, when you create it. AiDren stores only a hash — it can never be shown again, so copy it then. Your real OpenAI / Anthropic / Mistral key is added separately under Upstream Keys, encrypted at rest, and used only to forward your requests.
Chat / messages
Send the same request body you send today. AiDren does not rewrite it. A clean request is forwarded unchanged and the provider's response is returned verbatim (streaming included). A request that contains a prompt-injection attempt is blocked before it reaches the model.
OpenAI · Python
from openai import OpenAI
client = OpenAI(
api_key="YOUR_AIDREN_KEY", # AiDren proxy key, not your OpenAI key
base_url="https://api.aidren.co.uk/v1", # point at AiDren
)
resp = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)
OpenAI · Node
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_AIDREN_KEY",
baseURL: "https://api.aidren.co.uk/v1",
});
const resp = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello" }],
});
Anthropic · Python
from anthropic import Anthropic
client = Anthropic(
api_key="YOUR_AIDREN_KEY",
base_url="https://api.aidren.co.uk",
)
msg = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
curl
# OpenAI-style
curl https://api.aidren.co.uk/v1/chat/completions \
-H "Authorization: Bearer YOUR_AIDREN_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Hello"}]}'
# Anthropic-style
curl https://api.aidren.co.uk/v1/messages \
-H "x-api-key: YOUR_AIDREN_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "claude-sonnet-4-5", "max_tokens": 1024, "messages": [{"role": "user", "content": "Hello"}]}'
What comes back when a request is blocked
A blocked request returns HTTP 400 with a small JSON body and is not
forwarded to the provider (so you are not billed by them for it). The body follows the
wire format you called, so your SDK raises its normal 400 error. On the OpenAI-compatible
and Mistral-compatible endpoints it looks like this:
{
"error": {
"message": "Request blocked by AiDren Proxy: content flagged as a potential prompt injection attempt.",
"type": "proxy_blocked",
"code": "injection_detected"
}
}
The code field says why the request was blocked:
code | Meaning |
|---|---|
injection_detected | The request was flagged as a potential prompt injection attempt. |
sensitive_data_detected | Personal data or secrets were found in the request, or in the model's response when output scanning is set to Enforce → Block. |
policy_blocked | The request matched a block rule in your custom policy. |
On the Anthropic-compatible endpoint (/v1/messages) the body uses Anthropic's error envelope instead:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "Request blocked by AiDren Proxy: content flagged as a potential prompt injection attempt."
}
}
Because it is a 400, the official SDKs raise their usual bad-request error
(BadRequestError in both the OpenAI and Anthropic SDKs). To tell an AiDren block from
a genuinely malformed request, check error.type === "proxy_blocked" on the OpenAI and Mistral shapes, or
check that the message starts with Request blocked by AiDren Proxy: (the only marker on the Anthropic shape).
Every decision — clean, blocked, or flagged — appears on your Events page with a reason and a confidence score.
Model-file scanning
Route a model-file download through AiDren and it's checked against six formats: pickle
(including one wrapped in a torch.save ZIP), joblib, safetensors, GGUF, ONNX,
and Keras (.h5 and the .keras archive). Safetensors and GGUF
files are structurally verified and their metadata extracted, then the tensor data streams
straight through untouched. Pickle, joblib, ONNX, and Keras files are fully scanned for
dangerous content (unsafe opcodes, custom ops, external-data path escapes, Lambda/custom
layers) before any byte is delivered. A file renamed to disguise its real format, such as
a pickle saved as .safetensors, is caught by a content check before any
scanner even runs. A malicious file is blocked with 403; a file scanned clean
once downloads instantly on later pulls, without AiDren ever storing its content.
# Hugging Face Hub — swap the host
# was: https://huggingface.co/org/model/resolve/main/pytorch_model.bin
curl https://api.aidren.co.uk/org/model/resolve/main/pytorch_model.bin \
-H "Authorization: Bearer YOUR_AIDREN_KEY" -L -o pytorch_model.bin
# GitHub — add a /gh/ prefix
# was: https://github.com/org/repo/releases/download/v1.0/model.pt
curl https://api.aidren.co.uk/gh/org/repo/releases/download/v1.0/model.pt \
-H "Authorization: Bearer YOUR_AIDREN_KEY" -L -o model.pt
Model-scan controls
Scanning runs in one of two modes per key, set on the
Proxy Keys page under “Model-file
scanning”: Enforce (default) blocks a malicious file with
403; Monitor scans and logs the same verdict but lets the
download through, so you can shadow-run scanning against real traffic before switching to
Enforce. A key left in Monitor for 14 days gets a review nudge in the dashboard.
You can also block an entire format outright, independent of scan result — add
pickle, joblib, safetensors, gguf,
onnx, or keras to a key's blocked-formats list and any file of
that format is refused before scanning even runs, in either mode.
A narrow allowlist covers two specific false-positive shapes only — a named ONNX custom op or Keras custom layer, approved by exact name. Nothing else is allowlistable; an unsafe opcode or dangerous global is never exemptable. Allowlist one directly from the matching event's row on the Events page.
Egress monitoring
The @aidren/worker-agent npm package watches your app's own outbound
network connections and flags unexpected destinations without blocking anything.
npm install @aidren/worker-agent
// as early as possible in your app's startup
import '@aidren/worker-agent/init';
Set AIDREN_KEY in the environment to your proxy key. Observed destinations
appear on the Egress page. It starts in
training mode; once the list looks right you lock an allowlist, and any
connection to a destination not on it is flagged (never blocked) on your Events page.
Output scanning & data-leak prevention
AiDren can also scan what the model sends back for personal data and secrets, and redact or block it before it reaches your app. Turn it on per proxy key under “Scanning” on the Proxy Keys page.
| Setting | What it does |
|---|---|
| Off (default) | Responses pass through untouched. |
| Monitor | Scan every response, log a redacted-style event and fire an alert, but don't change the bytes. |
| Enforce → Redact | Replace each match with [REDACTED_EMAIL], [REDACTED_CREDIT_CARD] etc. and return the rest. |
| Enforce → Block | Return a 400 proxy-block response (code: sensitive_data_detected) instead of the model's reply. |
| Also scan prompts | Apply the same scan to the user and tool messages before they are forwarded to the provider (OpenAI / Anthropic / Mistral). |
| Buffer streaming responses | By default a streaming response is relayed live and scanned after it finishes (logged, not retro-blocked). Enable this and a streaming response is held, scanned, then released — so Enforce can act on it, at the cost of progressive tokens for that key. |
What is detected (regex / heuristic, no added round-trip):
email addresses, credit-card numbers (Luhn-checked), phone numbers, IBANs (mod-97), US social-security numbers, IP addresses, AWS access keys, common API-key shapes, JSON Web Tokens, and PEM private-key blocks.
Events record the kinds found (scan:email,aws_key) and a count,
never the matched values. Redacted values are removed inside AiDren and never written
anywhere. Non-streaming responses add a single regex pass (single-digit milliseconds);
streaming in the default mode adds nothing the client can see.
Custom policies
A policy is a named set of rules you attach to one or more proxy keys on
the Policies page. Every attached key runs
the policy on the prompt (before forwarding) and on the response (before returning it).
Rules act independently — the most severe outcome wins — and each rule chooses
its own action: monitor (log only), redact (replace the match with
[REDACTED_POLICY]), or block (return a proxy-block response).
| Rule | Matches | Targets | Actions |
|---|---|---|---|
| Contains term | A case-insensitive substring. “Negate” flips it to fire when the term is absent (an allow-list, or a required disclaimer). | prompt / response / both | monitor, redact, block |
| Matches regex | A regular expression, run under a linear-time engine (no catastrophic backtracking). /pattern/i syntax for flags. Negatable. | prompt / response / both | monitor, redact, block |
| Covers topic | A plain-language topic label (“competitor pricing”, “legal advice”). Adds one classifier call per request on keys that use it; fails open if the classifier is unavailable. | prompt / response / both | monitor, block |
| Exceeds limit | A numeric cap: max_messages, max_input_chars, or max_pii_matches (needs “Also scan prompts” on). | prompt | monitor, block |
| Leaks system prompt | Flags a response that echoes a long verbatim span of your system prompt back to the caller (OWASP LLM07). | response | monitor, redact, block |
Events record which rule kinds fired (policy:regex,term), joined with
any data-leak scan on the same request (scan:email;policy:regex) — never
the matched text or the topic that matched. A streaming response is scanned after it
finishes unless “Buffer streaming responses” is on for the key, the same as
output scanning. Keys with no policy attached are unaffected.
Shadow-testing a policy
Before you attach a new or edited policy to a key for real, you can shadow-test it instead — from the Policies page, pick a proxy key and start a shadow test. Every request that key handles is evaluated against the shadow policy in parallel with whatever's actually live on that key. The shadow never blocks, redacts, or otherwise changes anything — it only tallies what would have happened, so you can see the impact before you commit to it.
The stats panel shows how many requests were evaluated, how many the shadow policy would have blocked or redacted that the live policy didn't (would add new coverage), and how many it agrees with what the live policy already does — broken down per rule. Once you're happy with it, promote the shadow straight to the key's active policy, or stop the test and discard the stats. A shadow left running for two weeks or more gets a plain nudge on the page to promote it or stop it — nothing expires automatically.
Because a shadow's topic rules run the same classifier call a live topic rule does, a
shadow policy with topic rules adds to your judge-call volume for every request on that
key, same as attaching it live would — monitor, term, regex, and threshold rules cost
nothing extra. Shadow verdicts are logged the same way everything else is: as events with
subsystem: policy_shadow, visible on the
Events page and via
the Events API below. The reason field marks each event
;new (the shadow policy would have acted where the live one didn't) or
;agree (the live policy already did) — never the matched text, same as
every other policy event.
Attack test
Before you route real traffic through an agent, find out how exposed its system prompt is. On the Attack test page, paste the system prompt and pick one of your configured providers — AiDren runs about 20 known prompt-injection and jailbreak attacks, including several multi-turn ones, against a cheap model carrying that prompt, using your on-file provider key. No new key needed, and nothing is sent to your actual production agent. Want a quick look first? A free 6-attack sample runs on the website with no signup.
Every attack is tagged to the OWASP LLM Top 10. Each result is scored vulnerable or resisted, with the model's response and, if vulnerable, a one-line remediation. Alongside that, we show what your own AiDren stack would have done — the judge always, and, if you pick a proxy key with the run, that key's attached policy and output scanning too.
A baseline run with no system prompt at all is included for comparison, so you can see how much your prompt is actually doing. Edit the prompt and run again to see a fixed / regressed / still-vulnerable delta against your last run.
Runs use your own provider key (about 20–24 requests per run) and are capped at 10 a day. No attack payloads or internal reference tokens are ever written to your event log — this tool is entirely separate from request scanning.
Monitor mode & alerts
Every proxy key runs in one of two modes, set on the Proxy Keys page:
| Mode | Behaviour |
|---|---|
| Enforce (default) | A flagged request is blocked and never reaches the model. |
| Monitor | The judge still screens every request, but a flagged one is logged as monitored and forwarded anyway. Use it to shadow-run a new integration for a few days, see exactly what would have been blocked, then switch to Enforce. |
Monitored requests count towards your plan allowance the same as any other, since they still run the judge and the upstream call.
Set a webhook on the Account page to get a
JSON alert whenever AiDren blocks a request, logs a monitor-mode would-block, or flags an
unexpected egress destination. Paste a Slack incoming-webhook URL to receive Slack
messages instead. Each delivery carries an X-AiDren-Signature: sha256=…
header (HMAC of the raw body with the signing secret shown once on save) and contains
decision metadata only — never prompt or response content.
Team accounts
Invite teammates from the Team page — unlimited seats, no extra charge. An invite is a normal email link; accepting it creates a member account that shares your proxy keys, policies, events, and billing — no separate sign-up.
| Role | Can |
|---|---|
| Owner | Everything, including billing, deleting the account, and managing the team. |
| Member | Everything except billing, account deletion, and team management — proxy keys, policies, events, and scanning settings are all shared and editable. |
Every action a member takes is attributed to them by email in a per-account audit log, visible to the owner on the Team page and exportable as CSV. Removing a member is immediate — their session is deleted along with their access.
Events API
Pull your decision log into your own SIEM or dashboards. GET https://api.aidren.co.uk/v1/events is authenticated with a read-only key, separate from your proxy keys: it can read events and nothing else. Create one under “Read-only API keys” on the Proxy Keys page.
curl https://api.aidren.co.uk/v1/events \
-H "authorization: Bearer aidren_read_…" \
--get \
--data-urlencode "decision=blocked" \
--data-urlencode "limit=100"
Response:
{
"events": [
{
"id": "3f2a…",
"at": "2026-09-03T17:41:22.108Z",
"subsystem": "proxy",
"decision": "blocked",
"reason": "prompt_injection",
"confidence": 0.94,
"provider": "openai",
"latency_ms": 6,
"proxy_key_label": "prod"
}
],
"next_cursor": "eyJ…"
}
| Query parameter | Meaning |
|---|---|
subsystem | proxy, model_scan or egress. |
decision | clean, blocked, monitored, flagged or upstream_error. |
since | ISO-8601 timestamp; only events at or after it. |
limit | 1–200, default 50. |
cursor | The next_cursor from the previous page. Absent next_cursor means the last page. |
The endpoint is rate-limited to 60 requests per minute per read key and returns decision
metadata only. It never includes prompt or response content. A revoked key returns
401; an unknown filter value returns 400.
Errors & status codes
| Status | Meaning |
|---|---|
200 / 2xx | Request was clean and forwarded; this is the provider's own response, unchanged. |
400 | Malformed request (bad JSON, missing model, etc.) — rejected before screening — or blocked by AiDren (prompt injection, sensitive data or policy; see above). Blocked requests are not forwarded. |
401 | Missing or invalid AiDren proxy key. |
402 | Your trial or subscription has lapsed — proxied traffic is paused. Add or renew a plan in the dashboard. |
403 | Model-file download blocked by AiDren — a malicious or unsafe file. Not forwarded. |
404 | No upstream key configured for this proxy key's provider, or unknown path. |
429 | Rate limit or hard fair-use cap reached. Back off and retry. |
502 | The upstream provider returned an error or was unreachable. |
503 | Fail closed. The screening pass could not complete (screening provider outage or timeout). The request was not forwarded unscreened — retry. Screening runs on a primary provider with an automatic fallback, so this is rare. |
Error bodies follow the shape of the client style you are using (an OpenAI-style client gets an OpenAI-shaped error object), so your existing error handling keeps working.
Rate & usage limits
Each plan has a monthly checked-request allowance (Starter 100k, Growth 500k, Scale 2M;
the 14-day trial covers 25k). The allowance is a fair-use guide, not a hard wall — we
email you before anything stops, and only sustained use far above the allowance is
rate-limited with a 429. Short-term burst limits also apply per key to keep
the service healthy. See pricing for current allowances.
Data handling
Request and response bodies pass through in memory to make the block/allow decision and are not stored. AiDren keeps only decision metadata — timestamp, subsystem, decision, a short reason, a confidence score, the provider routed to — on a rolling 12-month basis. Request text is sent to a classification model to make the decision; under that provider's paid API terms it is not used for training. Full detail is in the Privacy Policy and the Data Processing Agreement.
Something missing here? Email [email protected].