Agent Protocol Inspector API Tutorial: Scan, Look Up, and Diff Two Scans
A curl-based tutorial for the Agent Protocol Inspector API: scanning an MCP or A2A target, retrieving a stored scan by scanId, and diffing two scans for a pass/warn/fail verdict.
This is a working tutorial for the three API-key-authenticated Agent Protocol Inspector endpoints that matter for automation: running a scan, retrieving a past one without re-scanning, and diffing two scans for a CI-usable verdict. Every request below uses a real endpoint and a real response shape.
Prerequisites
- An API key from the developer dashboard — API keys require a Pro plan.
curlandjqfor the examples below.- If you'd rather pay per call with USDC instead of holding an API key, every endpoint here has an
x402-v2sibling covered in our x402 wire v2 tutorial — the request/response shapes are identical, only the payment step differs.
All three endpoints share one rate limit bucket: 20 requests/minute, 1,000/day, at $0.02 per call.
Step 1: Run a Scan
curl -X POST https://contextiq.trango-compute.com/api/v1/agent-protocol-inspector \
-H "Authorization: Bearer $CONTEXTIQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"mcp.example.com"}'
The response is the full scan result, plus a scanId you'll reuse in the next two steps:
{
"target": "https://mcp.example.com",
"origin": "https://mcp.example.com",
"protocols": {
"mcp": { "status": "confirmed", "evidence": ["..."], "details": { "endpoint": "https://mcp.example.com/mcp", "mcpEra": "modern", "tools": [{ "name": "search_docs" }] } },
"a2a": { "status": "not_detected", "evidence": [] },
"ard": { "status": "not_detected", "evidence": [] }
},
"detectedCount": 1,
"conformance": "pass",
"scanId": "7f3c9a2e-1b44-4e8d-9c2a-5e7d0f1a8b3c",
"normalizedAgent": { "skills": ["..."] },
"capabilities": ["..."],
"igaPacket": { "recommendedDecision": "approve" }
}
Store scanId — it's how you refer back to this exact scan without paying to re-run it, and it's what the diff endpoint compares against.
Step 2: Look Up That Scan Later
Weeks later, without re-scanning:
curl https://contextiq.trango-compute.com/api/v1/agent-protocol-inspector/7f3c9a2e-1b44-4e8d-9c2a-5e7d0f1a8b3c \
-H "Authorization: Bearer $CONTEXTIQ_API_KEY"
This returns the identical response shape from Step 1 — normalizedAgent, capabilities, and igaPacket are recomputed fresh from the stored raw scan on every lookup, not cached from when the scan originally ran. That means a capability-rule improvement we ship later applies retroactively to a scan you ran months ago, with no re-scan required.
scanId lookup is ownership-scoped for API-key callers: you can only retrieve your own account's scans (anonymous-tier scans, with no owner, are the one exception — they resolve for anyone holding the id within their short retention window). Requesting a scanId that belongs to another account returns a 404, not a 403 — the endpoint doesn't reveal that the id exists at all.
Step 3: Run a Second Scan After Your Next Deploy
Same call as Step 1, run again after a deploy, producing a second, different scanId.
Step 4: Diff the Two Scans
curl -X POST https://contextiq.trango-compute.com/api/v1/agent-protocol-inspector/compare \
-H "Authorization: Bearer $CONTEXTIQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"baselineScanId":"7f3c9a2e-1b44-4e8d-9c2a-5e7d0f1a8b3c","currentScanId":"a1d8e4f0-22b7-4c91-8e5a-9f0c1d2b3a4e"}'
Response:
{
"baselineScanId": "7f3c9a2e-1b44-4e8d-9c2a-5e7d0f1a8b3c",
"currentScanId": "a1d8e4f0-22b7-4c91-8e5a-9f0c1d2b3a4e",
"verdict": "fail",
"protocols": {
"mcp": { "statusChanged": false, "from": "confirmed", "to": "confirmed", "itemsRemoved": ["search_docs"] },
"a2a": { "statusChanged": false, "from": "not_detected", "to": "not_detected" },
"ard": { "statusChanged": false, "from": "not_detected", "to": "not_detected" }
},
"summary": ["MCP tool(s) removed: search_docs"]
}
verdict is pass, warn, or fail — a tool or skill disappearing between scans is always a fail; something new appearing is a warn; no meaningful change is a pass. Both baselineScanId and currentScanId go through the same ownership check as Step 2 — comparing across two different accounts' scans 404s regardless of which side either scan lands on.
Step 5: Make the Verdict Actually Gate Something
A 200 response with "verdict":"fail" in the body still exits curl with status 0 — nothing about a successful HTTP call fails a build on its own. Pipe it through jq and check the field explicitly:
RESPONSE=$(curl -sS -X POST https://contextiq.trango-compute.com/api/v1/agent-protocol-inspector/compare \
-H "Authorization: Bearer $CONTEXTIQ_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"baselineScanId\":\"$BASELINE_SCAN_ID\",\"currentScanId\":\"$CURRENT_SCAN_ID\"}")
echo "$RESPONSE" | jq .
VERDICT=$(echo "$RESPONSE" | jq -r '.verdict')
if [ "$VERDICT" = "fail" ]; then
echo "Agent Protocol Inspector: regression detected — failing build." >&2
exit 1
fi
Drop that into a post-deploy CI job, with $BASELINE_SCAN_ID read from wherever you stored last deploy's scan id, and $CURRENT_SCAN_ID from the scan you just ran in Step 3. We cover the reasoning behind the pass/warn/fail rules — and why only fail should block a pipeline — in a separate post on the diff verdict itself.
Error Shapes Worth Handling
400— missing or malformedurl(scan endpoint) or missingbaselineScanId/currentScanId(compare endpoint).404— the scanId doesn't exist, has expired, or belongs to a different account.402— no API key and no x402 payment attached (see the x402 tutorial for the payment flow).
That's the full loop: scan, store the id, scan again later, diff the two, and gate a pipeline on the result. Get an API key from the developer dashboard and try it against your own MCP or A2A endpoint.
Follow Trango Compute on LinkedIn
We post updates on new tools, context engineering patterns, and LLM cost research.