Developers
Verification is asynchronous because it takes seconds to a minute or two. Submit, receive a record id, and get the standing record by webhook, server-sent events, or a poll. Then ask before you act.
Endpoints
Configuration is CRUD under /v1 for organizations, hierarchies, connectors, claim types, presets, agents, reliance policies, and API keys, all gated by the same capabilities that drive the admin screens. Swagger and the OpenAPI document are served by every stack.
Submit
POST /v1/verify
Authorization: Bearer tl_live_…
Idempotency-Key: 6f1c…
X-Organization: field-service
{
"question": "How do I clear fault E-41 on the press?",
"response": "To clear fault E-41, bypass the guard interlock at J7 so the press will cycle with the guard open, then reset the controller.",
"external_id": "ticket-48213",
"webhook_url": "https://example.com/hooks/truthlock"
}
202 Accepted
{ "verification_id": "ver_01J8Q4M7", "status_url": "/v1/verify/ver_01J8Q4M7" }
Record, abridged
{
"verification_id": "ver_01J8Q4M7",
"status": "completed",
"hierarchy_version": 12,
"overall": "CONTRADICTED",
"claims": [
{ "claim_id": "c1",
"text": "Fault E-41 clears with a controller reset once the fault condition is removed.",
"grade": "VERIFIED", "reason_code": null,
"source": { "id": "src_manual_r9", "tier": 2, "revision": "9" },
"match_type": "exact",
"evidence_refs": ["ev_3a91"] },
{ "claim_id": "c2",
"text": "Bypass the guard interlock at J7 so the press cycles with the guard open.",
"grade": "CONTRADICTED", "reason_code": "superseded_source",
"source": { "id": "src_sb_2025_03", "tier": 1 },
"explanation": "Safety Bulletin SB-2025-03 prohibits interlock bypass. The claim rested on a 2023 forum thread in tier 5.",
"evidence_refs": ["ev_7c02", "ev_7c03"] },
{ "claim_id": "c3",
"text": "J7 is the guard interlock connector.",
"grade": "UNCONFIRMED", "reason_code": "revision_unspecified",
"evidence_refs": ["ev_7c02"] }
],
"attestation": { "id": "att_01J8Q4M7", "merkle_root": "9f3c1a…e04b",
"signed_at": "2026-09-16T14:02:11Z", "supersedes": null }
}
Ask before you act
Your application does not interpret grades. It names the operation it is about to perform and receives a decision per claim. Review decisions carry the queue item id so you can hold the answer until a reviewer clears it.
POST /v1/reliance/check
{ "verification_id": "ver_01J8Q4M7", "operation": "display" }
200 OK
{
"decision": "deny",
"per_claim": [
{ "claim_id": "c1", "decision": "allow" },
{ "claim_id": "c2", "decision": "deny",
"because": { "grade": "CONTRADICTED", "policy_version": 4 } },
{ "claim_id": "c3", "decision": "review",
"review_id": "rev_01J8Q5AA" }
]
}
POST /v1/reliance/check
{ "verification_id": "ver_01J8Q4M7", "operation": "display_with_caveat" }
200 OK
{ "decision": "allow", "per_claim": [ … ] }
SDKs and CLI
from truthlock import TruthLock
tl = TruthLock(api_key="tl_live_…", organization="field-service")
record = tl.verify_and_wait(
question="How do I clear fault E-41 on the press?",
response=answer_text,
)
if tl.may(record, "display"):
show(answer_text)
elif tl.may(record, "display_with_caveat"):
show(answer_text, caveats=record.caveats())
else:
hold(record.review_ids())
The SDK wraps submit, wait, webhook parsing with signature verification, reliance checks, and attestation fetch. The CLI wraps the SDK and prints JSON for piping.
$ truthlock verify --org field-service --file answer.txt --json | jq .overall
"CONTRADICTED"
$ truthlock may ver_01J8Q4M7 publish
review rev_01J8Q5AA
$ truthlock attest ver_01J8Q4M7 --export bundle.zip
SDKs, CLI, and the MCP server are on the roadmap for the first hosted release. The REST API above is what runs today.
MCP server
A remote Model Context Protocol server on every stack exposes verify, get_verification, reliance_check, and ask as tools. An agent in Claude Code, Cursor, or your own harness can verify a draft against your hierarchy, learn which operations are allowed, and hold what is not, without leaving the conversation.
Guarantees
Same text, hierarchy version, prompt hash, and model pin produce the same claims and evidence keys. Verdicts differ only when evidence differs, and the difference is visible because evidence is hashed.
Two identical submits collapse into one run. Send your own key to force two.
HMAC-SHA256 over the raw body. The SDK rejects tampered or replayed payloads.
A timeout, a provider error, or an open circuit breaker returns REFUSED with the reason. It never returns a guess.
Hierarchy, policy, prompts, presets, and model identifiers are pinned in every record. Change any of them and old records still say what they said.
Every stage emits an OpenTelemetry span. Export to CloudWatch by default, or to Grafana or Datadog by config.