{"openapi":"3.0.3","info":{"title":"LLMReady Public API","version":"v1","description":"Public API for creating and retrieving LLMReady scans. Version v1 is additive-compatible: existing fields and endpoints remain stable, and new optional fields may be added without a version bump.","x-api-version":"v1","x-compatibility":{"policy":"additive-compatible","breakingChanges":"require a new major public API version path"},"x-pricing":{"discoveryUrl":"/api/public/v1/pricing","wellKnownUrl":"/.well-known/llmready.json","hash":"b788d5f0667b5f55","scanTypes":{"quick":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"quick","description":"Create a quick LLMReady public scan","accepts":[{"amount":"5000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]},"full":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"full","description":"Create a full LLMReady public scan","accepts":[{"amount":"10000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]},"fixes":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"fixes","description":"Create an LLMReady public scan with generated fixes","accepts":[{"amount":"15000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]}}}},"servers":[{"url":"https://llmready.com","description":"Production"}],"tags":[{"name":"Scans","description":"Public scan creation and retrieval."},{"name":"Metadata","description":"Public API metadata."}],"paths":{"/api/public/v1/scans":{"post":{"operationId":"createPublicScan","summary":"Create a public scan","description":"Creates an AI-readiness scan for a public HTTP or HTTPS URL. Requires a bearer API key with the `scans:write` scope. x402-compatible clients can inspect the documented 402 response and `PAYMENT-SIGNATURE` authorization header metadata for paid access flows as they are enabled.","tags":["Scans"],"responses":{"201":{"description":"Scan accepted and queued.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicScanCreateEnvelope"},"example":{"data":{"scanId":"scan_123","publicId":"scan_123","statusUrl":"/api/public/v1/scans/scan_123/status","reportUrl":"/scan/scan_123","estimatedCompletionTime":"2026-05-24T10:01:00.000Z","estimatedCompletionSeconds":60,"options":{"scanType":"full","visibility":"unlisted","includeRecommendations":true,"includeGeneratedFixes":true}},"error":null}}}},"400":{"description":"Invalid request body, URL, or scan option.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Only HTTP and HTTPS URLs are supported","errorCode":"invalid_request"}}}},"401":{"description":"Missing or invalid API key.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Unauthorized","errorCode":"invalid_api_key"}}}},"402":{"description":"x402 payment is required for paid access flows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Payment required","errorCode":"payment_required"}}}},"403":{"description":"The API key is valid but lacks `scans:write`.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Forbidden","errorCode":"insufficient_scope"}}}},"429":{"description":"Rate limit exceeded for this API key.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."},"Retry-After":{"schema":{"type":"integer","example":60},"description":"Seconds until the client should retry."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Too many requests.","errorCode":"rate_limited"}}}},"500":{"description":"Unexpected server error.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Internal server error"}}}}},"x-api-version":"v1","x-required-scopes":["scans:write"],"x-authentication":["bearer-api-key","x402-payment"],"x-pricing":{"quick":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"quick","description":"Create a quick LLMReady public scan","accepts":[{"amount":"5000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]},"full":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"full","description":"Create a full LLMReady public scan","accepts":[{"amount":"10000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]},"fixes":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"fixes","description":"Create an LLMReady public scan with generated fixes","accepts":[{"amount":"15000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]}},"security":[{"bearerApiKey":[]},{"x402Payment":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicScanCreateRequest"},"example":{"url":"https://example.com","options":{"scanType":"full","visibility":"unlisted","includeRecommendations":true,"includeGeneratedFixes":true}}}}}}},"/api/public/v1/scans/{scanId}":{"get":{"operationId":"getPublicScan","summary":"Retrieve a public scan","description":"Returns a public scan report by public scan id. Private or internal scans are returned as not found.","tags":["Scans"],"responses":{"200":{"description":"Public scan report.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicScanEnvelope"},"example":{"data":{"id":"scan_123","publicId":"scan_123","url":"https://example.com/","inputUrl":"example.com","normalizedUrl":"https://example.com/","finalUrl":"https://example.com/","domain":"example.com","status":"completed","score":92,"rating":"ai-ready","summary":"This site is AI-ready.","results":{"checks":[{"key":"llmsTxt","title":"llms.txt","status":"pass","severity":"low","explanation":"Found llms.txt.","recommendation":"Keep the file updated.","weight":15,"pointsAwarded":15}],"issueCount":0,"recommendations":[]},"metadata":{"httpStatus":200,"title":"Example","description":"Example site","durationMs":123,"scannerVersion":"1.0.0","reportUrl":"/scan/scan_123","createdAt":"2026-05-19T10:00:00.000Z","updatedAt":"2026-05-19T10:01:00.000Z"}},"error":null}}}},"400":{"description":"Invalid scan id format.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Invalid scanId format","errorCode":"invalid_scan_id"}}}},"404":{"description":"Scan not found or not publicly accessible.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Scan not found","errorCode":"not_found"}}}},"429":{"description":"IP-based rate limit exceeded.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."},"Retry-After":{"schema":{"type":"integer","example":60},"description":"Seconds until the client should retry."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Too many requests.","errorCode":"rate_limited"}}}},"500":{"description":"Unexpected server error.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Internal server error"}}}}},"x-api-version":"v1","x-authentication":["none"],"parameters":[{"name":"scanId","in":"path","required":true,"description":"Public scan identifier.","schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9_-]+$"},"example":"scan_123"}]}},"/api/public/v1/scans/{scanId}/status":{"get":{"operationId":"getPublicScanStatus","summary":"Retrieve scan status","description":"Returns current progress for a public scan. Private or internal scans are returned as not found.","tags":["Scans"],"responses":{"200":{"description":"Public scan status.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicScanStatusEnvelope"},"example":{"data":{"scanId":"scan_123","publicId":"scan_123","status":"running","progress":45,"domain":"example.com","url":"https://example.com/","estimatedCompletion":"2026-05-24T10:01:00.000Z","updatedAt":"2026-05-24T10:00:30.000Z"},"error":null}}}},"400":{"description":"Invalid scan id format.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Invalid scanId format","errorCode":"invalid_scan_id"}}}},"404":{"description":"Scan not found or not publicly accessible.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Scan not found","errorCode":"not_found"}}}},"429":{"description":"IP-based rate limit exceeded.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."},"Retry-After":{"schema":{"type":"integer","example":60},"description":"Seconds until the client should retry."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Too many requests.","errorCode":"rate_limited"}}}},"500":{"description":"Unexpected server error.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Internal server error"}}}}},"x-api-version":"v1","x-authentication":["none"],"parameters":[{"name":"scanId","in":"path","required":true,"description":"Public scan identifier.","schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9_-]+$"},"example":"scan_123"}]}},"/api/public/v1/scans/{scanId}/fixes":{"get":{"operationId":"getPublicScanFixes","summary":"Retrieve generated scan fixes","description":"Returns generated remediation artifacts and check-level fixes for a public scan. Private or internal scans are returned as not found.","tags":["Scans"],"responses":{"200":{"description":"Generated fixes for a public scan.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicScanFixesEnvelope"},"example":{"data":{"scanId":"scan_123","publicId":"scan_123","domain":"example.com","generated":{"llmsTxt":"# Example","robotsTxtAdditions":"Allow: /"},"fixes":[{"checkKey":"structuredData","title":"Structured data","severity":"high","recommendation":"Add JSON-LD.","fixSnippet":"{\"@context\":\"https://schema.org\"}","fixLanguage":"json"}]},"error":null}}}},"400":{"description":"Invalid scan id format.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Invalid scanId format","errorCode":"invalid_scan_id"}}}},"404":{"description":"Scan not found or not publicly accessible.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Scan not found","errorCode":"not_found"}}}},"429":{"description":"IP-based rate limit exceeded.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."},"Retry-After":{"schema":{"type":"integer","example":60},"description":"Seconds until the client should retry."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Too many requests.","errorCode":"rate_limited"}}}},"500":{"description":"Unexpected server error.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Internal server error"}}}}},"x-api-version":"v1","x-authentication":["none"],"parameters":[{"name":"scanId","in":"path","required":true,"description":"Public scan identifier.","schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9_-]+$"},"example":"scan_123"}]}},"/api/public/v1/domains/{domain}/history":{"get":{"operationId":"getPublicDomainHistory","summary":"Retrieve public domain scan history","description":"Returns UTC daily average scores for public scans on a domain. Private and internal scans are excluded.","tags":["Scans"],"responses":{"200":{"description":"Public domain history.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicDomainHistoryEnvelope"},"example":{"data":[{"date":"2026-05-20","score":90}],"error":null}}}},"400":{"description":"Invalid domain or query string.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Domain is invalid","errorCode":"invalid_domain"}}}},"404":{"description":"Domain has no public scan data.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Domain not found","errorCode":"domain_not_found"}}}},"429":{"description":"IP-based rate limit exceeded.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."},"Retry-After":{"schema":{"type":"integer","example":60},"description":"Seconds until the client should retry."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Too many requests.","errorCode":"rate_limited"}}}},"500":{"description":"Unexpected server error.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Internal server error"}}}}},"x-api-version":"v1","x-authentication":["none"],"parameters":[{"name":"domain","in":"path","required":true,"description":"Domain name or URL-encoded HTTP(S) URL.","schema":{"type":"string","example":"example.com"}},{"name":"range","in":"query","required":false,"description":"History range to include.","schema":{"type":"string","enum":["7d","30d","90d","all"],"default":"30d"}}]}},"/api/public/v1/scans/recent":{"get":{"operationId":"listRecentPublicScans","summary":"List recent public scans","description":"Returns recent completed public scan summaries. Private and internal scans are excluded.","tags":["Scans"],"responses":{"200":{"description":"Recent public scans.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRecentScansEnvelope"},"example":{"data":{"items":[{"publicId":"scan_123","domain":"example.com","score":90,"rating":"ai-ready","summary":"Example scored 90/100 for AI visibility.","checks":[],"reportUrl":"/scan/scan_123","scanDate":"2026-05-20T10:00:00.000Z","createdAt":"2026-05-20T10:00:00.000Z"}],"source":"database"},"error":null}}}},"400":{"description":"Invalid query string.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"limit must be less than or equal to 10","errorCode":"invalid_query"}}}},"429":{"description":"IP-based rate limit exceeded.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."},"Retry-After":{"schema":{"type":"integer","example":60},"description":"Seconds until the client should retry."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Too many requests.","errorCode":"rate_limited"}}}},"500":{"description":"Unexpected server error.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Internal server error"}}}}},"x-api-version":"v1","x-authentication":["none"],"parameters":[{"name":"limit","in":"query","required":false,"description":"Number of recent scans to return.","schema":{"type":"integer","minimum":1,"maximum":10,"default":10}}]}},"/api/public/v1/pricing":{"get":{"operationId":"getPublicPricing","summary":"Retrieve public API pricing","description":"Returns current x402 endpoint pricing, accepted currencies or tokens, and per-scan-type prices for agent discovery.","tags":["Metadata"],"responses":{"200":{"description":"Public API endpoint pricing.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicPricingEnvelope"},"example":{"data":{"version":"v1","source":"environment","updatedAt":"2026-05-24T00:00:00.000Z","currencyOptions":["USDC:base-sepolia"],"endpoints":[{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"quick","description":"Create a quick LLMReady public scan","accepts":[{"amount":"5000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]},{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"full","description":"Create a full LLMReady public scan","accepts":[{"amount":"10000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]},{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"fixes","description":"Create an LLMReady public scan with generated fixes","accepts":[{"amount":"15000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]}],"scanTypes":{"quick":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"quick","description":"Create a quick LLMReady public scan","accepts":[{"amount":"5000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]},"full":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"full","description":"Create a full LLMReady public scan","accepts":[{"amount":"10000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]},"fixes":{"endpoint":"/api/public/v1/scans","method":"POST","operationId":"createPublicScan","scanType":"fixes","description":"Create an LLMReady public scan with generated fixes","accepts":[{"amount":"15000","asset":"USDC","network":"base-sepolia","payTo":"x402:llmready","scheme":"exact"}]}},"metadata":{"hash":"b788d5f0667b5f55","discoveryUrl":"/api/public/v1/pricing","wellKnownUrl":"/.well-known/llmready.json"}},"error":null}}}},"429":{"description":"IP-based metadata rate limit exceeded.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."},"Retry-After":{"schema":{"type":"integer","example":60},"description":"Seconds until the client should retry."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Too many requests.","errorCode":"rate_limited"}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Internal server error"}}}}},"x-api-version":"v1","x-authentication":["none"],"x-pricing-discovery":true}},"/api/public/v1/openapi.json":{"get":{"operationId":"getPublicOpenApiSpec","summary":"Retrieve the public OpenAPI specification","description":"Returns the dynamically generated OpenAPI 3.0 document for the public API.","tags":["Metadata"],"responses":{"200":{"description":"OpenAPI 3.0 document.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenApiDocument"},"example":{"openapi":"3.0.3","info":{"title":"LLMReady Public API","version":"v1"},"paths":{}}}}},"429":{"description":"IP-based metadata rate limit exceeded.","headers":{"X-LLMReady-API-Version":{"schema":{"type":"string","example":"v1"},"description":"Public API version that handled the request."},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60},"description":"Maximum public API requests allowed for this identity and endpoint type."},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":59},"description":"Remaining public API requests in the current token bucket."},"X-RateLimit-Reset":{"schema":{"type":"integer","example":1779616800},"description":"Unix timestamp, in seconds, when the current token bucket refills."},"Retry-After":{"schema":{"type":"integer","example":60},"description":"Seconds until the client should retry."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorEnvelope"},"example":{"data":null,"error":"Too many requests.","errorCode":"rate_limited"}}}}},"x-api-version":"v1","x-authentication":["none"]}}},"components":{"schemas":{"PublicApiErrorEnvelope":{"type":"object","properties":{"data":{"nullable":true},"error":{"type":"string"},"errorCode":{"type":"string"}},"required":["data","error"]},"PublicScanCreateEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"scanId":{"type":"string"},"publicId":{"type":"string"},"statusUrl":{"type":"string"},"reportUrl":{"type":"string"},"estimatedCompletionTime":{"type":"string","format":"date-time"},"estimatedCompletionSeconds":{"type":"integer","minimum":0},"options":{"type":"object","properties":{"scanType":{"type":"string","enum":["quick","full","fixes"]},"visibility":{"type":"string","enum":["public","unlisted"]},"includeRecommendations":{"type":"boolean"},"includeGeneratedFixes":{"type":"boolean"}}}},"required":["scanId","publicId","statusUrl","reportUrl","estimatedCompletionTime","estimatedCompletionSeconds","options"]},"error":{"nullable":true}},"required":["data","error"]},"PublicScanCreateRequest":{"type":"object","properties":{"url":{"type":"string","minLength":3,"maxLength":2048},"options":{"type":"object","properties":{"scanType":{"type":"string","enum":["quick","full","fixes"]},"visibility":{"type":"string","enum":["public","unlisted"]},"includeRecommendations":{"type":"boolean"},"includeGeneratedFixes":{"type":"boolean"}},"additionalProperties":false}},"required":["url"]},"PublicScanEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"publicId":{"type":"string"},"url":{"type":"string"},"inputUrl":{"type":"string"},"normalizedUrl":{"type":"string"},"finalUrl":{"type":"string"},"domain":{"type":"string"},"status":{"type":"string","enum":["pending","running","completed","failed"]},"score":{"type":"number"},"rating":{"type":"string","enum":["poor","needs-work","ai-readable","ai-ready"]},"summary":{"type":"string"},"results":{"type":"object","properties":{"checks":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"severity":{"type":"string"},"explanation":{"type":"string"},"recommendation":{"type":"string"},"weight":{"type":"number"},"pointsAwarded":{"type":"number"}},"required":["key","title","status","severity","explanation","weight","pointsAwarded"]}},"issueCount":{"type":"integer","minimum":0},"recommendations":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"priority":{"type":"string"},"checkKey":{"type":"string"}},"required":["title","description","priority"]}}},"required":["checks","issueCount","recommendations"]},"metadata":{"type":"object","properties":{"httpStatus":{"type":"integer","minimum":100,"maximum":599},"title":{"type":"string"},"description":{"type":"string"},"durationMs":{"type":"number"},"scannerVersion":{"type":"string"},"reportUrl":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["createdAt","updatedAt"]}},"required":["id","publicId","url","status","score","summary","results","metadata"]},"error":{"nullable":true}},"required":["data","error"]},"PublicScanStatusEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"scanId":{"type":"string"},"publicId":{"type":"string"},"status":{"type":"string","enum":["pending","running","completed","failed"]},"progress":{"type":"integer","minimum":0,"maximum":100},"domain":{"type":"string"},"url":{"type":"string"},"error":{"type":"string"},"estimatedCompletion":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["scanId","publicId","status","progress","estimatedCompletion","updatedAt"]},"error":{"nullable":true}},"required":["data","error"]},"PublicScanFixesEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"scanId":{"type":"string"},"publicId":{"type":"string"},"domain":{"type":"string"},"generated":{"type":"object","properties":{"llmsTxt":{"type":"string"},"robotsTxtAdditions":{"type":"string"},"sitemapXml":{"type":"string"},"contentSignal":{"type":"string"},"jsonLd":{"type":"string"}}},"fixes":{"type":"array","items":{"type":"object","properties":{"checkKey":{"type":"string"},"title":{"type":"string"},"severity":{"type":"string","enum":["low","medium","high"]},"recommendation":{"type":"string"},"fixSnippet":{"type":"string"},"fixLanguage":{"type":"string","enum":["txt","json","html","markdown"]}},"required":["checkKey","title","severity","recommendation"]}}},"required":["scanId","publicId","generated","fixes"]},"error":{"nullable":true}},"required":["data","error"]},"PublicDomainHistoryEnvelope":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"score":{"type":"integer","minimum":0,"maximum":100}},"required":["date","score"]}},"error":{"nullable":true}},"required":["data","error"]},"PublicRecentScansEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"publicId":{"type":"string"},"domain":{"type":"string"},"score":{"type":"integer","minimum":0,"maximum":100},"rating":{"type":"string","enum":["poor","needs-work","ai-readable","ai-ready"]},"summary":{"type":"string"},"checks":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"status":{"type":"string","enum":["pass","warn","fail"]},"pointsAwarded":{"type":"number"},"weight":{"type":"number"}},"required":["key","label","status","pointsAwarded","weight"]}},"reportUrl":{"type":"string"},"scanDate":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["publicId","domain","score","rating","summary","checks","reportUrl","scanDate","createdAt"]}},"source":{"type":"string","enum":["database","fixture"]}},"required":["items","source"]},"error":{"nullable":true}},"required":["data","error"]},"PublicPricingEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"version":{"type":"string"},"source":{"type":"string","enum":["environment"]},"updatedAt":{"type":"string"},"currencyOptions":{"type":"array","items":{"type":"string"}},"endpoints":{"type":"array","items":{"type":"object","properties":{"endpoint":{"type":"string"},"method":{"type":"string"},"operationId":{"type":"string"},"description":{"type":"string"},"scanType":{"type":"string","enum":["quick","full","fixes"]},"accepts":{"type":"array","items":{"type":"object","properties":{"amount":{"type":"string"},"asset":{"type":"string"},"network":{"type":"string"},"payTo":{"type":"string"},"scheme":{"type":"string"},"decimals":{"type":"integer"}},"required":["amount","asset","network","payTo","scheme"]}}},"required":["endpoint","method","operationId","description","accepts"]}},"scanTypes":{"type":"object","additionalProperties":{"type":"object","properties":{"endpoint":{"type":"string"},"method":{"type":"string"},"operationId":{"type":"string"},"description":{"type":"string"},"scanType":{"type":"string","enum":["quick","full","fixes"]},"accepts":{"type":"array","items":{"type":"object","properties":{"amount":{"type":"string"},"asset":{"type":"string"},"network":{"type":"string"},"payTo":{"type":"string"},"scheme":{"type":"string"},"decimals":{"type":"integer"}},"required":["amount","asset","network","payTo","scheme"]}}},"required":["endpoint","method","operationId","description","accepts"]}},"metadata":{"type":"object","properties":{"hash":{"type":"string"},"discoveryUrl":{"type":"string"},"wellKnownUrl":{"type":"string"}},"required":["hash","discoveryUrl","wellKnownUrl"]}},"required":["version","source","updatedAt","currencyOptions","endpoints","scanTypes","metadata"]},"error":{"nullable":true}},"required":["data","error"]},"OpenApiDocument":{"type":"object","properties":{"openapi":{"type":"string"},"info":{"type":"object","properties":{"title":{"type":"string"},"version":{"type":"string"}},"required":["title","version"]},"paths":{"type":"object","additionalProperties":{}}},"required":["openapi","info","paths"]}},"securitySchemes":{"bearerApiKey":{"type":"http","scheme":"bearer","bearerFormat":"LLMReady API key","description":"Send `Authorization: Bearer <api_key>`. Scan creation requires the `scans:write` scope."},"x402Payment":{"type":"apiKey","in":"header","name":"PAYMENT-SIGNATURE","description":"x402 payment authorization header for clients using pay-per-call access flows."}}}}