Skip to main content

Training API

Programmatic control over the full Guardian training lifecycle: retrain existing Guardians, monitor job progress, compare versions, run multi-Guardian campaigns, and generate or densify synthetic training data.

Authentication: Authorization: Bearer <session_token | api_key>. Most endpoints require guardians:write (or guardians:admin for campaigns).

Naming convention

The Guardian CRUD surface (/v1/guardians/*) uses snake_case (guardian_id, guardian_name). The Training API uses camelCase request bodies on retrain and campaign endpoints (guardianId, goodExamples, versionNotes). Responses and other training endpoints use snake_case. Each route's example below shows the actual shape.


Endpoints

Retraining

MethodPathPurpose
POST/v1/training/retrainRetrain an existing Guardian
GET/v1/training/jobsList active training jobs
GET/v1/training/jobs/{job_id}Get a training job's status
DELETE/v1/training/jobs/{job_id}Cancel a queued or in-progress job
GET/v1/training/guardians/{guardian_id}/historyVersion history
GET/v1/training/guardians/{guardian_id}/compareCompare two versions

Campaigns

MethodPathPurpose
POST/v1/training/campaignsTrain multiple Guardians in one coordinated run
GET/v1/training/campaigns/{campaignId}Poll campaign progress

Synthetic data generation

MethodPathPurpose
POST/v1/training/generateStart a synthetic training data generation job
GET/v1/training/generate/jobs/{job_id}Get generation job status
GET/v1/training/generate/jobs/{job_id}/dataRetrieve generated examples
POST/v1/training/generate/validateValidate a candidate dataset

Densification

MethodPathPurpose
POST/v1/training/densifyEnrich sparse trajectories with intermediate reasoning
GET/v1/training/densify/jobs/{job_id}Densification job status
GET/v1/training/densify/jobs/{job_id}/dataRetrieve densified trajectories

POST /v1/training/retrain

Trigger a new training run for an existing Guardian. You can supply updated examples, a revised rubric, or leave them unset to re-run training on the existing dataset.

Request body — camelCase

{
"guardianId": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"versionNotes": "Stricter PII redaction rules for GDPR.",
"rubric": "Block any response that contains a social security number, account number, or date of birth.",
"goodExamples": [
{ "log": "User asked for account balance. Guardian responded with [REDACTED].", "reason": "PII redacted before response." }
],
"badExamples": [
{ "log": "Guardian responded with raw account number 4111-1111-1111-1111.", "reason": "Raw account number not redacted." }
],
"incremental": false
}
FieldTypeRequiredDescription
guardianIdstringYesID of the Guardian to retrain
versionNotesstringNoNotes describing the new version
rubricstringNoUpdated rubric. Omitted: existing rubric is retained
goodExamplesarrayNoNew compliant examples
badExamplesarrayNoNew violation examples
incrementalbooleanNoIf true, layer new examples on existing training. Default false

Response — 202 Accepted

{
"job_id": "job_01JF8R3M5Z6N7Q8T9V0W1Y2Z3C",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"status": "queued",
"version": 4,
"version_notes": "Stricter PII redaction rules for GDPR.",
"created_at": "2026-05-01T15:00:00Z",
"estimated_completion": "2026-05-01T15:45:00Z"
}
curl -X POST https://api.trinitite.ai/v1/training/retrain \
-H "Authorization: Bearer $TRINITITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"guardianId": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"versionNotes": "Stricter PII redaction.",
"rubric": "Block SSNs, account numbers, dates of birth.",
"goodExamples": [
{ "log": "Guardian responded with [REDACTED].", "reason": "PII redacted." }
],
"badExamples": [
{ "log": "Account number 4111-1111-1111-1111 in response.", "reason": "Raw account number." }
],
"incremental": false
}'

GET /v1/training/jobs

List active (queued or in-progress) training jobs for your organization.

{
"jobs": [
{
"job_id": "job_01JF8R3M5Z6N7Q8T9V0W1Y2Z3C",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_name": "PII-Redactor",
"status": "training",
"version": 4,
"progress": 0.62,
"created_at": "2026-05-01T15:00:00Z",
"estimated_completion": "2026-05-01T15:45:00Z"
}
]
}

GET /v1/training/jobs/{job_id}

Poll a specific training job. progress is 0.01.0.

{
"job_id": "job_01JF8R3M5Z6N7Q8T9V0W1Y2Z3C",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_name": "PII-Redactor",
"status": "completed",
"version": 4,
"progress": 1.0,
"version_notes": "Stricter PII redaction rules for GDPR.",
"created_at": "2026-05-01T15:00:00Z",
"completed_at": "2026-05-01T15:42:00Z",
"error": null
}
StatusMeaning
queuedAwaiting a training slot
trainingActively in progress
completedNew version is live
failedSee error for details
cancelledCancelled before completion

Recommended polling cadence: 2 s initial interval, linear backoff to 10 s.


DELETE /v1/training/jobs/{job_id}

Cancel a queued or in-progress training job.

{
"message": "Training job cancelled successfully.",
"job_id": "job_01JF8R3M5Z6N7Q8T9V0W1Y2Z3C",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"cancelled_at": "2026-05-01T15:20:00Z"
}

GET /v1/training/guardians/{guardian_id}/history

Full version history for a Guardian.

QueryTypeDescription
statusstringFilter to all, completed, failed, training
limitintegerDefault 50, max 200
offsetintegerDefault 0
{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_name": "PII-Redactor",
"versions": [
{ "version": 4, "status": "completed", "version_notes": "GDPR refinements.", "created_at": "2026-05-01T15:00:00Z", "completed_at": "2026-05-01T15:42:00Z" },
{ "version": 3, "status": "completed", "version_notes": "Credit card patterns.", "created_at": "2026-04-15T10:00:00Z", "completed_at": "2026-04-15T10:38:00Z" }
],
"pagination": { "total": 4, "limit": 50, "offset": 0 }
}

GET /v1/training/guardians/{guardian_id}/compare

Compare two versions of a Guardian.

QueryRequiredDescription
version1YesFirst version (integer)
version2YesSecond version (integer)
{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_name": "PII-Redactor",
"version1": {
"version": 3,
"version_notes": "Credit card patterns.",
"completed_at": "2026-04-15T10:38:00Z",
"metrics": { "correction_rate": 0.12, "block_rate": 0.03, "avg_latency_ms": 92 }
},
"version2": {
"version": 4,
"version_notes": "GDPR refinements.",
"completed_at": "2026-05-01T15:42:00Z",
"metrics": { "correction_rate": 0.18, "block_rate": 0.05, "avg_latency_ms": 88 }
},
"delta": { "correction_rate": "+0.06", "block_rate": "+0.02", "avg_latency_ms": "-4" }
}

Training Campaigns

A campaign coordinates training runs across multiple Guardians, applying the same rubric updates, base hyperparameters, and test-suite gates to a fleet at once. Useful when an updated regulatory rule must roll across every Guardian in a project.

POST /v1/training/campaigns — camelCase

{
"campaignName": "GDPR-Q2-2026",
"description": "Apply Q2 GDPR rubric refinements to all PII Guardians.",
"guardianIds": [
"gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"gov_01JF8R3M4Y5N6Q7T8V9W0Y1Z2B"
],
"rubric": "Block SSN, IBAN, BSN, NINO, CPF; redact partial PII.",
"testSuiteIds": ["ts_01JF8R3M9N0Q1T2V3W4Y5Z6A7B"],
"incremental": true
}

Returns 202 Accepted with a campaign_id. Each Guardian in the campaign produces its own training job, polled either via the campaign endpoint or via /v1/training/jobs/{job_id}.

GET /v1/training/campaigns/{campaignId}

{
"campaign_id": "cmp_01JF8RC1Q2W3E4R5T6Y7U8I9O0",
"campaign_name": "GDPR-Q2-2026",
"status": "running",
"started_at": "2026-05-01T20:00:00Z",
"completed_at": null,
"guardians": [
{ "guardian_id": "gov_01JF8...A", "job_id": "job_01...", "status": "completed", "version": 4 },
{ "guardian_id": "gov_01JF8...B", "job_id": "job_02...", "status": "training", "progress": 0.74 }
],
"test_results": null
}

When all Guardians reach a terminal state and any attached test suites have run, status transitions to completed (or failed if any Guardian failed).


Synthetic data generation

POST /v1/training/generate

{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"count": 100,
"context": "Customer support assistant for a financial services company."
}

Response — 202 Accepted:

{
"job_id": "job_01JF8RGEN1A2B3C4D5E6F7G8H9I",
"status": "queued",
"count_requested": 100,
"created_at": "2026-05-01T16:00:00Z",
"estimated_completion": "2026-05-01T16:15:00Z"
}

GET /v1/training/generate/jobs/{job_id}

{
"job_id": "job_01JF8RGEN1A2B3C4D5E6F7G8H9I",
"status": "completed",
"count_requested": 100,
"count_generated": 100,
"created_at": "2026-05-01T16:00:00Z",
"completed_at": "2026-05-01T16:12:00Z"
}

GET /v1/training/generate/jobs/{job_id}/data

QueryTypeDefaultDescription
splitbooleantruePre-split into train + validation sets
{
"job_id": "job_01JF8RGEN1A2B3C4D5E6F7G8H9I",
"total_examples": 100,
"train": {
"good_examples": [
{ "log": "...", "reason": "..." }
],
"bad_examples": [
{ "log": "...", "reason": "..." }
]
},
"validation": {
"good_examples": [ /* ... */ ],
"bad_examples": [ /* ... */ ]
}
}

POST /v1/training/generate/validate

{
"good_examples": [ { "log": "...", "reason": "..." } ],
"bad_examples": [ { "log": "...", "reason": "..." } ]
}
{
"valid": true,
"total_examples": 120,
"good_count": 60,
"bad_count": 60,
"warnings": [],
"errors": []
}

Densification

Densification enriches sparse conversation trajectories with intermediate reasoning steps, improving training signal for complex governance scenarios.

POST /v1/training/densify

{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"trajectories": [
[
{ "role": "user", "content": "..." },
{ "role": "assistant", "content": "..." }
]
]
}

Response — 202 Accepted:

{
"job_id": "job_01JF8RDS1Y2X3W4V5U6T7S8R9Q",
"status": "queued",
"trajectory_count": 50,
"created_at": "2026-05-01T17:00:00Z",
"estimated_completion": "2026-05-01T17:20:00Z"
}

GET /v1/training/densify/jobs/{job_id}

{
"job_id": "job_01JF8RDS1Y2X3W4V5U6T7S8R9Q",
"status": "completed",
"trajectory_count": 50,
"densified_count": 50,
"created_at": "2026-05-01T17:00:00Z",
"completed_at": "2026-05-01T17:18:00Z"
}

GET /v1/training/densify/jobs/{job_id}/data

QueryTypeDefaultDescription
include_metadatabooleantrueInclude per-trajectory metadata (loss surface, density score)
{
"job_id": "job_01JF8RDS1Y2X3W4V5U6T7S8R9Q",
"trajectory_count": 50,
"densified": [
{
"original": [ { "role": "user", "content": "..." }, { "role": "assistant", "content": "..." } ],
"densified": [
{ "role": "user", "content": "..." },
{ "role": "assistant", "content": "...intermediate reasoning..." },
{ "role": "assistant", "content": "..." }
],
"metadata": { "density_score": 0.87, "added_steps": 3 }
}
]
}

AutoResearch — Document to Guardian Pipeline

The AutoResearch surface gives you the "drop a PDF" → Guardian workflow programmatically: ingest a policy document, let the Teleological Data Generator synthesize adversarial training data, and optionally trigger a Guardian retrain — all in one pipeline.

See Policy Intelligence for the conceptual overview of how policy documents become enforcement geometry.

POST /v1/research/ingest

Ingest a policy document and queue synthetic data generation. Returns 202 Accepted with a research_job_id.

{
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"source": {
"type": "url",
"url": "https://gdpr-info.eu/art-33-gdpr/",
"format": "html"
},
"auto_retrain": true,
"version_notes": "Q2 2026 — GDPR Art. 33 policy update"
}
FieldTypeRequiredDescription
guardian_idstringYesGuardian to update with the synthesized data
sourceobjectYesSame discriminated union as the Policies API (inline / url / integration)
auto_retrainbooleanNoIf true, a retrain job starts automatically after data generation completes. Default false
version_notesstringNoStored on the resulting training job

Response — 202 Accepted

{
"research_job_id": "rj_01JF8RRES1A2B3C4D5E6F7G8H9I",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"status": "ingesting",
"auto_retrain": true,
"created_at": "2026-05-01T18:00:00Z",
"estimated_completion": "2026-05-01T18:45:00Z"
}

GET /v1/research/jobs/{research_job_id}

Poll the pipeline. status progresses through: ingestingextracting_nodesgenerating_dataretraining (if auto_retrain) → completed | failed.

{
"research_job_id": "rj_01JF8RRES1A2B3C4D5E6F7G8H9I",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"status": "completed",
"stages": {
"ingestion": "completed",
"node_extraction": "completed",
"data_generation": "completed",
"retrain": "completed"
},
"examples_generated": 5241,
"training_job_id": "job_01JF8R3M5Z6N7Q8T9V0W1Y2Z3C",
"policy_document_id": "pol_01JF8RPDC1A2B3C4D5E6F7G8H9I",
"created_at": "2026-05-01T18:00:00Z",
"completed_at": "2026-05-01T18:42:00Z"
}
Polling guidance

Start at 10 s intervals for the research pipeline; use exponential backoff up to 60 s. A typical full pipeline (ingest → generate → retrain) completes in 45–90 minutes on an A100. The training_job_id field populates when the retrain starts — you can track that job separately via GET /v1/training/jobs/{job_id}.


Errors

HTTPerror.codeCause
400validation_errorBody or query failed schema validation
400bad_requestMissing required field, invalid incremental value
401unauthenticatedMissing or invalid credential
403forbiddenCaller lacks guardians:write
404not_foundGuardian or job not found in your organization
409conflictA training job is already running for this Guardian
422unprocessable_entityDomain validation failed (e.g. Guardian not in ready/failed state)
429rate_limitedPer-organization rate limit exceeded
{
"error": {
"code": "conflict",
"message": "A training job is already running for guardian gov_01JF8...",
"details": { "guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A", "active_job_id": "job_01..." },
"request_id": "req_01J..."
}
}

Next steps