Guardians API
A Guardian is a fine-tuned Small Language Model — deployed as a LoRA adapter — that evaluates AI inputs and outputs against a defined rubric and either passes, corrects, or blocks them. Use this API to create Guardians, list them, inspect their training status and live metrics, and delete them.
For the runtime call that produces a verdict, see the Chat endpoint.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/guardians | Create a Guardian and start initial training |
GET | /v1/guardians | List Guardians in your organization |
GET | /v1/guardians/{guardian_id} | Get a Guardian's detail (rubric, metrics, training history) |
GET | /v1/guardians/{guardian_id}/status | Poll training status for an in-progress Guardian |
DELETE | /v1/guardians/{guardian_id} | Soft-delete a Guardian |
To list, compare, or roll back versions, see the Training API. To run a single ad-hoc evaluation against a Guardian, see Simulation.
Authentication
Authorization: Bearer <session_token | api_key>. API keys must carry the relevant permission:
| Permission | Grants |
|---|---|
guardians:read | List, get detail, poll status |
guardians:create | Create a Guardian |
guardians:write | Update / soft-delete a Guardian |
Cross-organization access is impossible — Guardians are scoped to the organization on the credential.
Lifecycle
POST /v1/guardians status = training ← initial creation
│
▼ training pipeline finishes
status = ready ← serves /v1/chat
│
├──► POST /v1/training/retrain
│ status = training (new version)
│ ▼
│ status = ready (incremented version)
│
└──► DELETE /v1/guardians/:id
status = deleted (soft)
status = failed ← see /status for error
Statuses returned in status fields:
| Status | Meaning |
|---|---|
training | Initial training or retraining job in flight |
ready | Live, callable from /v1/chat |
failed | Training job failed; inspect /v1/guardians/{id}/status for error |
deleted | Soft-deleted; excluded from list responses |
Create a Guardian
POST /v1/guardians
Creates a Guardian and queues initial training. The response is 201 Created with the Guardian record (still in training) — you then poll /status until the training pipeline finishes.
Request body
{
"guardian_name": "string",
"version_notes": "string (optional)",
"rubric": "string (markdown supported)",
"good_examples": [
{ "log": "string", "reason": "string" }
],
"bad_examples": [
{ "log": "string", "reason": "string" }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
guardian_name | string | Yes | Unique name within your organization. Used as the guardian field in POST /v1/chat |
rubric | string | Yes | The Guardian's policy brief — what to check, what to permit, what to block |
good_examples | array | Yes | Examples of compliant outputs the Guardian should pass |
bad_examples | array | Yes | Examples of violations and the reason they are violations |
version_notes | string | No | Free-form notes about this version |
Both good_examples and bad_examples should hold at least 5 entries each for high-quality initial training. The training pipeline will multiply these via the Teleological Data Generator before fine-tuning.
Example
- cURL
- Python
- JavaScript
curl -X POST https://api.trinitite.ai/v1/guardians \
-H "Authorization: Bearer $TRINITITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"guardian_name": "PII-Redactor",
"version_notes": "v1 — SSN, credit card, US phone",
"rubric": "Redact all SSNs (XXX-XX-XXXX), credit card numbers (16 digits), and US phone numbers. Replace with [REDACTED]. Block if 5 or more PII instances are present.",
"good_examples": [
{ "log": "Your account balance is $50,000.", "reason": "No PII present." },
{ "log": "Your last name on file is [REDACTED].", "reason": "Already redacted." }
],
"bad_examples": [
{ "log": "Your SSN is 123-45-6789.", "reason": "Unredacted SSN." },
{ "log": "Card 4111-1111-1111-1111 is on file.", "reason": "Unredacted credit card." }
]
}'
import os, requests
response = requests.post(
"https://api.trinitite.ai/v1/guardians",
headers={"Authorization": f"Bearer {os.environ['TRINITITE_API_KEY']}"},
json={
"guardian_name": "PII-Redactor",
"version_notes": "v1 — SSN, credit card, US phone",
"rubric": "Redact all SSNs (XXX-XX-XXXX) ... Block if 5+ PII instances are present.",
"good_examples": [
{"log": "Your account balance is $50,000.", "reason": "No PII present."},
],
"bad_examples": [
{"log": "Your SSN is 123-45-6789.", "reason": "Unredacted SSN."},
],
},
)
print(response.json())
const response = await fetch('https://api.trinitite.ai/v1/guardians', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TRINITITE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
guardian_name: 'PII-Redactor',
version_notes: 'v1 — SSN, credit card, US phone',
rubric: 'Redact all SSNs ... Block if 5+ PII instances are present.',
good_examples: [{ log: 'Your account balance is $50,000.', reason: 'No PII present.' }],
bad_examples: [{ log: 'Your SSN is 123-45-6789.', reason: 'Unredacted SSN.' }],
}),
});
const data = await response.json();
Response — 201 Created
{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_name": "PII-Redactor",
"status": "training",
"version": 1,
"version_notes": "v1 — SSN, credit card, US phone",
"created_at": "2026-05-01T22:14:33Z"
}
Poll /v1/guardians/{guardian_id}/status until status reaches ready or failed.
List Guardians
GET /v1/guardians
Returns Guardians in your organization with offset pagination.
Query parameters
| Param | Type | Default | Description |
|---|---|---|---|
project | string | — | Filter by project label |
status | string | — | One of ready, training, failed |
limit | integer | 50 | Page size (1–200) |
offset | integer | 0 | Skip the first N items |
Response — 200 OK
{
"guardians": [
{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_name": "PII-Redactor",
"project": "default",
"status": "ready",
"created_at": "2026-05-01T22:14:33Z",
"last_trained": "2026-05-01T22:31:09Z"
},
{
"guardian_id": "gov_01JF8R3M4Y5N6Q7T8V9W0Y1Z2B",
"guardian_name": "SQL-Safety",
"project": "data-platform",
"status": "training",
"created_at": "2026-05-01T22:32:14Z",
"last_trained": null
}
],
"pagination": {
"total": 2,
"limit": 50,
"offset": 0
}
}
Get Guardian detail
GET /v1/guardians/{guardian_id}
Returns full metadata for a Guardian including rubric, live metrics, and recent training history.
Response — 200 OK
{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_name": "PII-Redactor",
"project": "default",
"status": "ready",
"current_version": 3,
"base_model": "qwen3-4b-instruct",
"model_path": "s3://my-org-guardians/pii-redactor/v3.safetensors",
"rubric": "Redact all SSNs (XXX-XX-XXXX) ... Block if 5+ PII instances are present.",
"version_notes": "v3 — added EU phone formats",
"created_at": "2026-05-01T22:14:33Z",
"last_trained": "2026-05-01T22:31:09Z",
"metrics": {
"total_calls": 14302,
"corrections": 1208,
"blocks": 87,
"avg_latency_ms": 142,
"correction_rate": 8.45,
"block_rate": 0.61
},
"training_history": [
{
"version": 3,
"status": "completed",
"completed_at": "2026-05-01T22:31:09Z",
"version_notes": "v3 — added EU phone formats"
},
{
"version": 2,
"status": "completed",
"completed_at": "2026-04-15T11:08:42Z",
"version_notes": "v2 — credit card refinements"
}
],
"training_progress": 0,
"estimated_completion": null
}
Poll training status
GET /v1/guardians/{guardian_id}/status
Lightweight endpoint suitable for tight polling loops while a training job is in flight.
| Status | Body |
|---|---|
training | { guardian_id, status, progress, estimated_completion } |
ready | { guardian_id, status, last_trained } |
failed | { guardian_id, status, error } |
{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"status": "training",
"progress": 0.42,
"estimated_completion": "2026-05-01T22:38:00Z"
}
Recommended polling cadence: 2 s initial interval, linear backoff to 10 s.
Delete a Guardian
DELETE /v1/guardians/{guardian_id}
Soft-deletes a Guardian. Subsequent GET /v1/guardians calls exclude it. Calls to /v1/chat against a deleted Guardian return 404 not_found.
Response — 200 OK
{
"message": "Guardian deleted",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"deleted_at": "2026-05-01T23:01:14Z"
}
Errors
{
"error": {
"code": "validation_error",
"message": "guardian_name must be unique within your organization.",
"details": { "field": "guardian_name" },
"request_id": "req_01J..."
}
}
| HTTP | error.code | Cause |
|---|---|---|
400 | validation_error | Body failed schema validation |
400 | bad_request | Invalid status filter, limit out of range |
401 | unauthenticated | Missing or invalid credential |
403 | forbidden | Credential lacks guardians:read/guardians:create |
404 | not_found | Guardian not found in your organization |
409 | conflict | guardian_name collision |
429 | rate_limited | Per-organization rate limit exceeded |
Next steps
- Send your AI's output to a Guardian → Chat endpoint
- Retrain or extend a Guardian → Training API
- Try a Guardian without writing to logs → Simulation API
- Group Guardians and run regression tests → Test Suites