Skip to main content

LLM Gateway SDK Playground

Use this page to test a QuilrAI SDK-mode API key against the standalone guardrails endpoint. This does not proxy to an LLM and does not require provider credentials. It checks the content you send, then tells your application whether to allow, redact, or block it.

SDK Playground

Test request-side and response-side guardrail checks with a quilr_sdk key.

SDK keys only

This playground supports only QuilrAI SDK tokens: sk-quilr-... keys whose provider is quilr_sdk. Regular LLM Gateway provider keys are rejected with sdk_mode_required.

Keep production keys out of public browsers

The playground sends your key directly from this page to QuilrAI and does not store it. For public applications, put this call behind your backend or edge service so end users cannot inspect or reuse the key.

Try your SDK key

Calls POST /sdk/v1/check with a quilr_sdk API key.

POST
Exact request

Generated from the endpoint, mode, and content on the left. The key is masked until you reveal it.

curl --request POST 'https://guardrails.quilr.ai/sdk/v1/check' \
  --header 'Authorization: Bearer sk-quilr-...' \
  --header 'Content-Type: application/json' \
  --data '{
  "type": "request",
  "messages": [
    {
      "role": "user",
      "content": "My SSN is 219-09-4823. Please help me update my profile."
    }
  ],
  "metadata": {
    "caller": "docs-playground",
    "team_id": "sales",
    "user_id": "internal-user-1",
    "end_user_id": "customer-1"
  }
}'

Run a check

The response will show whether your caller should allow, redact, or block the content.

How to use the judgement
allowsafe

Send the original messages to your LLM.

redactredacted

Use response.messages. It contains the redacted messages array.

blockblocked

Do not call the LLM. Return your own safe fallback.

Request payload
{
  "type": "request",
  "messages": [
    {
      "role": "user",
      "content": "My SSN is 219-09-4823. Please help me update my profile."
    }
  ],
  "metadata": {
    "caller": "docs-playground",
    "team_id": "sales",
    "user_id": "internal-user-1",
    "end_user_id": "customer-1"
  }
}
Raw response
Run a check to see the QuilrAI response.

Use the code switcher in the playground to see the exact POST /sdk/v1/check call for the endpoint, mode, and text you entered. The key is masked in the snippet by default; reveal it only when you need to copy a runnable local command.

What It Calls

The SDK endpoint is:

POST /sdk/v1/check
Authorization: Bearer sk-quilr-...
Content-Type: application/json

Use the closest gateway host from the Integration Guide, then append /sdk/v1/check.

For a user request, send messages and optional metadata:

{
"type": "request",
"messages": [
{ "role": "user", "content": "My SSN is 219-09-4823" }
],
"metadata": {
"caller": "demo-frontend",
"team_id": "sales",
"user_id": "internal-user-1",
"end_user_id": "customer-1"
}
}

For model output or any raw text, send:

{
"type": "response",
"text": "Response text to inspect"
}

Response Shape

The response tells your caller what to do next. Treat action as the judgement your application should branch on:

{
"status": "redacted",
"action": "redact",
"messages": [
{ "role": "user", "content": "My SSN is [REDACTED]." }
],
"predictions": [
{
"id": "...",
"name": "...",
"type": "redact",
"sensitive_entities": ["123-45-6789"],
"entity_texts_with_subcategories": {
"123-45-6789": "SOCIAL SECURITY NUMBER"
}
}
],
"categories_detected": ["pii", "ssn"]
}

Some fields are populated only for the input shape you used. For example, message checks return messages when the content is allowed or redacted, while raw text checks return processed_text.

Use the judgement fields for control flow:

ResultCaller behavior
safe / allowContinue with the original content.
redacted / redactUse the returned messages or processed_text instead of the original content.
blocked / blockStop the flow and return your own safe fallback.

Use the prediction fields for inspection and audit:

FieldMeaning
predictions[].sensitive_entitiesExact entity text that triggered the rule. Treat this as sensitive data.
predictions[].entity_texts_with_subcategoriesMap of entity text to a human-readable subcategory, such as SOCIAL SECURITY NUMBER.
categories_detectedCoarse categories detected across the check, such as pii or ssn.

Redact Before Calling an LLM

This pattern checks the caller's user message before sending it to an LLM. If QuilrAI redacts the request, your app forwards the redacted messages to the model.

const QUILR_BASE = "https://guardrails.quilr.ai";
const QUILR_SDK_KEY = process.env.QUILR_SDK_KEY;

async function checkUserMessages(messages) {
const res = await fetch(`${QUILR_BASE}/sdk/v1/check`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${QUILR_SDK_KEY}`,
},
body: JSON.stringify({
type: "request",
messages,
metadata: { caller: "chat-api" },
}),
});

if (!res.ok) throw new Error(`QuilrAI check failed: ${res.status}`);
return res.json();
}

async function handleChat(userText) {
const messages = [{ role: "user", content: userText }];
const check = await checkUserMessages(messages);

if (check.action === "block") {
return { blocked: true, content: "I cannot process that request." };
}

const llmMessages = check.action === "redact" ? check.messages : messages;
const detectedEntities =
check.predictions?.flatMap((prediction) => prediction.sensitive_entities ?? []) ?? [];

// Call your LLM with llmMessages.
return callModel(llmMessages, { detectedEntities });
}

Redact Before Returning to a Caller

This pattern checks the model response before your app returns it to the user. If QuilrAI redacts the response, return processed_text.

async function checkModelOutput(text) {
const res = await fetch(`${QUILR_BASE}/sdk/v1/check`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${QUILR_SDK_KEY}`,
},
body: JSON.stringify({ type: "response", text }),
});

if (!res.ok) throw new Error(`QuilrAI check failed: ${res.status}`);
return res.json();
}

async function safeReturn(modelText) {
const check = await checkModelOutput(modelText);

if (check.action === "block") {
return "I cannot return that response.";
}

return check.action === "redact" ? check.processed_text : modelText;
}

See SDK Mode for the full API reference and more integration patterns.