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.

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 styleBase URL
OpenAI-compatiblehttps://api.aidren.co.uk/v1
Anthropic-compatiblehttps://api.aidren.co.uk (SDK appends /v1/messages)
Mistral-compatiblehttps://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:

codeMeaning
injection_detectedThe request was flagged as a potential prompt injection attempt.
sensitive_data_detectedPersonal data or secrets were found in the request, or in the model's response when output scanning is set to Enforce → Block.
policy_blockedThe 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.

SettingWhat it does
Off (default)Responses pass through untouched.
MonitorScan every response, log a redacted-style event and fire an alert, but don't change the bytes.
Enforce → RedactReplace each match with [REDACTED_EMAIL], [REDACTED_CREDIT_CARD] etc. and return the rest.
Enforce → BlockReturn a 400 proxy-block response (code: sensitive_data_detected) instead of the model's reply.
Also scan promptsApply the same scan to the user and tool messages before they are forwarded to the provider (OpenAI / Anthropic / Mistral).
Buffer streaming responsesBy 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).

RuleMatchesTargetsActions
Contains termA case-insensitive substring. “Negate” flips it to fire when the term is absent (an allow-list, or a required disclaimer).prompt / response / bothmonitor, redact, block
Matches regexA regular expression, run under a linear-time engine (no catastrophic backtracking). /pattern/i syntax for flags. Negatable.prompt / response / bothmonitor, redact, block
Covers topicA 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 / bothmonitor, block
Exceeds limitA numeric cap: max_messages, max_input_chars, or max_pii_matches (needs “Also scan prompts” on).promptmonitor, block
Leaks system promptFlags a response that echoes a long verbatim span of your system prompt back to the caller (OWASP LLM07).responsemonitor, 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:

ModeBehaviour
Enforce (default)A flagged request is blocked and never reaches the model.
MonitorThe 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.

RoleCan
OwnerEverything, including billing, deleting the account, and managing the team.
MemberEverything 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 parameterMeaning
subsystemproxy, model_scan or egress.
decisionclean, blocked, monitored, flagged or upstream_error.
sinceISO-8601 timestamp; only events at or after it.
limit1–200, default 50.
cursorThe 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

StatusMeaning
200 / 2xxRequest was clean and forwarded; this is the provider's own response, unchanged.
400Malformed 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.
401Missing or invalid AiDren proxy key.
402Your trial or subscription has lapsed — proxied traffic is paused. Add or renew a plan in the dashboard.
403Model-file download blocked by AiDren — a malicious or unsafe file. Not forwarded.
404No upstream key configured for this proxy key's provider, or unknown path.
429Rate limit or hard fair-use cap reached. Back off and retry.
502The upstream provider returned an error or was unreachable.
503Fail 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].