Quickstart

Add TrustLayer logging to your AI agent in three steps. Every action your agent takes should fire a log event to our API.

1. Get your API key

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...

2. Log your first event

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"
  }'

3. View your score

After 10+ events, your Trust Score becomes available in your dashboard and on your public agent profile.

Authentication

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.

API Reference

Log an action taken by your agent. Call this after every significant action your agent takes.

Request body

Parameter Type Required Description
actionstringrequiredAction type (e.g. send_email, create_record, url_analyzed)
resultstringrequiredsuccess, error, or timeout
duration_msintegeroptionalHow long the action took in milliseconds
sensitive_databooleanoptionalDid this action touch sensitive or personal data?
error_codestringoptionalError code if result is error
metadataobjectoptionalAny additional structured context as a JSON object
Governance Fields — EU AI Act
risk_scoreintegeroptionalRisk level 0–100. Triggers alert if ≥ 80. Used for Risk Overview chart.
severitystringoptionalOne of: low, medium, high, critical. Triggers email alert if high or critical.
compliance_statusstringoptionalOne of: ok, warning, violation, pending. Triggers alert if violation.
policy_triggeredstringoptionalName of the policy or rule that fired (e.g. medical_risk, transparency_violation)
decision_contextstringoptionalHuman-readable description of the decision or context for this event
source_modelstringrecommendedAI model that generated this output (e.g. gpt-4o, claude-sonnet-4-6, mistral-large). Required for Third Party Monitoring in Enterprise dashboard.
prompt_hashstringoptionalSHA-256 hash of the input prompt for traceability (max 64 chars)
output_hashstringoptionalSHA-256 hash of the model output for traceability (max 64 chars)
drift_detectedbooleanoptionalSet to true if model behavior change is detected. Triggers alert.
anomaly_scoreintegeroptionalAnomaly level 0–100. Triggers alert if ≥ 75.
human_overridebooleanoptionalSet to true when a human manually intervenes or overrides the AI decision (Art. 14)
geo_originstringoptionalISO country code of the request origin (e.g. ES, DE, FR)

Response

{
  "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.

Error responses

Code Error Description
401Missing API keyNo Authorization header provided
403Invalid or inactive API keyKey doesn't exist or agent not active yet
400action is requiredMissing required action field
405Method not allowedOnly POST is accepted

Python

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"
)

Node.js

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"
});

Vendor Tracking — source_model

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.

Recommended values

source_model valueProviderJurisdiction
gpt-4oOpenAIUSA
gpt-4-turboOpenAIUSA
claude-sonnet-4-6AnthropicUSA
claude-opus-4-6AnthropicUSA
gemini-1.5-proGoogleUSA
mistral-largeMistralFrance 🇫🇷
mistral-smallMistralFrance 🇫🇷
llama-3-70bMetaUSA
deepseek-chatDeepSeekChina ⚠

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.

Node.js — auto-capture from response

// 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)
});

Agent Passport — Enterprise

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.

What it covers

LayerWhat it defines
IdentityWho owns this agent technically, legally, and for compliance. Version-controlled.
Risk profileRisk tier (low / medium / high), decision criticality, deployment environment.
PolicyAllowed tools, blocked tools, actions requiring human approval before execution.
EvidenceEvidence mode (standard / enhanced / forensic), I/O hashing, reasoning capture, retention period.
JurisdictionOperating jurisdictions, regulatory scope (EU AI Act, GDPR, DORA…), data residency.

How to create one

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.

What your developers need to know

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)
});