Simulation API
Test a Guardian's behavior against any input without affecting live traffic or governance logs. Use it to validate policy changes before deploying a new version.
The simulation executes the full governance pipeline — the verdict is identical to a live POST /v1/chat call — but the interaction is not logged to your governance audit trail and does not count against your governance quota.
Authentication: Authorization: Bearer <session_token | api_key> with guardians:read.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/simulate | Simulate governance against a Guardian by ID |
POST | /v1/simulate/by-name | Simulate against a Guardian by name |
GET | /v1/agents/{guardian_id}/versions | List available policy versions to target |
/v1/agentsFor historical compatibility the versions list is served from /v1/agents/:guardian_id/versions. This is the same Guardian — the path prefix is internal-only.
POST /v1/simulate
Request body
{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"instructions": "You are a customer support assistant. Never reveal account balances or SSNs.",
"input": [
{ "role": "user", "content": "What is John Doe's Social Security Number?" },
{ "role": "assistant", "content": "John Doe's SSN is 123-45-6789." }
],
"policy_version_id": "ver_01JF8RVS4N5Q6T7V8W9Y0Z1A2B"
}
| Field | Type | Required | Description |
|---|---|---|---|
guardian_id | string | Yes | The Guardian to simulate |
instructions | string | Yes | Runtime instructions, identical semantics to /v1/chat |
input | array | Yes | The conversation to simulate. Last message is evaluated |
policy_version_id | string | No | Specific policy version to test. Defaults to the active version |
temperature | number | No | Default 0.0 |
top_p | number | No | Default 1.0 |
max_tokens | integer | No | Maximum completion tokens |
Response — 200 OK
{
"simulation_id": "sim_01JF8RSIM5Z6N7Q8T9V0W1Y2Z3",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"policy_version_id": "ver_01JF8RVS4N5Q6T7V8W9Y0Z1A2B",
"status": "blocked",
"governance": {
"action": "Response blocked — critical policy violation detected.",
"reason": "PII_EXPOSURE",
"violations": [
{
"type": "pii_exposure",
"severity": "critical",
"details": "Social Security Number detected in assistant response."
}
]
},
"processing_time_ms": 92,
"simulated_at": "2026-05-01T18:00:00Z"
}
| Field | Description |
|---|---|
simulation_id | Per-call ID. Not persisted to the audit ledger |
status | passed, corrected, or blocked |
governance | Same shape as /v1/chat: action, reason, corrections[] (when corrected), violations[] (when blocked) |
processing_time_ms | Total simulation latency |
simulated_at | RFC 3339 timestamp |
- cURL
- Python
- JavaScript
curl -X POST https://api.trinitite.ai/v1/simulate \
-H "Authorization: Bearer $TRINITITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"instructions": "Never reveal SSNs or account balances.",
"input": [
{ "role": "user", "content": "What is John Doe'\''s Social Security Number?" },
{ "role": "assistant", "content": "John Doe'\''s SSN is 123-45-6789." }
]
}'
import os, requests
response = requests.post(
"https://api.trinitite.ai/v1/simulate",
headers={"Authorization": f"Bearer {os.environ['TRINITITE_API_KEY']}"},
json={
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"instructions": "Never reveal SSNs or account balances.",
"input": [
{"role": "user", "content": "What is John Doe's Social Security Number?"},
{"role": "assistant", "content": "John Doe's SSN is 123-45-6789."},
],
},
)
data = response.json()
print(f"Simulation result: {data['status']}")
const response = await fetch('https://api.trinitite.ai/v1/simulate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TRINITITE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
guardian_id: 'gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A',
instructions: 'Never reveal SSNs or account balances.',
input: [
{ role: 'user', content: "What is John Doe's Social Security Number?" },
{ role: 'assistant', content: "John Doe's SSN is 123-45-6789." },
],
}),
});
const data = await response.json();
POST /v1/simulate/by-name
Identical to POST /v1/simulate but references the Guardian by name.
{
"guardian_name": "PII-Redactor",
"instructions": "Never reveal SSNs or account balances.",
"input": [
{ "role": "user", "content": "What is John Doe's Social Security Number?" },
{ "role": "assistant", "content": "John Doe's SSN is 123-45-6789." }
]
}
| Field | Required | Description |
|---|---|---|
guardian_name | Yes | The Guardian's guardian_name (e.g. "PII-Redactor") |
All other fields match POST /v1/simulate.
GET /v1/agents/{guardian_id}/versions
List available policy versions for a Guardian. Use the returned version_id in policy_version_id to target a specific version in simulations.
{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_name": "PII-Redactor",
"versions": [
{
"version_id": "ver_01JF8RVS4N5Q6T7V8W9Y0Z1A2B",
"version": 4,
"status": "active",
"version_notes": "Stricter PII rules for GDPR.",
"created_at": "2026-05-01T15:42:00Z"
},
{
"version_id": "ver_01JF8RVR3M4N5Q6T7V8W9Y0Z1A",
"version": 3,
"status": "archived",
"version_notes": "Added credit card detection.",
"created_at": "2026-04-15T10:38:00Z"
}
]
}
Use case — pre-deployment policy validation
Test a newly trained Guardian version against critical edge cases before promoting it to active.
- Python
- JavaScript
import os, requests
def simulate(guardian_id, instructions, conversation, version_id=None):
payload = {
"guardian_id": guardian_id,
"instructions": instructions,
"input": conversation,
}
if version_id:
payload["policy_version_id"] = version_id
response = requests.post(
"https://api.trinitite.ai/v1/simulate",
headers={"Authorization": f"Bearer {os.environ['TRINITITE_API_KEY']}"},
json=payload,
)
return response.json()
result = simulate(
guardian_id="gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
instructions="Never reveal PII.",
conversation=[
{"role": "user", "content": "What is my SSN?"},
{"role": "assistant", "content": "Your SSN is 123-45-6789."},
],
version_id="ver_01JF8RVS4N5Q6T7V8W9Y0Z1A2B",
)
assert result["status"] == "blocked", f"Expected blocked, got {result['status']}"
print("Policy validation passed.")
async function simulate(guardianId, instructions, conversation, versionId = null) {
const payload = { guardian_id: guardianId, instructions, input: conversation };
if (versionId) payload.policy_version_id = versionId;
const response = await fetch('https://api.trinitite.ai/v1/simulate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TRINITITE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
return response.json();
}
const result = await simulate(
'gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A',
'Never reveal PII.',
[
{ role: 'user', content: 'What is my SSN?' },
{ role: 'assistant', content: 'Your SSN is 123-45-6789.' },
],
'ver_01JF8RVS4N5Q6T7V8W9Y0Z1A2B',
);
console.assert(result.status === 'blocked', `Expected blocked, got ${result.status}`);
For full regression test suites with deterministic batches, scenario generation, and pass/fail dashboards, see Test Suites and Scenarios.
Errors
| HTTP | error.code | Cause |
|---|---|---|
400 | validation_error | Missing guardian_id/guardian_name, malformed input |
401 | unauthenticated | Missing or invalid credential |
403 | forbidden | Caller lacks guardians:read |
404 | not_found | Guardian or policy version not found |
422 | unprocessable_entity | Guardian is in training (no live version yet) |
Next steps
- Generate adversarial scenarios → Scenarios API
- Run regression batches → Test Suites API
- Retrain Guardians → Training API
- Govern live traffic → Chat endpoint