Add trust-gated agent interactions to your project in minutes.
All API requests require an API key passed via the X-API-Key header. Generate a key through the API keys endpoint.
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"]
}
curl -H "X-API-Key: sn_live_abc123..." \ https://sentinelnet.gudman.xyz/trust/31253
| Tier | Limit | Notes |
|---|---|---|
| Default | 100 req/min | All authenticated requests |
| Batch endpoints | 20 req/min | /trust/batch, /api/simulate |
| WebSocket | 1 connection | Per API key |
| Webhooks | 10 registrations | Per API key |
Rate limit headers are included on every response:
X-RateLimit-Limit: 100 X-RateLimit-Remaining: 97 X-RateLimit-Reset: 1711036860
Base URL: https://sentinelnet.gudman.xyz
| Endpoint | Method | Description |
|---|---|---|
/api/health | GET | Health check |
/api/scores | GET | All scored agents (query: apply_decay, verdict) |
/api/stats | GET | Ecosystem statistics |
/api/marketplace | GET | Paginated marketplace (query: page, per_page, verdict, search, sort) |
/trust/{agent_id} | GET | Trust score with decay + explanation |
/trust/{agent_id}/history | GET | Score history (query: limit) |
/trust/compare | GET | Side-by-side comparison (query: agents=1,2,3) |
/trust/batch | POST | Batch query up to 100 agents |
/trust/graph/{agent_id} | GET | Counterparty trust neighborhood |
/badge/{agent_id}.svg | GET | Embeddable SVG trust badge |
/evidence/{agent_id} | GET | Evidence timeline |
/api/threats | GET | Threat intelligence feed (query: limit) |
/api/anomalies | GET | Statistical anomaly detection |
/api/graph-data | GET | Full agent graph for visualization |
/api/classify/{agent_id} | GET | Agent behavioral classification |
/api/trustgate/{agent_id} | GET | On-chain TrustGate record |
/api/contracts | GET | Deployed contract addresses |
/api/eas/{agent_id} | GET | EAS attestation info |
/api/simulate | POST | Score simulation |
/api/webhooks | POST | Register webhook |
/api/webhooks | GET | List webhooks |
/api/webhooks/{id} | DELETE | Delete webhook |
/api/keys | POST | Generate API key |
/metrics | GET | Prometheus metrics |
/ws/scores | WS | Live score updates |
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)",
...
]
}
}
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
}
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
}
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
}
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
}
}
GET /api/classify/31253
{
"agent_id": 31253,
"classification": "DeFi Operator",
"confidence": 0.87,
"behavioral_tags": ["high_frequency", "multi_protocol", "consistent_patterns"],
"risk_profile": "low"
}
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
}
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..."
}
]
}
Embed a live trust badge on any site:
<img src="https://sentinelnet.gudman.xyz/badge/31253.svg" alt="Trust Score">
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
...
Connect to /ws/scores for real-time trust score updates and threat alerts pushed as they happen.
ws://sentinelnet.gudman.xyz/ws/scores wss://sentinelnet.gudman.xyz/ws/scores (TLS)
wss://sentinelnet.gudman.xyz/ws/scores?api_key=sn_live_abc123...
| Event | Description | Frequency |
|---|---|---|
score_update | An agent's trust score was recomputed | As rescored |
threat_alert | New threat detected (sybil, degradation, contagion) | Real-time |
// 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"
}
}
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);
};
All error responses follow a consistent JSON structure. The status field matches the HTTP status code.
{
"error": "Human-readable error message",
"status": 400,
"detail": "Optional additional context"
}
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"
}
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"
}
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."
}
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."
}
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)
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);
Use TrustGate.sol to gate on-chain interactions by trust score.
// 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"
}
}
| Function | Returns | Description |
|---|---|---|
isTrusted(agentId) | bool | True if verdict is TRUST |
getTrustScore(agentId) | uint8 | Score 0-100 |
getVerdict(agentId) | string | TRUST / CAUTION / REJECT / UNSCORED |
getTrustRecord(agentId) | tuple | Full record with evidence URI |
| Modifier | Reverts When |
|---|---|
onlyTrusted(agentId) | Agent is not TRUST verdict |
onlyNotRejected(agentId) | Agent is REJECT verdict |
8 tools available via Model Context Protocol for agent-to-agent trust queries:
| Tool | Input | Description |
|---|---|---|
check_trust | agent_id, fresh? | Score lookup or fresh on-chain analysis |
list_scored_agents | verdict?, limit? | Browse all scored agents |
get_ecosystem_stats | none | Aggregate trust statistics |
get_score_history | agent_id, limit? | Score trends over time |
get_threat_feed | limit? | Real-time threat intelligence feed |
compare_agents | agent_ids | Side-by-side trust comparison of multiple agents |
check_sybil_status | agent_id | Check if an agent is flagged as part of a sybil cluster |
verify_on_chain | agent_id | Verify trust score against on-chain TrustGate record |
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"
}
}
}
}
// 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"
}
Register HTTP endpoints to receive push notifications when trust events occur. SentinelNet will POST a JSON payload to your URL for each matching event.
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 | Fires When | Payload Includes |
|---|---|---|
score_update | Any agent's score is recomputed | agent_id, trust_score, previous_score, verdict |
verdict_changed | Agent verdict transitions (e.g., TRUST to CAUTION) | agent_id, previous_verdict, verdict, trust_score |
sybil_detected | Agent flagged as sybil | agent_id, sybil_flagged, trust_score |
trust_degraded | Agent score drops from previous score | agent_id, trust_score, previous_score |
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
}
}
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)
| Attempt | Delay | Notes |
|---|---|---|
| 1st retry | 30 seconds | After initial failure (non-2xx response or timeout) |
| 2nd retry | 2 minutes | Exponential backoff |
| 3rd retry | 10 minutes | Final 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.
// 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
Every trust score is written on-chain via TrustGate (composable trust oracle) and attested via EAS (Ethereum Attestation Service).
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..."
}
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}
}
GET /api/eas/31253
{
"agent_id": 31253,
"attested": true,
"attestation_uid": "0x...",
"explorer": "https://base.easscan.org/attestation/view/0x..."
}
| Dimension | Weight | Signal |
|---|---|---|
| Longevity | 15% | Wallet age (logarithmic curve) |
| Activity | 20% | Tx volume, active days, ETH balance |
| Counterparty Quality | 20% | Verified vs flagged interaction ratio |
| Contract Risk | 20% | Malicious contract exposure |
| Agent Identity | 25% | 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)
Real-time feed of ecosystem threats detected by the autonomous agent:
| Threat Type | Description |
|---|---|
SYBIL_CLUSTER | Cluster of agents sharing wallets or forming closed interaction loops |
TRUST_DEGRADED | Agent's trust score dropped significantly between rescores |
CONTAGION_NEGATIVE | Agent'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
}
application/json and return application/json unless otherwise noted.