Try the demo
See Wayreeve enforce data rules on live requests in a few minutes. The demo serves two synthetic models, demo/finch and demo/heron, that reply with a description of what happened to your request. Nothing you send reaches a model provider, and nothing costs money.
Step 1
Get a demo code
Get in touch and ask for a demo code. We email you:
- A demo code: a Wayreeve project API key that allows 25 requests and expires after 30 days.
- The demo's address, which the examples below call
WAYREEVE_DEMO_URL. - A sign-in for the read-only demo console, where you can see the record of each request.
Everyone with a demo sign-in shares one read-only console. Prompts and replies stay visible there until they are deleted, 10 minutes after the reply is delivered. Do not send anything real.
| Limit | Value |
|---|---|
| Requests per demo code | 25 in total |
| Rate per demo code | 10 requests a minute |
| Rate for the whole demo | 30 requests a minute, shared |
| Models | demo/finch, demo/heron |
| Prompts and replies kept | 10 minutes after delivery |
Step 2
Send your first request
The demo speaks the OpenAI Chat Completions and Responses APIs and the Anthropic Messages API. Existing SDKs work with a base URL change. Put the address and code from your email in environment variables, which keeps the code out of your shell history:
read -r WAYREEVE_DEMO_URL && export WAYREEVE_DEMO_URL # paste the address, press Enter
read -rs WAYREEVE_DEMO_KEY && export WAYREEVE_DEMO_KEY # paste the code, press Enter
curl
curl -sS -i "$WAYREEVE_DEMO_URL/v1/chat/completions" \
-H "Authorization: Bearer $WAYREEVE_DEMO_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "demo/finch",
"messages": [{"role": "user", "content": "Draft a reminder about the Thursday release window."}]}'
The reply is a normal chat completion. Look at the headers too: x-wayreeve-data-class: internal says which data class the request ran under (your code's default), and x-wayreeve-decision-id is the sha256 of the decision record stored for it.
Python, OpenAI SDK
# pip install openai
import os
from openai import OpenAI
client = OpenAI(
base_url=os.environ["WAYREEVE_DEMO_URL"] + "/v1",
api_key=os.environ["WAYREEVE_DEMO_KEY"],
)
raw = client.chat.completions.with_raw_response.create(
model="demo/heron",
messages=[{"role": "user",
"content": "Summarise the ward handover notes."}],
extra_headers={"X-Wayreeve-Data-Class": "phi"},
)
print(raw.headers["x-wayreeve-decision-id"])
print(raw.parse().choices[0].message.content)
Node, OpenAI SDK
// npm install openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: `${process.env.WAYREEVE_DEMO_URL}/v1`,
apiKey: process.env.WAYREEVE_DEMO_KEY,
});
const { data, response } = await client.chat.completions
.create(
{
model: "demo/heron",
messages: [{ role: "user",
content: "Summarise the ward handover notes." }],
},
{ headers: { "X-Wayreeve-Data-Class": "phi" } },
)
.withResponse();
console.log(response.headers.get("x-wayreeve-decision-id"));
console.log(data.choices[0].message.content);
Both label the request phi. That is allowed: a request may make its class stricter than the code's default, never looser.
Step 3
Watch the policy work
The demo has guardrails for a synthetic medical record number pattern, MRN- followed by six digits, plus US Social Security numbers and email addresses. Ordinary traffic gets them redacted. A request labelled phi that contains one is refused before it is admitted. Only requests that are admitted count against your 25; refusals do not.
Redacted: the identifier never reaches the model
curl -sS "$WAYREEVE_DEMO_URL/v1/chat/completions" \
-H "Authorization: Bearer $WAYREEVE_DEMO_KEY" -H "Content-Type: application/json" \
-d '{"model": "demo/heron", "messages": [{"role": "user",
"content": "Patient MRN-104233 asked for a callback about her discharge plan."}]}'
# The synthetic model repeats what it received:
# "Your request: Patient [REDACTED:mrn] asked for a callback about her discharge plan."
Refused: the same text, labelled phi
curl -sS -i "$WAYREEVE_DEMO_URL/v1/chat/completions" \
-H "Authorization: Bearer $WAYREEVE_DEMO_KEY" -H "Content-Type: application/json" \
-H "X-Wayreeve-Data-Class: phi" \
-d '{"model": "demo/heron", "messages": [{"role": "user",
"content": "Patient MRN-104233 asked for a callback about her discharge plan."}]}'
# HTTP 400, with x-wayreeve-decision-id: the refusal has its own record
{"error": {"code": "guardrail_blocked",
"message": "The request matched a guardrail and was not sent. …",
"reason": ["mrn"], "request_id": "req_…"}}
Refused: a label looser than the code allows
curl -sS "$WAYREEVE_DEMO_URL/v1/chat/completions" \
-H "Authorization: Bearer $WAYREEVE_DEMO_KEY" -H "Content-Type: application/json" \
-H "X-Wayreeve-Data-Class: public" \
-d '{"model": "demo/finch", "messages": [{"role": "user", "content": "Hello"}]}'
# HTTP 403
{"error": {"code": "data_class_widening",
"message": "This key's default class is `internal`; a request may not be labelled `public`.
A request may narrow its class, never widen it.", "request_id": "req_…"}}
The demo models run inside Wayreeve, so they meet every provider-terms rule (BAA, zero data retention, region, training use). On your own providers, a phi request sent to a route without a BAA is refused with 403 data_class_not_permitted, naming the rule and its source. A pilot shows it on your routes.
Reference
What errors look like
Every error has the same shape: {"error": {"code", "message", "request_id"}}. Branch on code, not on the message.
| HTTP | Code | When |
|---|---|---|
| 429 | allowance_exhausted | The demo code has used its 25 requests: "This demo key has used its 25 requests." Ask us for another. |
| 429 | key_rate_limited | More than 10 requests in a minute on one code. Wait for Retry-After (60 seconds). |
| 429 | rate_limit_exceeded | All demo visitors together passed 30 requests in a minute. Wait for Retry-After. |
| 400 | guardrail_blocked | A phi request contained an identifier the guardrails look for. reason lists which. |
| 403 | data_class_widening | The request was labelled less strictly than the code's default, internal. |
| 400 | unknown_model | A model other than demo/finch or demo/heron. |
| 401 | unauthorized | The code is wrong, expired or revoked. |
A refused request is not sent anywhere and does not count against your allowance.
Step 4
Look at the record
Open the demo address in a browser and use the read-only sign-in from your email. It has the viewer role, so it can look but not change anything.
- Requests: each request with its data class and decision record: the class and its version, the route, every rule outcome and the guardrail result.
- Usage & audit: requests and tokens this month against the demo's limits. Cost reads $0.00 because the synthetic models are free.
- Data classes and Provider terms: the rules and the sourced terms catalog.
Guardrail settings, the audit log and the evidence summary are for owners and admins. The tour shows them, along with how the audit chain is verified.
Run it against your own providers
The demo shows the mechanics. A two-week pilot runs them on your providers, with your data classes and rules.