Skip to content
AgentTrust

API reference

Use AgentTrust from another AI agent

Everything below is also available as a plain-text file at /llms.txt — built for pasting into an LLM's context or reading programmatically. Base URL for every example on this page: https://getagenttrust.com

MCP (no key)
https://getagenttrust.com/api/mcp/publicPublic connector: check_agent_trust and assess_agent
MCP server
https://getagenttrust.com/api/mcpStreamable HTTP
Trust check (MCP)
check_agent_trust({ endpointUrl })No API key or account
Use-or-avoid (MCP)
assess_agent({ endpointUrl })No API key or account
Trust check (REST)
GET /api/v1/agents?endpoint_url=API key required
SDK (TypeScript)
npm install @getagenttrust/sdkAnonymous trust checks, typed results
Authentication
Authorization: Bearer <API_KEY>REST and keyed MCP tools
On this page

Quick Start

Check an endpoint in under a minute — no account or API key. The check is read-only, and AgentTrust never contacts the endpoint you check. Each option below checks AgentTrust's own monitored test agent, https://agenttrust-umber.vercel.app/api/test-agent; swap in the URL you're about to call.

1. MCP — connect your agent

Add the public MCP connector https://getagenttrust.com/api/mcp/public (Streamable HTTP, no authentication). It exposes two read-only tools, check_agent_trust and assess_agent. In Claude Code:

claude mcp add --transport http agenttrust https://getagenttrust.com/api/mcp/public

Run claude mcp list to confirm it's connected. Claude Desktop, Cursor and other clients: Connect an MCP client. To call the tool without a client:

curl -s https://getagenttrust.com/api/mcp/public \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_agent_trust","arguments":{"endpointUrl":"https://agenttrust-umber.vercel.app/api/test-agent"}}}'

The response is one server-sent event; the trust result is in result.structuredContent (see MCP).

2. TypeScript SDK

npm install @getagenttrust/sdk
import { checkAgentTrust } from "@getagenttrust/sdk";

// AgentTrust's own test agent: a real, monitored endpoint you can check.
const result = await checkAgentTrust("https://agenttrust-umber.vercel.app/api/test-agent");

if (result.matched) {
  console.log(result.status, result.reliabilityScore, result.trustDecision);
  // e.g. "healthy" 100 { recommended: true, confidence: "high", reasons: [] }
} else {
  // AgentTrust has no data for this endpoint (yet). An unmatched result never
  // carries a score; result.observation may say it was queued for a lookup.
  console.log("Unknown endpoint", result.observation?.status);
}

Policies, errors and options: SDK (TypeScript). New to AgentTrust? Start with First 5 minutes.

3. In the browser

Check the test agent, or paste any endpoint URL into Check an agent.

Registering your own agent, or using the REST API?

These need an account: Sign up → Dashboard → API keys → Create key → Dashboard → Agents → Register agent → Activate agent → call ?endpoint_url= and read trustDecision from the response. Skip ownership verification for now — it's optional (see Step 5).

First 5 minutes

No account or API key. Node.js 18 or later.

1. Install. assessAgent needs SDK 0.2.0 or later.

npm install @getagenttrust/sdk@^0.2.0

2. Check an endpoint. This checks AgentTrust's own monitored test agent, so it returns a real result. The check is read-only, and AgentTrust never contacts the endpoint you ask about.

import { assessAgent } from "@getagenttrust/sdk";

// AgentTrust's own monitored test agent. Swap in the URL your agent is about to call.
const assessment = await assessAgent("https://agenttrust-umber.vercel.app/api/test-agent");

console.log(assessment.decision, assessment.confidence, assessment.reasonCodes);
// e.g. allow_with_caution high ["OWNERSHIP_VERIFIED", "REACHABLE_AT_LAST_CHECK", …]

if (assessment.decision === "allow_with_caution") {
  // Reachable and not failing in AgentTrust's observations. Not proof that the
  // agent behaves safely: keep your own safeguards when you call it.
} else {
  // "avoid", or "insufficient_evidence" — also the answer for a URL AgentTrust
  // doesn't monitor (matched: false, reasonCodes includes "UNKNOWN_ENDPOINT").
  console.log("Not calling it:", assessment.limitations);
}

3. Read the answer. confidence, reasonCodes and limitations say why.

  • allow_with_caution — AgentTrust's observations show the endpoint reachable and not failing: a current historical reliability score, or at least two successful observations at least 10 minutes apart. What to do: Call it, with your own safeguards. It isn't proof that the agent behaves safely.
  • avoid — AgentTrust's observations show it failing — for example two or more consecutive failures, or a current reliability score below 50. What to do: Don't call it.
  • insufficient_evidence — Not enough evidence either way: an endpoint AgentTrust doesn't monitor, too few or too old observations, or a single failure that may be temporary. What to do: Don't treat it as approval — handle it as an unknown endpoint.

Which call should I use?

  • assessAgent(url) — Your agent needs one decision to act on before it calls an endpoint. You get: decision, confidence, reasonCodes and limitations, with the evidence behind them.
  • checkAgentTrust(url) — You want the evidence itself — status, reliabilityScore, verified and trustDecision — to apply your own rules. You get: { matched: true, … }, or { matched: false } for an endpoint AgentTrust doesn't monitor.
  • assertTrusted(url, policy) — You want a gate: go ahead only if the endpoint meets your policy. You get: The checkAgentTrust result, or a thrown NotTrustedError.

All three are anonymous and read-only, and never contact the endpoint (over MCP: assess_agent and check_agent_trust). They report what AgentTrust has observed; they don't certify an endpoint's security.

Unknown endpoints are an answer, not an error

AgentTrust only has evidence for endpoints it monitors, so your first check of a real URL may come back unknown. That is an answer, not an API failure — the call succeeds:

  • assessAgent returns matched: false, decision: "insufficient_evidence", confidence: "none", and reasonCodes including "UNKNOWN_ENDPOINT".
  • checkAgentTrust returns { matched: false }, sometimes with an observation status when AgentTrust has queued the URL for a lookup in the official MCP Registry.
  • assertTrusted throws NotTrustedError ("AgentTrust has no data for this endpoint") unless you pass allowUnknown: true.

Real failures — RATE_LIMITED, TIMEOUT, NETWORK_ERROR and the rest — throw an AgentTrustError instead.

Handle an unknown endpoint as not trusted: don't map insufficient_evidence to "allow", keep allowUnknown: false (the default) unless you have chosen otherwise on purpose, and ask a human or run your own checks before calling an endpoint nobody has observed.

Next steps

  • Gate a real connection: examples/check-before-connect.ts puts assertTrusted in front of an MCP client connection.
  • Tune the gate: minConfidence, requireVerified and minReliabilityScore in the assertTrusted policy — see SDK (TypeScript).
  • Running an agent yourself? Register it so other agents can check it — that needs an account and an API key: Getting started.

MCP

Connect an MCP client

AgentTrust has two MCP endpoints. Most agents need only the first:

  • Public connector — no key (recommended): https://getagenttrust.com/api/mcp/public. No authentication. Two read-only tools, check_agent_trust and assess_agent. Use it to let an agent or client check endpoints before calling them.
  • Full MCP server — API key: https://getagenttrust.com/api/mcp. Every tool except check_agent_trust and assess_agent needs Authorization: Bearer <API_KEY>. Adds list_agents, get_agent, get_agent_health and send_heartbeat, for reading full agent records and sending your own agents' heartbeats.

Both use Streamable HTTP. To add the public connector:

Claude Code (Claude Code MCP docs):

claude mcp add --transport http agenttrust https://getagenttrust.com/api/mcp/public

Add --scope user to make it available in every project. Run claude mcp list to confirm it's connected.

Claude Desktop and claude.ai (Claude connector guide): AgentTrust is listed in Claude's connector directory — add it from its directory listing. Or add it as a custom connector: Customize → Connectors → + Add → Add custom connector, name it AgentTrust, enter https://getagenttrust.com/api/mcp/public, then Continue → Add. No authentication is needed. On Team and Enterprise plans, an owner adds it under Organization settings → Connectors. To use it in a chat, open + → Connectors and turn AgentTrust on. Free plans can add one custom connector. Claude Desktop doesn't need claude_desktop_config.json for this — that file is for local servers.

Cursor (Cursor MCP docs): add this to ~/.cursor/mcp.json (every project) or .cursor/mcp.json (one project):

{
  "mcpServers": {
    "agenttrust": {
      "url": "https://getagenttrust.com/api/mcp/public"
    }
  }
}

Any HTTP client: see the curl example in the Quick Start.

Full MCP server (API key) — only if you need the keyed tools. Replace <API_KEY> with a key from Dashboard → API keys, and keep it out of shared files: in Claude Code keep the default local scope (--scope project writes it to a shared .mcp.json), and in Cursor use ~/.cursor/mcp.json, not a project file you commit.

claude mcp add --transport http agenttrust-account https://getagenttrust.com/api/mcp --header "Authorization: Bearer <API_KEY>"
{
  "mcpServers": {
    "agenttrust-account": {
      "url": "https://getagenttrust.com/api/mcp",
      "headers": {
        "Authorization": "Bearer <API_KEY>"
      }
    }
  }
}

Endpoints and tools

Endpoint: https://getagenttrust.com/api/mcp (GET and POST, Streamable HTTP transport). Auth: the same Bearer token as REST, in the Authorization header — except check_agent_trust and assess_agent, below, which need none. tools/list works without a key; calling any other tool requires one (the same 401 as REST on a missing/bad key).

check_agent_trust({endpointUrl})

Pre-invocation trust check for an unknown AI agent or MCP server endpoint. No API key or account required. Read-only, and never contacts endpointUrl itself — it only reads AgentTrust's own already-observed data. Returns { matched: false } for an unregistered URL, or { matched: true, slug, name, status, verified, reliabilityScore, reliabilityScoreStatus, trustDecision } for a known public+active agent. Anonymous calls are rate-limited per caller IP; over the limit the tool returns an error result with the code RATE_LIMITED and retryAfterSeconds (see Rate limits). See Check an AI Agent Before You Invoke It for a plain-language walkthrough of this check.

assess_agent({endpointUrl})

A use-or-avoid decision for an agent about to call endpointUrl. No API key or account required. Read-only, and never contacts endpointUrl: it is built only from AgentTrust's stored observations. Returns decision (allow_with_caution, avoid or insufficient_evidence), confidence, machine-readable reasonCodes, reachability (the latest stored observation and its age, not a live check), initialRisk, historical (the reliability score and trustDecision, unchanged), limitations and freshness. allow_with_caution needs a fresh historical score or at least two successful observations 10+ minutes apart — one success is never enough. avoid means two or more consecutive failures, a down agent still failing, a fresh score below 50, or a TLS failure or an endpoint resolving into a private network; a single failure that may be temporary is insufficient_evidence. Reachability is not safety. Same anonymous per-IP rate limit as check_agent_trust; also over REST as GET /api/v1/assessments?endpoint_url= (API key).

Public connector endpoint: https://getagenttrust.com/api/mcp/public (Streamable HTTP, no authentication). It exposes only check_agent_trust and assess_agent, both annotated read-only, and runs the same checks with the same rate limit. Use it to add AgentTrust to an MCP client or connector directory that connects without credentials, such as a custom connector in Claude.

Tools requiring an API key (each backed by the exact same handler as its REST equivalent):

  • list_agents({limit?, cursor?, endpointUrl?}) — endpointUrl triggers the same trust-check enrichment as the REST ?endpoint_url= filter, plus the full public agent record (agent card, capabilities, etc.) that check_agent_trust deliberately omits.
  • get_agent({slug}) — same enriched shape as GET /agents/{slug}.
  • get_agent_health({slug}) — same as GET /agents/{slug}/health.
  • send_heartbeat({slug}) — owner-only, same as POST /agents/{slug}/heartbeat.

Example — list_agents with endpointUrl:

Request:  { "endpointUrl": "https://api.example-acme.com/v1/invoke" }
Response: structuredContent.agents[0] has the exact same fields as
          the REST example above.

SDK (TypeScript)

@getagenttrust/sdk is the official TypeScript SDK for AgentTrust's two anonymous checks: checkAgentTrust and assertTrusted call check_agent_trust, and assessAgent calls assess_agent, on https://getagenttrust.com/api/mcp/public, with typed results and errors. No API key or account. It runs on Node.js 18 or later and is an ES module; require() works on Node.js 20.19+ and 22.12+. Use version 0.2.0 or later — the current release, and the first with assessAgent; 0.1.0 and 0.1.1 are deprecated.

npm install @getagenttrust/sdk

Check an endpoint. The example uses https://agenttrust-umber.vercel.app/api/test-agent, AgentTrust's own monitored test agent, so it returns a real result. AgentTrust never contacts the endpoint you check.

import { checkAgentTrust } from "@getagenttrust/sdk";

// AgentTrust's own test agent: a real, monitored endpoint you can check.
const result = await checkAgentTrust("https://agenttrust-umber.vercel.app/api/test-agent");

if (result.matched) {
  console.log(result.status, result.reliabilityScore, result.trustDecision);
  // e.g. "healthy" 100 { recommended: true, confidence: "high", reasons: [] }
} else {
  // AgentTrust has no data for this endpoint (yet). An unmatched result never
  // carries a score; result.observation may say it was queued for a lookup.
  console.log("Unknown endpoint", result.observation?.status);
}

Only connect if it's trusted: assertTrusted throws NotTrustedError unless the endpoint meets your policy, and fails closed — an endpoint AgentTrust has no data for is rejected unless you set allowUnknown. For a result you already have, evaluatePolicy(result, policy) returns the same failures as a string array (empty means it passes).

import { assertTrusted, NotTrustedError } from "@getagenttrust/sdk";

const endpointUrl = "https://agenttrust-umber.vercel.app/api/test-agent";

try {
  await assertTrusted(endpointUrl, {
    requireRecommended: true, // default
    minConfidence: "medium",
    requireVerified: false, // default
    minReliabilityScore: 80,
    allowUnknown: false, // default
  });
  // Trusted: connect with your MCP client here.
} catch (error) {
  if (error instanceof NotTrustedError) {
    console.log("Not connecting:", error.failures);
  } else {
    throw error; // couldn't get a decision: treat the endpoint as untrusted
  }
}

Policy options. The boolean options must be true or false: any other value, or any other invalid policy, throws TypeError before a request is made.

  • requireRecommended (default true) — Require AgentTrust's own trustDecision.recommended.
  • minConfidence — Minimum trustDecision.confidence: "low", "medium" or "high".
  • requireVerified (default false) — Require proven endpoint ownership.
  • minReliabilityScore — Minimum reliability score (0–100); a missing or stale score fails it.
  • allowUnknown (default false) — Accept an endpoint AgentTrust has no data for.

Results are { matched: true, slug, name, status, verified, reliabilityScore, reliabilityScoreStatus, trustDecision } — the same fields as check_agent_trust above, explained in Interpreting trustDecision — or { matched: false, observation? }, which never carries a score.

Use-or-avoid decisions: assessAgent(endpointUrl) returns the same result as the assess_agent tool above — decision, confidence, reasonCodes, reachability, initialRisk, historical, limitations and freshness. Requires @getagenttrust/sdk 0.2.0 or later.

Errors. Invalid client options, per-call options and policies throw a plain TypeError. Everything else is an AgentTrustError with a code, and the SDK never retries on its own:

  • INVALID_URL — not an absolute http(s) URL, or it contains a username or password; no request is made.
  • RATE_LIMITED — the anonymous limit was reached; see retryAfterSeconds.
  • TIMEOUT — no answer within timeoutMs.
  • ABORTED — your AbortSignal aborted the check.
  • NETWORK_ERROR — AgentTrust couldn't be reached.
  • HTTP_ERROR — a non-2xx response; see status.
  • PROTOCOL_ERROR — the response wasn't a valid check_agent_trust or assess_agent result.
  • TOOL_ERROR — the tool rejected the input.
  • NOT_TRUSTED — NotTrustedError from assertTrusted; see failures and result.

Full reference, including createAgentTrustClient options and per-call timeouts: the SDK README. A complete trust gate in front of an MCP connection: examples/check-before-connect.ts.

Getting started

  1. 01

    Create an account

    Sign up at /signup with email + password; confirm your email before continuing. There's no programmatic/self-service account-creation API yet — this one step is manual.

  2. 02

    Create an API key

    Dashboard → API keys → Create key. The raw key is shown exactly once — copy it immediately. Use it as Authorization: Bearer YOUR_API_KEY on every request below (see Authentication further down for error details).

  3. 03

    Register an agent

    Dashboard → Agents → Register agent. Required: name, endpointUrl (must be https://). Optional: description, version, authType (none / api_key / bearer — how AgentTrust's monitor authenticates to your endpoint, with a credential stored encrypted and never exposed back), and capabilities (comma-separated tags). The agent starts as a private draft — not monitored, not publicly visible yet.

  4. 04

    Configure the agent endpoint

    This is just the endpointUrl (and authType/credential, if your endpoint needs one) from Step 3 — it's the exact URL other callers will look you up by. It must be reachable over HTTPS and must not point at a private/internal/localhost address; registration rejects those.

  5. 05

    Endpoint ownership verification (optional)

    On the agent's dashboard page: Start verification → publish a file at the given URL containing the given token → Check now. This proves you control the endpoint, not just that something answers there. Checks are throttled to one per 60 seconds per agent.

    Verification is entirely optional and never gates recommended — an unverified agent with strong health/reliability history can still be recommended: true. Verification only raises confidence, and its absence always appears as one entry in reasons — it's a signal, not a hard requirement.
  6. 06

    Let monitoring collect health/reliability data

    Click Activate agent on its dashboard page — this makes it public and puts it on the monitoring schedule. Pull-mode (default) checks run once per day via cron, and reliabilityScore stays null (shown as "Not enough data yet") until at least 5 checks exist, which can take several days in pull mode. Only AgentTrust's own checks count toward a pull-mode agent's status and score — heartbeats don't.

  7. 07

    Discover an agent by endpoint URL

    GET /api/v1/agents?endpoint_url=<url> — exact match against the endpointUrl you registered (see URL normalization for what's normalized). An unregistered URL returns 200 with an empty data array, never an error.

  8. 08

    Request/read the trust decision

    The Step 7 response already includes trustDecision — there's no separate call. See Interpreting trustDecision below for exactly what recommended/confidence/reasons mean.

Your first call — also the trust lookup itself:

curl -s "https://getagenttrust.com/api/v1/agents?endpoint_url=YOUR_AGENT_ENDPOINT" \
  -H "Authorization: Bearer YOUR_API_KEY"

# YOUR_AGENT_ENDPOINT must be URL-encoded, e.g.
# https%3A%2F%2Fyour-agent.example.com%2Fv1%2Finvoke

Response shape (fictional values):

{
  "data": [
    {
      "id": "3fa1c2b0-1234-4a5b-8c9d-abcdef123456",
      "slug": "acme-support-bot",
      "name": "Acme Support Bot",
      "description": "Handles tier-1 customer support requests.",
      "version": "1.2.0",
      "capabilities": ["chat", "ticket-triage"],
      "status": "healthy",
      "createdAt": "2026-01-15T10:00:00.000Z",
      "agentCard": {
        "schemaVersion": "1.0",
        "name": "Acme Support Bot",
        "description": "Handles tier-1 customer support requests.",
        "capabilities": ["chat", "ticket-triage"],
        "authentication": { "type": "none" },
        "interfaces": { "modalities": ["text"], "interactionType": "request-response" },
        "documentationUrl": null
      },
      "source": "owner_registered",
      "verified": false,
      "ownershipVerifiedAt": null,
      "reliabilityScore": 97,
      "reliabilityScoreStatus": "fresh",
      "reliabilityScoreComputedAt": "2026-09-14T00:44:16.440Z",
      "lastCheckedAt": "2026-09-14T00:44:13.152Z",
      "latencyMs": 142,
      "httpStatus": 200,
      "trustDecision": {
        "recommended": true,
        "confidence": "low",
        "reasons": ["Endpoint ownership has not been verified."]
      }
    }
  ],
  "pagination": { "nextCursor": null }
}

The workflow

The thing AgentTrust is actually for: another AI agent has a URL it's about to call, and wants to know whether it should.

  1. Discover — this page, /llms.txt, or AgentTrust's own A2A Agent Card at /.well-known/agent-card.json (for A2A-capable agents/clients).
  2. Authenticate — for REST and the keyed MCP tools, a human creates an API key once, via the dashboard (see below), and it's sent as Authorization: Bearer <API_KEY>. The anonymous MCP tools check_agent_trust and assess_agent need no key.
  3. Look up the agent by the URL you're about to call: GET /api/v1/agents?endpoint_url=<url> (API key), or with no key, check_agent_trust over MCP at /api/mcp/public or the SDK.
  4. Receive trust information: reliability score, status, verification state, and the latest health check.
  5. Interpret trustDecision: recommended, confidence, and reasons.
  6. Make your own policy decision — e.g. only proceed when recommended === true, or apply a stricter rule yourself using confidence/verified directly.

Authentication

Every /api/v1/* request requires Authorization: Bearer <API_KEY>. Getting a key is a one-time human step — sign up, then Dashboard → API keys → Create key. There is currently no unauthenticated or self-service account-creation API; a human owns the account.

The raw key is shown exactly once, at the moment you create it — copy it immediately. AgentTrust stores only a hash and can never show it to you again; if you lose it, revoke it and create a new one.

Revoked keys stay visible in your dashboard's key list — kept for audit/usage history — but can never authenticate again once revoked. That's intentional, not a bug.

Missing key:

401
{"error":{"code":"UNAUTHENTICATED","message":"Missing API key. Provide one as: Authorization: Bearer <API_KEY>"}}

Invalid, expired, or revoked key:

401
{"error":{"code":"UNAUTHENTICATED","message":"Invalid, expired, or revoked API key."}}

Rate limits

Anonymous (no API key): check_agent_trust and assess_agent share one limit, counted in fixed 60-second windows: 10 checks per caller IP address, and 300 across all anonymous callers combined. It applies to both tools on /api/mcp/public and on /api/mcp (even when an API key is sent), and to the browser checker at /check-agent-trust.

Over the limit, the HTTP response is still 200: the tool returns an error result (isError: true) whose structuredContent.error has the code RATE_LIMITED and retryAfterSeconds. The SDK reports it as an AgentTrustError with the code RATE_LIMITED and never retries on its own. A call whose IP address can't be determined is refused the same way.

With an API key (REST /api/v1/*): 100 requests / 60 seconds, per API key, fixed window. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.

Over the API-key limit:

429
Retry-After: 37
{"error":{"code":"RATE_LIMITED","message":"Rate limit exceeded. Try again later."}}

Trust-check lookup — GET /api/v1/agents?endpoint_url=

The entry point for the workflow above. Exact match only (see Normalization below) against an agent's registered endpoint URL. Returns the same envelope as the plain listing, but each matched agent is additionally enriched with reliabilityScore, reliabilityScoreStatus, reliabilityScoreComputedAt, lastCheckedAt, latencyMs, httpStatus, and trustDecision. An unregistered URL returns 200 with an empty data array — never an error.

Example request:

GET /api/v1/agents?endpoint_url=https%3A%2F%2Fapi.example-acme.com%2Fv1%2Finvoke
Authorization: Bearer at_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Example response (fictional values):

{
  "data": [
    {
      "id": "3fa1c2b0-1234-4a5b-8c9d-abcdef123456",
      "slug": "acme-support-bot",
      "name": "Acme Support Bot",
      "description": "Handles tier-1 customer support requests.",
      "version": "1.2.0",
      "capabilities": ["chat", "ticket-triage"],
      "status": "healthy",
      "createdAt": "2026-01-15T10:00:00.000Z",
      "agentCard": {
        "schemaVersion": "1.0",
        "name": "Acme Support Bot",
        "description": "Handles tier-1 customer support requests.",
        "capabilities": ["chat", "ticket-triage"],
        "authentication": { "type": "none" },
        "interfaces": { "modalities": ["text"], "interactionType": "request-response" },
        "documentationUrl": null
      },
      "source": "owner_registered",
      "verified": false,
      "ownershipVerifiedAt": null,
      "reliabilityScore": 97,
      "reliabilityScoreStatus": "fresh",
      "reliabilityScoreComputedAt": "2026-09-14T00:44:16.440Z",
      "lastCheckedAt": "2026-09-14T00:44:13.152Z",
      "latencyMs": 142,
      "httpStatus": 200,
      "trustDecision": {
        "recommended": true,
        "confidence": "low",
        "reasons": ["Endpoint ownership has not been verified."]
      }
    }
  ],
  "pagination": { "nextCursor": null }
}

This is a realistic pattern, not a corner case: a strong, healthy, unverified agent is still recommended: true — see "Interpreting trustDecision" below for why.

source ("owner_registered" | "externally_observed"): how the agent entered AgentTrust. owner_registered means a human registered and activated it. externally_observed means AgentTrust discovered it from a public agent registry on nobody's behalf — it is always unclaimed and unverified, exactly like any other unverified agent; source is provenance, not a trust signal by itself.

URL normalization

Exact match only — never fuzzy or partial. Both the URL you pass and each registered URL go through standard URL parsing, plus one extra rule, before comparing:

  1. A trailing slash on a non-root path (.../invoke/ matches .../invoke).
  2. Scheme/host casing (HTTPS://Example.com matches https://example.com), and the other effects of standard URL parsing — for example, a default port is dropped (https://example.com:443/a matches https://example.com/a).

Nothing else is normalized — path casing, query strings, fragments and non-default ports are compared exactly as given.

Interpreting trustDecision

Derived entirely from an agent's existing status, reliability score, and verification state — never a second, independent score.

recommended (boolean): true only when status === "healthy" AND reliabilityScore !== null AND reliabilityScore >= 50 AND reliabilityScoreStatus === "fresh".

reliabilityScoreStatus ("none" | "fresh" | "stale"): none — no score computed yet; fresh — the latest score was produced by the agent's most recent health check (a score needs at least 5 checks in the 7 days before it) and is at most 50 hours old; stale — a score exists, but it's older than that, or a newer health check couldn't produce a replacement. A stale reliabilityScore is the last computed value, kept for reference — not current evidence, and never makes an agent recommended.

confidence ("high" | "medium" | "low" | "insufficient_data"):

  • insufficient_data if reliabilityScore is null (not enough monitoring history yet) or reliabilityScoreStatus is "stale".
  • otherwise low if the agent is unverified, regardless of score.
  • otherwise high if score ≥ 90, medium if score ≥ 50, low below that.

reasons (string[]): a plain-language explanation for every factor that counted against the agent — empty only when nothing did.

Verification is a trust signal, not a hard requirement.

Ownership verification is optional and does not gate recommended — an unverified agent with strong health/reliability history can still be recommended: true. Verification instead affects confidence, and its absence is always spelled out explicitly in reasons, so a caller wanting a stricter policy (e.g. "only trust verified agents") can enforce that themselves using the raw verified field — AgentTrust doesn't impose that policy for everyone.

Other endpoints

GET /api/v1/agents
Plain listing of public, active agents (no endpoint_url). Query params: limit (1-100, default 20), cursor (opaque, from a previous response's pagination.nextCursor). No trust-decision enrichment — only the base identity/verification fields.
GET /api/v1/agents/{slug}
Same enrichment as the endpoint_url lookup, for one agent by its AgentTrust slug. 404 if the slug doesn't exist or isn't public+active.
GET /api/v1/agents/{slug}/health
{agentId, slug, status, lastCheckedAt, latencyMs, httpStatus, checkStatus, reliabilityScore, reliabilityScoreStatus, reliabilityScoreComputedAt}
POST /api/v1/agents/{slug}/heartbeat
Owner-only (the key must belong to that agent's own account); records a push-mode liveness signal. Reads no request body. For a pull-mode agent (the default) it only updates lastHeartbeatAt; status and score come from AgentTrust's own checks. {slug, status, lastHeartbeatAt}
GET /api/v1/assessments?endpoint_url=<url>
The assess_agent result as { data: {...} }. Read-only: built from stored observations, it never contacts the URL. An unknown URL returns the decision insufficient_evidence, never an error.

Common errors

  • 401 UNAUTHENTICATED — missing, invalid, expired, or revoked key.
  • 404 NOT_FOUND — unknown slug on GET /agents/{slug}. An unknown endpoint_url on the list endpoint is not an error — it's 200 with an empty data array.
  • 400 VALIDATION_ERROR — e.g. limit=0 or a malformed cursor; the body includes a details object with per-field messages.
  • 429 RATE_LIMITED — see Rate limits above.

Not yet built

The official SDK covers only the two anonymous checks, check_agent_trust and assess_agent (see SDK); for everything else — registering agents, and the REST API and keyed MCP tools — use those directly. No programmatic/self-service account creation — a human creates the account and first API key. No batch/multi-URL lookup — call ?endpoint_url= once per URL.

Support

For product support, privacy questions, or to report a security issue, email dlrhkdaud5592@naver.com. How AgentTrust handles data is described in the Privacy Policy.