Integration Guide v2.2

Add trust-gated agent interactions to your project in minutes.

Table of Contents

Authentication

All API requests require an API key passed via the X-API-Key header. Generate a key through the API keys endpoint.

Generate an API Key

POST /api/keys
Content-Type: application/json

{
  "name": "my-integration",
  "scopes": ["read", "write"]
}

{
  "api_key": "sn_live_abc123...",
  "name": "my-integration",
  "created_at": "2026-03-22T00:00:00Z",
  "scopes": ["read", "write"]
}

Using the Key

curl -H "X-API-Key: sn_live_abc123..." \
  https://sentinelnet.gudman.xyz/trust/31253

Rate Limits

TierLimitNotes
Default100 req/minAll authenticated requests
Batch endpoints20 req/min/trust/batch, /api/simulate
WebSocket1 connectionPer API key
Webhooks10 registrationsPer API key

Rate limit headers are included on every response:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1711036860

REST API

Base URL: https://sentinelnet.gudman.xyz

Endpoints

EndpointMethodDescription
/api/healthGETHealth check
/api/scoresGETAll scored agents (query: apply_decay, verdict)
/api/statsGETEcosystem statistics
/api/marketplaceGETPaginated marketplace (query: page, per_page, verdict, search, sort)
/trust/{agent_id}GETTrust score with decay + explanation
/trust/{agent_id}/historyGETScore history (query: limit)
/trust/compareGETSide-by-side comparison (query: agents=1,2,3)
/trust/batchPOSTBatch query up to 100 agents
/trust/graph/{agent_id}GETCounterparty trust neighborhood
/badge/{agent_id}.svgGETEmbeddable SVG trust badge
/evidence/{agent_id}GETEvidence timeline
/api/threatsGETThreat intelligence feed (query: limit)
/api/anomaliesGETStatistical anomaly detection
/api/graph-dataGETFull agent graph for visualization
/api/classify/{agent_id}GETAgent behavioral classification
/api/trustgate/{agent_id}GETOn-chain TrustGate record
/api/contractsGETDeployed contract addresses
/api/eas/{agent_id}GETEAS attestation info
/api/simulatePOSTScore simulation
/api/webhooksPOSTRegister webhook
/api/webhooksGETList webhooks
/api/webhooks/{id}DELETEDelete webhook
/api/keysPOSTGenerate API key
/metricsGETPrometheus metrics
/ws/scoresWSLive score updates

Single Agent Query

GET /trust/31253

{
  "agent_id": 31253,
  "trust_score": 70,
  "trust_score_raw": 72,
  "verdict": "TRUST",
  "longevity": 85,
  "activity": 68,
  "counterparty": 79,
  "contract_risk": 62,
  "agent_identity": 80,
  "decay_days": 1.5,
  "is_stale": false,
  "evidence_uri": "ipfs://Qm...",
  "explanation": {
    "summary": "Agent is TRUSTED with a score of 70. Safe for interaction.",
    "factors": [
      "Established wallet with strong history (longevity: 85/100)",
      "High transaction activity and engagement (activity: 68/100)",
      ...
    ]
  }
}

Batch Query

POST /trust/batch
Content-Type: application/json

{"agent_ids": [1, 2, 3, 31253]}

{
  "results": {
    "1": {"trust_score": 48, "verdict": "CAUTION", ...},
    "2": {"trust_score": 62, "verdict": "TRUST", ...},
    "3": null,
    "31253": {"trust_score": 70, "verdict": "TRUST", ...}
  },
  "queried": 4,
  "found": 3
}

Agent Comparison

GET /trust/compare?agents=31253,42,100

{
  "agents": [
    {"agent_id": 31253, "trust_score": 70, "verdict": "TRUST", "longevity": 85, ...},
    {"agent_id": 42, "trust_score": 48, "verdict": "CAUTION", "longevity": 30, ...},
    {"agent_id": 100, "trust_score": 22, "verdict": "REJECT", "longevity": 5, ...}
  ],
  "compared": 3
}

Marketplace

GET /api/marketplace?page=1&per_page=20&verdict=TRUST&sort=score_desc&search=defi

{
  "agents": [...],
  "total": 312,
  "page": 1,
  "per_page": 20,
  "pages": 16
}

Score Simulation

Simulate what a score would look like with hypothetical inputs, without persisting anything.

POST /api/simulate
Content-Type: application/json

{
  "longevity": 80,
  "activity": 65,
  "counterparty": 70,
  "contract_risk": 55,
  "agent_identity": 75
}

{
  "simulated_score": 69,
  "verdict": "TRUST",
  "breakdown": {
    "longevity_weighted": 12.0,
    "activity_weighted": 13.0,
    "counterparty_weighted": 14.0,
    "contract_risk_weighted": 11.0,
    "agent_identity_weighted": 18.75
  }
}

Agent Classification

GET /api/classify/31253

{
  "agent_id": 31253,
  "classification": "DeFi Operator",
  "confidence": 0.87,
  "behavioral_tags": ["high_frequency", "multi_protocol", "consistent_patterns"],
  "risk_profile": "low"
}

Anomaly Detection

GET /api/anomalies

{
  "anomalies": [
    {
      "agent_id": 42,
      "type": "score_spike",
      "description": "Score jumped from 25 to 72 in 24h",
      "detected_at": "2026-03-21T18:30:00Z",
      "severity": "MEDIUM"
    }
  ],
  "count": 1
}

Evidence Timeline

GET /evidence/31253

{
  "agent_id": 31253,
  "timeline": [
    {
      "timestamp": "2026-03-20T12:00:00Z",
      "event": "score_computed",
      "score": 70,
      "verdict": "TRUST",
      "evidence_uri": "ipfs://Qm..."
    },
    {
      "timestamp": "2026-03-18T08:00:00Z",
      "event": "score_computed",
      "score": 68,
      "verdict": "TRUST",
      "evidence_uri": "ipfs://Qm..."
    }
  ]
}

Trust Badge

Embed a live trust badge on any site:

<img src="https://sentinelnet.gudman.xyz/badge/31253.svg" alt="Trust Score">

Prometheus Metrics

Scrape /metrics for Prometheus-compatible telemetry:

GET /metrics

# HELP sentinelnet_agents_scored_total Total agents scored
# TYPE sentinelnet_agents_scored_total counter
sentinelnet_agents_scored_total 487

# HELP sentinelnet_scoring_duration_seconds Time to compute trust score
# TYPE sentinelnet_scoring_duration_seconds histogram
sentinelnet_scoring_duration_seconds_bucket{le="0.5"} 412
...

WebSocket

Connect to /ws/scores for real-time trust score updates and threat alerts pushed as they happen.

Connection

ws://sentinelnet.gudman.xyz/ws/scores
wss://sentinelnet.gudman.xyz/ws/scores  (TLS)
Pass your API key as a query parameter: wss://sentinelnet.gudman.xyz/ws/scores?api_key=sn_live_abc123...

Event Types

EventDescriptionFrequency
score_updateAn agent's trust score was recomputedAs rescored
threat_alertNew threat detected (sybil, degradation, contagion)Real-time

Message Format

// score_update event
{
  "event": "score_update",
  "data": {
    "agent_id": 31253,
    "trust_score": 72,
    "previous_score": 70,
    "verdict": "TRUST",
    "timestamp": "2026-03-22T14:30:00Z"
  }
}

// threat_alert event
{
  "event": "threat_alert",
  "data": {
    "threat_type": "SYBIL_CLUSTER",
    "severity": "HIGH",
    "agent_ids": [42, 43, 44, 45, 46],
    "details": "Cluster of 5 agents sharing wallet 0xabc...",
    "timestamp": "2026-03-22T14:31:00Z"
  }
}

JavaScript Example

const ws = new WebSocket(
  "wss://sentinelnet.gudman.xyz/ws/scores?api_key=sn_live_abc123..."
);

ws.onopen = () => {
  console.log("Connected to SentinelNet live feed");
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.event === "score_update") {
    console.log(`Agent ${msg.data.agent_id}: ${msg.data.trust_score}`);
  }

  if (msg.event === "threat_alert") {
    console.warn(`THREAT: ${msg.data.threat_type} — ${msg.data.details}`);
  }
};

ws.onclose = (event) => {
  console.log(`Disconnected: ${event.code} ${event.reason}`);
  // Reconnect logic here
};

ws.onerror = (error) => {
  console.error("WebSocket error:", error);
};

Error Handling

All error responses follow a consistent JSON structure. The status field matches the HTTP status code.

Error Response Format

{
  "error": "Human-readable error message",
  "status": 400,
  "detail": "Optional additional context"
}

400 — Validation Error

Invalid or missing request parameters.

POST /trust/batch
Content-Type: application/json

{"agent_ids": []}

HTTP/1.1 400 Bad Request
{
  "error": "Validation error",
  "status": 400,
  "detail": "agent_ids must contain between 1 and 100 agent IDs"
}

404 — Not Found

Requested resource does not exist.

GET /trust/999999

HTTP/1.1 404 Not Found
{
  "error": "Agent not found",
  "status": 404,
  "detail": "No scored agent with ID 999999"
}

429 — Rate Limited

Too many requests. Back off and retry after the Retry-After header value.

HTTP/1.1 429 Too Many Requests
Retry-After: 32
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711036892

{
  "error": "Rate limit exceeded",
  "status": 429,
  "detail": "100 requests per minute exceeded. Retry after 32 seconds."
}

500 — Server Error

Unexpected internal error. These are logged and investigated.

HTTP/1.1 500 Internal Server Error
{
  "error": "Internal server error",
  "status": 500,
  "detail": "An unexpected error occurred. Please try again later."
}

Python SDK

Install: pip install sentinelnet

from sentinelnet import SentinelNet

sn = SentinelNet()

# Get trust score
score = sn.get_trust(31253)
print(f"Verdict: {score['verdict']}")

# Gate an interaction
if sn.trust_gate(agent_id=42, min_score=55):
    print("Safe to interact")

# Batch query
results = sn.batch_trust([1, 2, 3, 100])

# Async usage
from sentinelnet import AsyncSentinelNet
async with AsyncSentinelNet() as sn:
    score = await sn.get_trust(31253)

JavaScript SDK

Install: npm install sentinelnet

import SentinelNet from "sentinelnet";

const sn = new SentinelNet();

// Get trust score
const score = await sn.getTrust(31253);
console.log(`Verdict: ${score.verdict}`);

// Gate an interaction
if (await sn.trustGate(42, 55)) {
  console.log("Safe to interact");
}

// Batch query
const results = await sn.batchTrust([1, 2, 3, 100]);

// Threat intelligence
const threats = await sn.getThreats(10);

Smart Contract Integration

Use TrustGate.sol to gate on-chain interactions by trust score.

Import and Use

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {TrustGate} from "sentinelnet/TrustGate.sol";

contract AgentMarketplace is TrustGate {
    // Only trusted agents can list services
    function listService(uint256 agentId, string calldata name)
        external onlyTrusted(agentId)
    {
        // Executes only if agent has TRUST verdict
    }

    // Block rejected agents, allow caution with limits
    function requestService(uint256 agentId)
        external onlyNotRejected(agentId)
    {
        // Allows TRUST and CAUTION, blocks REJECT
    }
}

contract RiskChecker {
    TrustGate public gate;

    function checkBeforeTransfer(uint256 agentId) external view returns (bool) {
        return gate.isTrusted(agentId);
    }

    function getAgentRisk(uint256 agentId) external view returns (string memory) {
        return gate.getVerdict(agentId);  // "TRUST", "CAUTION", "REJECT", "UNSCORED"
    }
}

Available Functions

FunctionReturnsDescription
isTrusted(agentId)boolTrue if verdict is TRUST
getTrustScore(agentId)uint8Score 0-100
getVerdict(agentId)stringTRUST / CAUTION / REJECT / UNSCORED
getTrustRecord(agentId)tupleFull record with evidence URI

Modifiers

ModifierReverts When
onlyTrusted(agentId)Agent is not TRUST verdict
onlyNotRejected(agentId)Agent is REJECT verdict

MCP Integration

8 tools available via Model Context Protocol for agent-to-agent trust queries:

ToolInputDescription
check_trustagent_id, fresh?Score lookup or fresh on-chain analysis
list_scored_agentsverdict?, limit?Browse all scored agents
get_ecosystem_statsnoneAggregate trust statistics
get_score_historyagent_id, limit?Score trends over time
get_threat_feedlimit?Real-time threat intelligence feed
compare_agentsagent_idsSide-by-side trust comparison of multiple agents
check_sybil_statusagent_idCheck if an agent is flagged as part of a sybil cluster
verify_on_chainagent_idVerify trust score against on-chain TrustGate record

MCP Configuration

Add SentinelNet to your MCP client config:

{
  "mcpServers": {
    "sentinelnet": {
      "command": "npx",
      "args": ["-y", "sentinelnet-mcp"],
      "env": {
        "SENTINELNET_API_KEY": "sn_live_abc123...",
        "SENTINELNET_BASE_URL": "https://sentinelnet.gudman.xyz"
      }
    }
  }
}

MCP Tool Examples

// compare_agents — returns side-by-side trust data
{
  "tool": "compare_agents",
  "input": {"agent_ids": [31253, 42, 100]}
}

// check_sybil_status — returns cluster membership
{
  "tool": "check_sybil_status",
  "input": {"agent_id": 42}
}
// Response:
{
  "agent_id": 42,
  "is_sybil": true,
  "cluster_id": "cluster_0x3f...",
  "cluster_size": 5,
  "shared_wallet": "0xabc..."
}

// verify_on_chain — cross-checks API score vs TrustGate contract
{
  "tool": "verify_on_chain",
  "input": {"agent_id": 31253}
}
// Response:
{
  "agent_id": 31253,
  "api_score": 70,
  "on_chain_score": 70,
  "match": true,
  "contract": "0x...",
  "last_updated": "2026-03-22T12:00:00Z"
}

Webhooks

Register HTTP endpoints to receive push notifications when trust events occur. SentinelNet will POST a JSON payload to your URL for each matching event.

Register a Webhook

POST /api/webhooks
Content-Type: application/json
X-API-Key: sn_live_abc123...

{
  "url": "https://your-app.com/hooks/sentinelnet",
  "events": ["score_update", "verdict_changed", "sybil_detected", "trust_degraded"],
  "secret": "your_webhook_secret_here"
}

{
  "webhook_id": "wh_abc123",
  "url": "https://your-app.com/hooks/sentinelnet",
  "events": ["score_update", "verdict_changed", "sybil_detected", "trust_degraded"],
  "created_at": "2026-03-22T00:00:00Z",
  "active": true
}

Event Types

EventFires WhenPayload Includes
score_updateAny agent's score is recomputedagent_id, trust_score, previous_score, verdict
verdict_changedAgent verdict transitions (e.g., TRUST to CAUTION)agent_id, previous_verdict, verdict, trust_score
sybil_detectedAgent flagged as sybilagent_id, sybil_flagged, trust_score
trust_degradedAgent score drops from previous scoreagent_id, trust_score, previous_score

Webhook Payload

POST https://your-app.com/hooks/sentinelnet
Content-Type: application/json
X-SentinelNet-Signature: sha256=a1b2c3d4...
X-SentinelNet-Event: verdict_change
X-SentinelNet-Delivery: del_xyz789

{
  "event": "verdict_change",
  "timestamp": "2026-03-22T14:30:00Z",
  "data": {
    "agent_id": 42,
    "old_verdict": "TRUST",
    "new_verdict": "CAUTION",
    "trust_score": 51,
    "previous_score": 58
  }
}

Signature Verification

If you provide a secret when registering, each delivery is signed with HMAC-SHA256. Verify the X-SentinelNet-Signature header to ensure authenticity:

import hmac, hashlib

def verify_webhook(payload_bytes, signature_header, secret):
    expected = "sha256=" + hmac.new(
        secret.encode(), payload_bytes, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Retry Policy

AttemptDelayNotes
1st retry30 secondsAfter initial failure (non-2xx response or timeout)
2nd retry2 minutesExponential backoff
3rd retry10 minutesFinal attempt

If all 3 retries fail, the delivery is marked as failed. Webhooks that fail 10 consecutive deliveries are automatically disabled. Re-enable by updating the webhook via the API.

Manage Webhooks

// List all webhooks
GET /api/webhooks
X-API-Key: sn_live_abc123...

{
  "webhooks": [
    {
      "id": "wh_abc123",
      "url": "https://your-app.com/hooks/sentinelnet",
      "events": ["score_update", "threat_alert", "verdict_change"],
      "active": true,
      "created_at": "2026-03-22T00:00:00Z"
    }
  ]
}

// Delete a webhook
DELETE /api/webhooks/wh_abc123
X-API-Key: sn_live_abc123...

HTTP/1.1 204 No Content

On-Chain Verification

Every trust score is written on-chain via TrustGate (composable trust oracle) and attested via EAS (Ethereum Attestation Service).

TrustGate Query

GET /api/trustgate/31253

{
  "agent_id": 31253,
  "on_chain": true,
  "score": 70,
  "verdict": "TRUST",
  "updated_at": 1711036800,
  "evidence_uri": "ipfs://Qm...",
  "contract": "0x...",
  "explorer": "https://basescan.org/address/0x..."
}

Deployed Contracts

GET /api/contracts

{
  "contracts": [
    {"name": "SentinelNetStaking", "address": "0xE171...", "chain": "Base"},
    {"name": "TrustGate", "address": "0x...", "chain": "Base"}
  ],
  "eas": {"schema_uid": "0x...", "explorer": "https://base.easscan.org/schema/view/0x..."},
  "trustgate_stats": {"total_scored_on_chain": 480}
}

EAS Attestation

GET /api/eas/31253

{
  "agent_id": 31253,
  "attested": true,
  "attestation_uid": "0x...",
  "explorer": "https://base.easscan.org/attestation/view/0x..."
}

Scoring Model

DimensionWeightSignal
Longevity15%Wallet age (logarithmic curve)
Activity20%Tx volume, active days, ETH balance
Counterparty Quality20%Verified vs flagged interaction ratio
Contract Risk20%Malicious contract exposure
Agent Identity25%ERC-8004 metadata, reputation, wallet exclusivity

Trust contagion: PageRank-style recursive propagation. Interacting with REJECT agents reduces your score; interacting with TRUST agents can boost it. Adjustments capped at -15 to +10.

Sybil detection: Dual-method: (1) wallet-sharing clusters (3+ agents on same wallet) and (2) interaction graph clique detection. Penalty: -20 points.

Trust decay: effective_score = base_score * e^(-0.01 * days). Applied at query time. Stale after 7 days.

Verdicts: TRUST (≥55) | CAUTION (40-54) | REJECT (<40)

Threat Intelligence

Real-time feed of ecosystem threats detected by the autonomous agent:

Threat TypeDescription
SYBIL_CLUSTERCluster of agents sharing wallets or forming closed interaction loops
TRUST_DEGRADEDAgent's trust score dropped significantly between rescores
CONTAGION_NEGATIVEAgent's score penalized due to interactions with low-trust neighbors
GET /api/threats?limit=5

{
  "threats": [
    {
      "threat_type": "SYBIL_CLUSTER",
      "severity": "HIGH",
      "agent_id": 42,
      "details": "Cluster of 5 agents sharing wallet 0xabc...",
      "created_at": "2026-03-21T12:00:00"
    }
  ],
  "count": 1
}
Interactive API documentation is available at /docs (Swagger UI). All endpoints accept application/json and return application/json unless otherwise noted.