Results for https://hookdeck.com/LEVEL4Scanned just now
Agent-Integrated
Discoverability
75
3 pass · 1 fail
Content Accessibility
100
1 pass · 0 fail
Bot Access Control
100
2 pass · 0 fail
Discovery
29
2 pass · 5 fail
Commerce
Not checked
03 / 04 pass
Discoverability
- Goal
- Publish a robots.txt so agents and crawlers can discover crawl policy for this origin.
- How to implement
- Create /robots.txt on this origin with at least one User-agent group and sensible Allow/Disallow rules. Serve it as text/plain.
- Resources
- fetchGET /robots.txt200
User-agent: * Content-Signal: ai-train=yes, search=yes, ai-input=yes Allow: / Disallow: /discover User-agent: * Content-Signal: /terms ai-train=no, search=yes, ai-input=no Allow: /terms User-agent: * Content-Signal: /privacy ai-train=no, search=yes, ai-input=no Allow: /privacy User-agent: * Content-Signal: /dpa ai-train=no, search=yes, ai-input=no Allow: /dpa User-agent: * Content-Signal: /sub-processors ai-train=no, search=yes, ai-input=no Allow: /sub-processors
- concluderobots.txt present with User-agent directive
{"contentType":"text/plain; charset=utf-8"}
- Goal
- Expose a valid XML sitemap so agents can enumerate important URLs.
- How to implement
- Add a valid XML sitemap and reference it with a Sitemap: line in robots.txt (or serve /sitemap.xml).
- Resources
- fetchGET /sitemap-index.xml200
<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://hookdeck.com/sitemap-0.xml</loc></sitemap></sitemapindex>
- parseValid XML sitemap structure detected
- concludeSitemap OK at https://hookdeck.com/sitemap-index.xml
{"url":"https://hookdeck.com/sitemap-index.xml"}
- Goal
- Advertise agent-useful Link relations on the homepage so discovery is machine-readable.
- How to implement
- Add RFC 8288 Link response headers on GET / for agent-useful relations such as api-catalog, describedby, service-desc, or service-doc.
- Resources
- fetchGET /200
- parseParsed 6 Link entries
- concludeFound agent-useful rels: api-catalog, service-doc, service-doc, service-doc, service-doc, describedby
{"links":[{"rel":"api-catalog","href":"/.well-known/api-catalog"},{"rel":"service-doc","href":"/docs/api.md"},{"rel":"service-doc","href":"/docs/api"},{"rel":"service-doc","href":"/docs/outpost/api.md"},{"rel":"service-doc","href":"/docs/outpost/api"},{"rel":"describedby","href":"/llms.txt"}]}
- Goal
- Publish DNS-AID SVCB records under _agents so agents can find services via DNS.
- Issue
- No DNSSEC-validated DNS-AID SVCB/HTTPS/TXT ServiceMode records found
- How to implement
- Publish DNSSEC-validated SVCB/HTTPS records for _index._agents, _mcp._agents, and/or _a2a._agents on the apex (and www if used).
- Resources
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- dnsAD=false status=3 answers=0
- concludeNo DNSSEC-validated (AD=true) ServiceMode DNS-AID records
01 / 01 pass
Content Accessibility
- Goal
- Serve text/markdown when clients Accept: text/markdown so agents can read a clean page summary.
- How to implement
- When GET / is requested with Accept: text/markdown, respond with Content-Type including text/markdown (e.g. Cloudflare Markdown for Agents or an equivalent).
- Resources
- fetchGET /200
# Hookdeck > Hookdeck provides reliable infrastructure to work with webhooks and external events — without managing it yourself. Their offering includes managed solutions for the full webhook lifecycle — both receiving and sending. Hookdeck Event Gateway enables you to manage inbound webhooks and events before they hit your app, including receiving, transforming, and routing events, with full observability and control. Hookdeck Outpost is open-source outbound webhook delivery, enabling you to a…
- concludeContent-Type includes text/markdown
{"contentType":"text/markdown; charset=utf-8"}
02 / 03 pass
Bot Access Control
- Goal
- Declare AI crawler rules in robots.txt so bot access policy is explicit.
- How to implement
- Add explicit User-agent rules for known AI crawlers (GPTBot, ClaudeBot, PerplexityBot, etc.) or a clear User-agent: * policy in robots.txt.
- Resources
- parseParsed 5 user-agent group(s)
- concludeFound AI crawler rules or User-agent: * policy
- Goal
- Publish Content-Signal directives so AI training/search/input preferences are machine-readable.
- How to implement
- Add Content-Signal: lines in robots.txt with ai-train / search / ai-input directives stating your preferences for AI use of the site.
- Resources
- parseContent-Signal lines: 5
- concludeFound ai-train / search / ai-input directives
{"signals":["ai-train=yes, search=yes, ai-input=yes","/terms ai-train=no, search=yes, ai-input=no","/privacy ai-train=no, search=yes, ai-input=no","/dpa ai-train=no, search=yes, ai-input=no","/sub-processors ai-train=no, search=yes, ai-input=no"]}
- Goal
- Publish an HTTP Message Signatures directory so bots can authenticate cryptographically.
- How to implement
- Serve a valid JWKS directory at /.well-known/http-message-signatures-directory for cryptographic bot authentication.
- Resources
- fetchGET /.well-known/http-message-signatures-directory404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - concludeDirectory missing or invalid — reporting neutral
{"status":404}
02 / 08 pass
Discovery
- Goal
- Publish an RFC 9727 API catalog so agents can discover your API surfaces.
- How to implement
- Serve /.well-known/api-catalog as application/linkset+json with a linkset array describing your API surfaces.
- Resources
- fetchGET /.well-known/api-catalog200
{ "linkset": [ { "anchor": "https://api.hookdeck.com/latest", "service-desc": [ { "href": "https://api.hookdeck.com/latest/openapi", "type": "application/json" } ], "service-doc": [ { "href": "https://hookdeck.com/docs/api", "type": "text/html" }, { "href": "https://hookdeck.com/docs/api.md", "type": "text/markdown" } ], - parselinkset length 2
- concludeValid linkset catalog
{"linksetCount":2}
- Goal
- Publish OAuth/OIDC discovery metadata so agents can authenticate with your APIs.
- Issue
- No OAuth/OIDC discovery metadata with issuer + auth/token endpoints
- How to implement
- Serve /.well-known/openid-configuration or /.well-known/oauth-authorization-server with issuer, authorization_endpoint, and token_endpoint.
- Resources
- fetchGET /.well-known/openid-configuration404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - fetchGET /.well-known/oauth-authorization-server404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - concludeNo valid OAuth/OIDC discovery document
- Goal
- Publish OAuth protected resource metadata so agents know which auth servers protect your API.
- Issue
- oauth-protected-resource missing resource + authorization_servers
- How to implement
- Serve /.well-known/oauth-protected-resource with resource and authorization_servers, and advertise it via WWW-Authenticate where relevant.
- Resources
- fetchGET /.well-known/oauth-protected-resource404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - concludePRM missing or incomplete
- Goal
- Publish /auth.md so agents have human-readable registration and auth guidance.
- Issue
- Need auth.md plus discoverable PRM or agent_auth, with registration methods documented
- How to implement
- Serve /auth.md as text/markdown documenting how agents register/authenticate, discoverable via PRM and/or AS metadata agent_auth.
- Resources
- fetchGET /auth.md404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - fetchGET /.well-known/oauth-protected-resource404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentr… - parseauthMd=false prm=false agent_auth=false registrationDocs=true
- concludeauth.md discovery incomplete
{"authOk":false,"prmOk":false,"agentAuth":false,"mentionsRegistration":true}
- Goal
- Publish an MCP server card and reachable Streamable HTTP endpoint so agents can list tools.
- Issue
- No MCP server card (serverInfo.name/name) or live Streamable HTTP endpoint
- How to implement
- Publish /.well-known/mcp/server-card.json (or mcp.json) with serverInfo.name, and expose a Streamable HTTP MCP endpoint that answers initialize + tools/list.
- Resources
- fetchGET /.well-known/mcp.json404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - fetchGET /.well-known/mcp/server-cards.json404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - fetchGET /.well-known/mcp/server-card.json404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - fetchPOST /api/mcp/mcp404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - concludeNo MCP card or live endpoint
- Goal
- Publish an A2A agent card so agents can discover your A2A interface.
- How to implement
- Serve /.well-known/agent-card.json with name, version, and supportedInterfaces per the A2A Agent Card spec.
- Resources
- concludeCheck disabled for this scan
- Goal
- Publish an agent-skills index so agents can find skill docs for this origin.
- How to implement
- Serve /.well-known/agent-skills/index.json (v0.2) listing skills agents can use against this origin.
- Resources
- fetchGET /.well-known/agent-skills/index.json200
{ "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json", "skills": [ { "name": "event-gateway", "type": "archive", "description": "Comprehensive guide to the Hookdeck Event Gateway for receiving, routing, and delivering webhooks and events. Covers setup, connections, authentication, local development, monitoring, and API automation. Use when receiving webhooks, setting up webhook endpoints, testing webhooks locally, configuring webhook relay or event q… - parseskills array length 3
- concludeValid skills index at /.well-known/agent-skills/index.json
{"path":"/.well-known/agent-skills/index.json","count":3}
- Goal
- Register WebMCP tools on the homepage so headless scanners discover browser-side tools.
- Issue
- Homepage has no WebMCP tools on navigator.modelContext
- How to implement
- On page load, register at least one WebMCP tool via navigator.modelContext (provideContext/registerTool) so headless scanners can discover it.
- Resources
- fetchLaunching Browser Rendering session for WebMCP inspection
- parseCaptured 0 WebMCP tool registration(s)
- concludeNo tools recorded via provideContext/registerTool
00 / 05 pass
Commerce
- Goal
- Advertise x402 payment challenges on payable API routes so agents can pay per request.
- How to implement
- Return HTTP 402 with a valid x402 payment challenge (PAYMENT-REQUIRED / payment required body) on payable API routes such as /api/v1.
- Resources
- concludeCoinbase Bazaar discovery not queried (skipped in v1 scanner)
- fetchGET /200
<!DOCTYPE html><html lang="en"> <head><title>Hookdeck - Reliable webhook infrastructure</title><meta name="description" content="From webhooks to external event streams, Hookdeck ensures every event is received, processed, and monitored reliably at scale, giving you complete visibility and control."><link rel="canonical" href="https://hookdeck.com"><meta charset="UTF-8"><meta name="viewport" content="width=device-width"><link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96"><l…
- fetchGET /api404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - fetchGET /api/v1404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - concludeNo 402 x402 challenge found
- Goal
- Declare Machine Payments Protocol extensions in OpenAPI so payable ops are discoverable.
- How to implement
- Serve /openapi.json with x-payment-info extensions describing payable operations.
- Resources
- fetchGET /openapi.json404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - concludeHTTP 404
- Goal
- Publish Universal Commerce Protocol metadata for agent commerce discovery.
- How to implement
- Serve /.well-known/ucp with protocol_version and services.
- Resources
- fetchGET /.well-known/ucp404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - concludeHTTP 404
- Goal
- Publish Agentic Commerce Protocol metadata for agent commerce discovery.
- How to implement
- Serve /.well-known/acp.json with protocol name/version, api_base_url, transports, and capabilities.
- Resources
- fetchGET /.well-known/acp.json404
<!DOCTYPE html><script type="module">(function(){try{var d=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new d.Error().stack;e&&(d._sentryDebugIds=d._sentryDebugIds||{},d._sentryDebugIds[e]="5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3",d._sentryDebugIdIdentifier="sentry-dbid-5dbbf7a9-318d-4cf5-89b7-fd217b6b63c3")}catch{}})(),window.addEventListener("load",()=>{window.posthog&&window.posthog.capture("404NotFound")});</script> <html lang="en"… - concludeHTTP 404
- Goal
- Advertise AP2 extensions on the A2A agent card for agent payment flows.
- How to implement
- Extend /.well-known/agent-card.json with an AP2 extension that declares a role.
- Resources
- concludeCheck disabled for this scan
Improve the score
Next: Level 5 — Agent-Native
Publish an HTTP Message Signatures directory (Web Bot Auth)
Publish an MCP server card and reachable Streamable HTTP endpoint
Publish an A2A agent card
Publish OAuth/OIDC discovery metadata
Publish OAuth protected resource metadata
Publish auth.md with discoverable registration guidance
Next level
Level 5 — Agent-Native