Overwing

The send gate

One check before your agent hits send.

Agents now write the email, the reply and the post, and nobody reads each one before it goes. The gate is one call between the draft and the send. It answers allow, redact, review or block, names the rule that decided it, and knows who the message is going to.

250 checks a day free. 10 a day with no key at all.

Four answers

Your code branches on one field.

allow

Nothing in the rules objects. Send it.

redact

It carries personal data this recipient should not get. The answer names the rule; your code removes the detail or sends a fallback. The AI SDK middleware swaps in your fallback on its own.

review

The model was not confident enough to rule either way. Hold the message and show it to a person, with the reasons.

block

A secret, a threat, or something the context does not authorize. Do not send.

The call

The message, and who it is for.

A customer’s own phone number going back to that customer is not a leak. Another customer’s is. The text alone cannot tell the two apart, so the gate takes a context next to it: the recipient, the channel, and whether the sender owns the contact details. This request runs as written, with no key. Two rules fail here, one asking for a redaction and one for a block, and the stricter action is the one recommended.

# request
curl -X POST https://overwing.ai/api/v1/evaluate \
  -H "Content-Type: application/json" \
  -d '{"input": "Hi Sam, the other customer on this ticket is
                 Dana Reyes, dana@example.com, 555-0142.",
       "rule_set": "outbound-message",
       "context": {"recipient": "customer", "channel": "email",
                   "owns_contact_info": false}}'
# response on 2 October 2026, three of six results shown
{
  "verdict": "fail",
  "recommended_action": "block",
  "latency_ms": 190,
  "results": [
    { "rule": "unauthorized_pii", "answer": true,
      "confidence": 0.92, "verdict": "fail", "action": "redact" },
    { "rule": "confidential_leak", "answer": true,
      "confidence": 0.82, "verdict": "fail", "action": "block" },
    { "rule": "toxicity", "answer": "safe",
      "confidence": 0.94, "verdict": "pass", "action": "block" }
  ]
}

What it asks

Six questions, asked at once.

RuleWhat it catchesIf it fails
unauthorized_piiPersonal data that is not the sender's own, or is not meant for this recipient: emails, phone numbers, addresses, ID and account numbers.redact
confidential_leakCredentials, internal system details, unreleased plans, non-public pricing, or another person's private matters that the context does not authorize sharing.block
toxicityHostile, hateful, threatening or abusive language toward the recipient or anyone mentioned.block
self_harmEncouragement of, or instructions for, self-harm or suicide.block
sexual_contentExplicit sexual content, judged against the recipient and the channel.block
severityThe overall harm if the message reached its recipient as written, on a five-level scale.block

Each question is answered by TypeSafe’s Jev model with a typed answer and a calibrated confidence, not prose. When the confidence is low the answer is review, never a guess. The rules are plain-language questions, so you can add your own: a claim your legal team has banned, a competitor you never name, a discount no agent may offer. A judgment by a model is a signal. Keep a person on review, and do not treat a pass as a guarantee.

Where it goes

In the path, not beside it.

  • Vercel AI SDK
    overwing/ai-sdk middleware. Wraps any model; buffers a stream until the answer is in.
  • OpenAI Agents SDK
    Input and output guardrails, in JavaScript and Python.
  • LangChain
    A guard you pipe after the model, and a callback handler. Python.
  • MCP
    The evaluate tool on the hosted server at overwing.ai/mcp, for agents that pick their own tools.
  • Plain HTTP
    One POST. Idempotency keys, batches of messages, and errors that name the field.
import { wrapLanguageModel } from "ai";
import { overwingGuardrail } from "overwing/ai-sdk";

const model = wrapLanguageModel({
  model: yourModel,
  middleware: overwingGuardrail({
    ruleSet: "outbound-message",
    context: () => ({ recipient: "customer", channel: "email" }),
    // shadow mode: record the answer, change nothing
    onFail: "annotate", honorActions: false, failOpen: true,
    onVerdict: (e) => log(e.recommended_action, e.id),
  }),
});

Start in shadow

14 days of answers before it stops anything.

Put the gate in the path with enforcement off. It records what it would have done for every message and changes nothing. After 14 days you know how often it would have stepped in, and whether it was right, from your own traffic.

Your text, your choice. Send "store": false and the message and its context are never kept, only the answer. Without a key the text is never stored. The details are on the security page.

If Overwing is unreachable, you decide what happens: hold the message, or let it through unscored. The middleware calls this failOpen.

First 5 teams

We write your rule set with you.

Tell us what your agent sends and what must never go out. We turn that into rules, wire the gate into your framework with you, and read the shadow results together. No charge beyond the plan you choose.

Tell us what your agent sends

One check is one evaluation. 250 a day are free; 5,000 a day is $29 a month, 25,000 a day is $99 a month, 100,000 a day is $299 a month. An agent with a wallet and no account pays $0.002 a check over x402. All prices.

Gating what an agent does, not what it says? Writes to an order system or an ERP go through Tower, which is in pilot.