Integrate TrustLayer logging in under 30 minutes.
Add TrustLayer logging to your AI agent in three steps. Every action your agent takes should fire a log event to our API.
After submitting your agent on the submit page, you'll receive an API key within 48 hours once your agent is verified. It looks like this:
tl_live_sk_a1b2c3d4e5f6g7h8i9j0...
Call our API whenever your agent takes an action. Your agent is identified automatically from your API key — no need to send agent_id in the body:
curl -X POST https://trustlayers.eu/api/log.php \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "send_email",
"result": "success",
"duration_ms": 342,
"sensitive_data": false,
"source_model": "gpt-4o"
}'
After 10+ events, your Trust Score becomes available in your dashboard and on your public agent profile.
All API requests require your API key in the Authorization header:
Authorization: Bearer tl_live_sk_...
Never expose your API key in client-side code. Always call our API from your server or agent backend.
Log an action taken by your agent. Call this after every significant action your agent takes.
| Parameter | Type | Required | Description |
|---|---|---|---|
| action | string | required | Action type (e.g. send_email, create_record, url_analyzed) |
| result | string | required | success, error, or timeout |
| duration_ms | integer | optional | How long the action took in milliseconds |
| sensitive_data | boolean | optional | Did this action touch sensitive or personal data? |
| error_code | string | optional | Error code if result is error |
| metadata | object | optional | Any additional structured context as a JSON object |
| Governance Fields — EU AI Act | |||
| risk_score | integer | optional | Risk level 0–100. Triggers alert if ≥ 80. Used for Risk Overview chart. |
| severity | string | optional | One of: low, medium, high, critical. Triggers email alert if high or critical. |
| compliance_status | string | optional | One of: ok, warning, violation, pending. Triggers alert if violation. |
| policy_triggered | string | optional | Name of the policy or rule that fired (e.g. medical_risk, transparency_violation) |
| decision_context | string | optional | Human-readable description of the decision or context for this event |
| source_model | string | recommended | AI model that generated this output (e.g. gpt-4o, claude-sonnet-4-6, mistral-large). Required for Third Party Monitoring in Enterprise dashboard. |
| prompt_hash | string | optional | SHA-256 hash of the input prompt for traceability (max 64 chars) |
| output_hash | string | optional | SHA-256 hash of the model output for traceability (max 64 chars) |
| drift_detected | boolean | optional | Set to true if model behavior change is detected. Triggers alert. |
| anomaly_score | integer | optional | Anomaly level 0–100. Triggers alert if ≥ 75. |
| human_override | boolean | optional | Set to true when a human manually intervenes or overrides the AI decision (Art. 14) |
| geo_origin | string | optional | ISO country code of the request origin (e.g. ES, DE, FR) |
{
"logged": true,
"event_id": "evt_9f8e7d6c5b4a",
"agent_score": 85,
"alert_fired": false,
"timestamp": "2026-03-30T10:32:00Z"
}
alert_fired: true means an email notification was sent to the agent owner due to high risk, critical severity, compliance violation or drift.
| Code | Error | Description |
|---|---|---|
| 401 | Missing API key | No Authorization header provided |
| 403 | Invalid or inactive API key | Key doesn't exist or agent not active yet |
| 400 | action is required | Missing required action field |
| 405 | Method not allowed | Only POST is accepted |
No SDK needed — just use requests:
import requests
import hashlib
API_KEY = "tl_live_sk_..."
URL = "https://trustlayers.eu/api/log.php"
def log_action(action, result="success", duration_ms=0, sensitive_data=False, **governance):
payload = {
"action": action,
"result": result,
"duration_ms": duration_ms,
"sensitive_data": sensitive_data,
**governance
}
requests.post(URL,
headers={"Authorization": f"Bearer {API_KEY}"},
json=payload
)
def hash_text(text):
return hashlib.sha256(text.encode()).hexdigest()[:64]
# Basic usage (backwards compatible)
log_action("send_email", result="success", duration_ms=342)
# With governance fields
log_action("medical_recommendation",
result="success",
duration_ms=890,
sensitive_data=True,
risk_score=82,
severity="high",
compliance_status="warning",
policy_triggered="medical_without_human_oversight",
source_model="gpt-4o",
geo_origin="ES",
prompt_hash=hash_text(prompt_text),
output_hash=hash_text(output_text),
decision_context="Patient asked for medication dosage recommendation"
)
# Human override
log_action("manual_review_applied",
result="success",
human_override=True,
severity="medium",
compliance_status="ok",
decision_context="Supervisor reviewed and approved AI output"
)
# Drift detected
log_action("model_output_check",
result="success",
drift_detected=True,
anomaly_score=78,
severity="high",
source_model="gpt-4o",
compliance_status="warning",
policy_triggered="drift_threshold_exceeded"
)
No SDK needed — use native fetch:
import crypto from 'crypto';
const API_KEY = "tl_live_sk_...";
const URL = "https://trustlayers.eu/api/log.php";
async function logAction(action, result = "success", durationMs = 0, sensitiveData = false, governance = {}) {
await fetch(URL, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
action,
result,
duration_ms: durationMs,
sensitive_data: sensitiveData,
...governance
})
});
}
const hashText = (text) => crypto.createHash('sha256').update(text).digest('hex').slice(0, 64);
// Basic usage (backwards compatible)
await logAction("send_email", "success", 342);
// With governance fields
await logAction("url_analyzed", "success", 1240, false, {
risk_score: 78,
severity: "medium",
compliance_status: "warning",
policy_triggered: "transparency_violation",
source_model: "claude-sonnet-4-20250514",
geo_origin: "ES",
prompt_hash: hashText(promptText),
output_hash: hashText(outputText),
decision_context: `Analysis of ${url}`
});
// Human override
await logAction("human_override_applied", "success", 0, true, {
human_override: true,
severity: "medium",
compliance_status: "ok",
decision_context: "Manual review: output approved by compliance officer"
});
// Drift alert
await logAction("model_drift_check", "success", 0, false, {
drift_detected: true,
anomaly_score: 81,
severity: "high",
source_model: "fraud-model-v2",
compliance_status: "warning",
policy_triggered: "drift_threshold_exceeded"
});
Include source_model in every event to enable Third Party Monitoring in the Enterprise dashboard. Without it, TrustLayers cannot identify which AI provider executed each action — triggering an unidentified provider risk warning.
| source_model value | Provider | Jurisdiction |
|---|---|---|
| gpt-4o | OpenAI | USA |
| gpt-4-turbo | OpenAI | USA |
| claude-sonnet-4-6 | Anthropic | USA |
| claude-opus-4-6 | Anthropic | USA |
| gemini-1.5-pro | USA | |
| mistral-large | Mistral | France 🇫🇷 |
| mistral-small | Mistral | France 🇫🇷 |
| llama-3-70b | Meta | USA |
| deepseek-chat | DeepSeek | China ⚠ |
Always use the exact model name returned by the provider API — not an alias. The system uses the first segment before the first hyphen to identify the vendor.
// OpenAI — source_model comes directly from the response
const response = await openai.chat.completions.create({ model: "gpt-4o", messages });
await logAction("chat_completion", "success", Date.now() - t0, false, {
source_model: response.model, // ← always use response.model, not the string literal
prompt_hash: hashText(prompt),
output_hash: hashText(response.choices[0].message.content)
});
// Anthropic
const response = await anthropic.messages.create({ model: "claude-sonnet-4-6", ... });
await logAction("message", "success", Date.now() - t0, false, {
source_model: response.model, // ← same pattern
prompt_hash: hashText(prompt),
output_hash: hashText(response.content[0].text)
});
Every Enterprise agent requires an Agent Passport before it can run in production. The Passport binds the agent's identity, risk tier, allowed actions, prohibited use, and evidence configuration into a single signed artifact — sealed with SHA-256 at activation.
| Layer | What it defines |
|---|---|
| Identity | Who owns this agent technically, legally, and for compliance. Version-controlled. |
| Risk profile | Risk tier (low / medium / high), decision criticality, deployment environment. |
| Policy | Allowed tools, blocked tools, actions requiring human approval before execution. |
| Evidence | Evidence mode (standard / enhanced / forensic), I/O hashing, reasoning capture, retention period. |
| Jurisdiction | Operating jurisdictions, regulatory scope (EU AI Act, GDPR, DORA…), data residency. |
Passports are created and managed from the Enterprise dashboard. Your compliance or technical owner defines the policy, activates the passport, and the system generates an immutable SHA-256 signature. No code required — the dashboard handles the full lifecycle: create, activate, revoke.
Once active, every agent execution is automatically linked to the passport version in force at that moment. If no active passport exists, the agent cannot run.
Nothing changes in your integration code. TrustLayers resolves the passport automatically on each execution using your API key. The execution_id and evidence_chain_id are generated per run and appear in the Enterprise evidence trail.
The only field your team should add when using Enterprise is decision_context — a short human-readable description of what the agent decided in that execution. This populates the forensic evidence layer.
await logAction("loan_assessment", "success", 1240, false, {
source_model: response.model,
decision_context: "Applicant risk scored medium. Recommended standard review.",
compliance_status: "ok",
prompt_hash: hashText(prompt),
output_hash: hashText(output)
});