{"openapi":"3.0.3","info":{"title":"subagentdispatch API","version":"1.1.0","description":"Replay-mode managed agents. /api/v1/replay streams recorded Anthropic SSE responses from Cloudflare R2 — zero ANTHROPIC_API_KEY, zero tokens at runtime. Legacy vendor-tracking endpoints remain for the llms.txt ingestion tier.","contact":{"name":"subagentdispatch","url":"https://www.subagentdispatch.com"},"license":{"name":"MIT"}},"servers":[{"url":"https://www.subagentdispatch.com","description":"Chassis"},{"url":"https://www.subagentlegal.com","description":"Legal vertical"},{"url":"https://www.subagentfinance.com","description":"Finance vertical"},{"url":"https://www.subagentengineering.com","description":"Developer-tools vertical"}],"security":[],"tags":[{"name":"Replay","description":"SSE replay of recorded Anthropic responses from R2"},{"name":"Cassettes","description":"JSON listing of replayable cassettes per site"},{"name":"Feed","description":"Legacy: vendor snapshots and diffs (llms.txt ingestion tier)"},{"name":"Vendors","description":"Legacy: vendor listing, detail, and raw content access"},{"name":"Intelligence","description":"Legacy: AI-powered change analysis reports"},{"name":"Webhooks","description":"Push notification registration for high-significance changes (pro tier)"},{"name":"Keys","description":"API key management and rotation"},{"name":"Billing","description":"Pricing tiers and Stripe checkout"},{"name":"Operations","description":"Health checks and operational status"}],"paths":{"/api/v1/replay/{vertical}/{cookbook}":{"get":{"operationId":"replayCassette","summary":"Stream a recorded cassette as SSE","description":"Reads the matching HAR cassette from Cloudflare R2 (env.CASSETTES) and streams its recorded SSE chunks with original delta_ms timing. The shape is byte-identical to the original Anthropic API response. No ANTHROPIC_API_KEY required. The response carries x-replay-source: cassette and x-replay-tokens-spent: 0 headers so clients can verify the source.","tags":["Replay"],"parameters":[{"name":"vertical","in":"path","required":true,"schema":{"type":"string","enum":["legal","finance","small-business","developer-tools"]},"description":"Cassette vertical"},{"name":"cookbook","in":"path","required":true,"schema":{"type":"string"},"description":"Cassette slug under the vertical (e.g. diligence-grid, kyc-screener)"}],"responses":{"200":{"description":"SSE stream of recorded Anthropic message events","headers":{"x-replay-source":{"schema":{"type":"string","enum":["cassette"]}},"x-replay-cassette":{"schema":{"type":"string"}},"x-replay-tokens-spent":{"schema":{"type":"string","enum":["0"]}}},"content":{"text/event-stream":{"schema":{"type":"string"}}}},"404":{"description":"No cassette at the given path"},"503":{"description":"CASSETTES binding not configured on this Worker"}}}},"/api/v1/cassettes":{"get":{"operationId":"listCassettes","summary":"List replayable cassettes for this site","description":"Site-aware JSON listing. Each entry includes slug, vertical, title, model, cassette_path, replay_url, and tokens_per_replay (always 0).","tags":["Cassettes"],"responses":{"200":{"description":"Cassette listing","content":{"application/json":{"schema":{"type":"object","properties":{"site":{"type":"string"},"vertical":{"type":"string"},"host":{"type":"string"},"count":{"type":"integer"},"cassettes":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"vertical":{"type":"string"},"title":{"type":"string"},"subtitle":{"type":"string"},"model":{"type":"string"},"cassette_path":{"type":"string"},"replay_url":{"type":"string","format":"uri"},"tokens_per_replay":{"type":"integer","enum":[0]}}}}}}}}}}}},"/api/v1/health":{"get":{"operationId":"getHealth","summary":"Health check for uptime monitoring","description":"Returns service status, version, timestamp, and database connectivity. No authentication required. Intended for uptime monitors and load balancers.","tags":["Operations"],"responses":{"200":{"description":"Service health status","headers":{"Cache-Control":{"description":"Always set to no-cache","schema":{"type":"string","example":"no-cache"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"example":{"status":"ok","version":"1.0.0","timestamp":"2026-03-01T12:00:00.000Z","db_connected":true}}}}}}},"/api/v1/feed":{"get":{"operationId":"getFeed","summary":"Get the main feed","description":"Returns vendor metadata, latest snapshots, and recent diffs. Free tier omits diff content; starter/pro tiers include full diff text. Supports cursor-based pagination via the `cursor` parameter (pass `next_cursor` from the previous response).","tags":["Feed"],"security":[{},{"BearerAuth":[]}],"x-rate-limit":{"free":"100 requests/day","starter":"5000 requests/day","pro":"50000 requests/day"},"parameters":[{"name":"vendor","in":"query","description":"Filter by vendor slug","required":false,"schema":{"type":"string"},"example":"anthropic"},{"name":"since","in":"query","description":"Only include snapshots fetched after this ISO 8601 date","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-02-01T00:00:00Z"},{"name":"cursor","in":"query","description":"UUID of the last item from the previous page (snapshot_id). Used for cursor-based pagination. Pass the `next_cursor` value from the `_meta` object of the previous response.","required":false,"schema":{"type":"string","format":"uuid"},"example":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"},{"name":"limit","in":"query","description":"Maximum number of items to return per page. Default 50, max 100.","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"example":50}],"responses":{"200":{"description":"Feed entries with vendor metadata, latest snapshot, and optional diff content","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per day for the authenticated tier","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests for the current day","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit resets (midnight UTC)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedResponse"},"example":{"_meta":{"service":"jadecli llms.txt feed","version":"0.3.0","count":5,"next_cursor":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","has_more":true,"vendor_count":5,"tier":"free","updated_at":"2026-02-28T12:00:00.000Z"},"feed":[{"vendor":{"name":"Anthropic","slug":"anthropic","domain":"platform.claude.com","category":"ai-platform"},"latest":{"content_hash":"a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890","byte_size":15360,"line_count":342,"link_count":85,"fetched_at":"2026-02-28T06:00:00.000Z"},"recent_change":{"lines_added":12,"lines_removed":3,"detected_at":"2026-02-28T06:00:00.000Z"}}]}}}},"400":{"description":"Invalid request parameter (e.g. malformed cursor UUID)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"cursor must be a valid UUID","code":"invalid_cursor","status":400}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Rate limit exceeded","code":"rate_limited","status":429}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Feed query failed","code":"internal_error","status":500}}}}}}},"/api/v1/vendors":{"get":{"operationId":"listVendors","summary":"List all active vendors","description":"Returns all active vendors with their latest snapshot metadata. No authentication required.","tags":["Vendors"],"responses":{"200":{"description":"List of active vendors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VendorListResponse"},"example":{"count":5,"vendors":[{"name":"Anthropic","slug":"anthropic","domain":"platform.claude.com","category":"ai-platform","latest":{"content_hash":"a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890","byte_size":15360,"line_count":342,"link_count":85,"fetched_at":"2026-02-28T06:00:00.000Z"}},{"name":"Neon","slug":"neon","domain":"neon.com","category":"database","latest":{"content_hash":"f6e5d4c3b2a19876543210fedcba9876543210fedcba9876543210fedcba9876","byte_size":8192,"line_count":180,"link_count":42,"fetched_at":"2026-02-28T06:00:00.000Z"}}]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Vendors query failed","code":"internal_error","status":500}}}}}}},"/api/v1/vendors/search":{"get":{"operationId":"searchVendors","summary":"Full-text search vendors","description":"Search vendors by name, slug, or domain with optional category and status filters. No authentication required. Uses ILIKE for case-insensitive matching. Supports offset-based pagination via `limit` and `offset` parameters.","tags":["Vendors"],"parameters":[{"name":"q","in":"query","description":"Search term -- matched against name, slug, and domain via ILIKE","required":false,"schema":{"type":"string"},"example":"anthropic"},{"name":"category","in":"query","description":"Filter by vendor category","required":false,"schema":{"$ref":"#/components/schemas/VendorCategory"},"example":"ai-platform"},{"name":"status","in":"query","description":"Filter by vendor status (default: active)","required":false,"schema":{"type":"string","enum":["active","paused","unreachable"],"default":"active"},"example":"active"},{"name":"limit","in":"query","description":"Max results to return (default: 50, max: 100)","required":false,"schema":{"type":"integer","default":50,"minimum":1,"maximum":100},"example":50},{"name":"offset","in":"query","description":"Number of results to skip for offset-based pagination (default: 0)","required":false,"schema":{"type":"integer","default":0,"minimum":0},"example":0}],"responses":{"200":{"description":"Search results with metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VendorSearchResponse"},"example":{"_meta":{"count":1,"filters":{"q":"anthropic","category":null,"status":"active","limit":50,"offset":0}},"vendors":[{"name":"Anthropic","slug":"anthropic","domain":"platform.claude.com","category":"ai-platform","status":"active"}]}}}},"400":{"description":"Invalid filter parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Invalid status: unknown. Must be one of: active, paused, unreachable","code":"bad_request","status":400}}}}}}},"/api/v1/vendors/{slug}":{"get":{"operationId":"getVendor","summary":"Get vendor detail","description":"Returns vendor metadata, last 10 snapshots (metadata only, no content), and last 10 diffs. No authentication required.","tags":["Vendors"],"parameters":[{"name":"slug","in":"path","required":true,"description":"Vendor slug identifier","schema":{"type":"string"},"example":"anthropic"}],"responses":{"200":{"description":"Vendor detail with snapshot and diff history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VendorDetailResponse"},"example":{"vendor":{"name":"Anthropic","slug":"anthropic","domain":"platform.claude.com","category":"ai-platform","status":"active","llms_txt_url":"https://platform.claude.com/llms.txt","llms_full_txt_url":null},"snapshots":[{"id":"550e8400-e29b-41d4-a716-446655440000","content_hash":"a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890","byte_size":15360,"line_count":342,"link_count":85,"fetched_at":"2026-02-28T06:00:00.000Z","http_status":200,"response_time_ms":245,"security_score":0}],"diffs":[{"id":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","previous_snapshot_id":"11111111-2222-3333-4444-555555555555","current_snapshot_id":"550e8400-e29b-41d4-a716-446655440000","lines_added":12,"lines_removed":3,"links_added":["https://docs.anthropic.com/tool-use"],"links_removed":[],"created_at":"2026-02-28T06:00:00.000Z"}]}}}},"404":{"description":"Vendor not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Vendor not found","code":"not_found","status":404}}}}}}},"/api/v1/vendors/{slug}/content":{"get":{"operationId":"getVendorContent","summary":"Get raw vendor llms.txt content","description":"Returns the latest llms.txt content for a vendor with metadata. Requires starter or pro tier API key.","tags":["Vendors"],"security":[{"BearerAuth":[]}],"x-rate-limit":{"free":"Not available (401)","starter":"5000 requests/day","pro":"50000 requests/day"},"parameters":[{"name":"slug","in":"path","required":true,"description":"Vendor slug identifier","schema":{"type":"string"},"example":"anthropic"}],"responses":{"200":{"description":"Raw llms.txt content with metadata","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per day for the authenticated tier","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests for the current day","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit resets (midnight UTC)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VendorContentResponse"},"example":{"content":"# Anthropic\n\n> Anthropic builds reliable, interpretable, and steerable AI systems.\n\n- [Claude API Documentation](https://docs.anthropic.com)\n- [Tool Use](https://docs.anthropic.com/tool-use)\n","metadata":{"content_hash":"a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890","byte_size":15360,"line_count":342,"link_count":85,"fetched_at":"2026-02-28T06:00:00.000Z"}}}}},"401":{"description":"API key required (free tier insufficient)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"API key required. See /pricing for plans.","code":"unauthorized","status":401}}}},"404":{"description":"Vendor or snapshot not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Vendor not found","code":"not_found","status":404}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Rate limit exceeded","code":"rate_limited","status":429}}}}}}},"/api/v1/content/{slug}":{"get":{"operationId":"getContentSandboxed","summary":"Get sandboxed llms.txt content","description":"Returns the latest llms.txt content wrapped in XML sandbox delimiters for safe LLM consumption. Returns 403 if security_score >= 3. No authentication required.","tags":["Vendors"],"parameters":[{"name":"slug","in":"path","required":true,"description":"Vendor slug identifier","schema":{"type":"string"},"example":"anthropic"}],"responses":{"200":{"description":"Sandboxed llms.txt content as plain text wrapped in XML delimiters","headers":{"X-Content-Security-Score":{"description":"Security score of the content (0-5, where 0 is safest)","schema":{"type":"string"}}},"content":{"text/plain":{"schema":{"type":"string"},"example":"<vendor-content source=\"anthropic\">\n# Anthropic\n\n> Anthropic builds reliable AI systems.\n</vendor-content>"}}},"403":{"description":"Content flagged as unsafe (security_score >= 3)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Content flagged as unsafe","code":"forbidden","status":403}}}},"404":{"description":"Vendor or snapshot not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Vendor not found","code":"not_found","status":404}}}}}}},"/api/v1/stats":{"get":{"operationId":"getStats","summary":"Get aggregate statistics","description":"Returns aggregate counts for vendors, snapshots, diffs, total bytes tracked, and breakdowns by category and status. No authentication required.","tags":["Feed"],"responses":{"200":{"description":"Aggregate feed statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"},"example":{"vendors":334,"snapshots":12500,"diffs":890,"total_bytes_tracked":52428800,"category_breakdown":{"ai-platform":45,"developer-tools":120,"database":38,"payments":22,"cloud":40,"data-analytics":30,"integration":25,"security":14},"status_breakdown":{"active":310,"paused":12,"unreachable":12}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Stats query failed","code":"internal_error","status":500}}}}}}},"/api/v1/pricing":{"get":{"operationId":"getPricing","summary":"Get pricing tiers","description":"Returns all pricing tiers with rate limits, feature flags, and monthly prices. No authentication required.","tags":["Billing"],"responses":{"200":{"description":"Pricing tier configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingResponse"},"example":{"free":{"tier":"free","monthly_price_usd":0,"requests_per_day":100,"vendor_access":"public-5","history_days":7,"diff_access":false,"api_access":false,"webhooks":false},"starter":{"tier":"starter","monthly_price_usd":29,"requests_per_day":5000,"vendor_access":"all","history_days":90,"diff_access":true,"api_access":true,"webhooks":false},"pro":{"tier":"pro","monthly_price_usd":99,"requests_per_day":50000,"vendor_access":"all-plus-custom","history_days":365,"diff_access":true,"api_access":true,"webhooks":true}}}}}}}},"/api/v1/intelligence":{"get":{"operationId":"getIntelligence","summary":"Query intelligence reports","description":"AI-generated change analysis for tracked vendors. Returns summaries, significance scores (1-5), categorized changes, and key quotes. Requires starter tier or above. Starter tier limited to 90-day history; pro tier has full history.","tags":["Intelligence"],"security":[{"BearerAuth":[]}],"x-rate-limit":{"free":"Not available (403)","starter":"5000 requests/day","pro":"50000 requests/day"},"parameters":[{"name":"vendor","in":"query","description":"Filter by vendor slug","required":false,"schema":{"type":"string"},"example":"anthropic"},{"name":"since","in":"query","description":"Only reports after this ISO 8601 date (clamped to tier history limit)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-01-01T00:00:00Z"},{"name":"min_significance","in":"query","description":"Minimum significance threshold (1-5). Default: 1","required":false,"schema":{"type":"integer","minimum":1,"maximum":5,"default":1},"example":3},{"name":"category","in":"query","description":"Filter by intelligence category","required":false,"schema":{"type":"string","enum":["new-feature","deprecation","pricing-change","docs-restructure","api-change","sdk-update","model-release","security-advisory","bug-fix","content-expansion","content-reduction","formatting-only"]},"example":"new-feature"},{"name":"limit","in":"query","description":"Maximum number of results. Capped at 100. Default: 50","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"example":50}],"responses":{"200":{"description":"Intelligence reports matching the query","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed per day for the authenticated tier","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests for the current day","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate limit resets (midnight UTC)","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntelligenceResponse"},"example":{"_meta":{"service":"jadecli llms.txt intelligence","tier":"starter","count":1,"filters":{"vendor":"anthropic","since":null,"min_significance":3,"category":null,"limit":50,"history_days":90}},"intelligence":[{"id":"550e8400-e29b-41d4-a716-446655440000","vendor":{"name":"Anthropic","slug":"anthropic","domain":"platform.claude.com"},"summary":"Added new tool-use documentation section with comprehensive examples for function calling, computer use, and MCP integration","significance":4,"categories":["new-feature","api-change"],"sections_added":["Tool Use","MCP Integration"],"sections_removed":[],"sections_modified":["Getting Started","API Reference"],"key_quotes":["Tool use is now generally available","MCP servers can be connected directly"],"byte_size_change_pct":12.5,"analysis_mode":"realtime","created_at":"2026-02-28T06:00:00.000Z"}]}}}},"403":{"description":"Requires starter tier or above","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Intelligence requires starter tier or above","code":"forbidden","status":403}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Rate limit exceeded","code":"rate_limited","status":429}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Intelligence query failed","code":"internal_error","status":500}}}}}}},"/api/v1/webhooks":{"get":{"operationId":"listWebhooks","summary":"List active webhooks","description":"Returns all active webhooks for the authenticated API key. Requires pro tier.","tags":["Webhooks"],"security":[{"BearerAuth":[]}],"x-rate-limit":{"free":"Not available (403)","starter":"Not available (403)","pro":"50000 requests/day"},"responses":{"200":{"description":"List of active webhooks","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"},"example":{"_meta":{"count":1,"tier":"pro"},"webhooks":[{"id":"550e8400-e29b-41d4-a716-446655440000","url":"https://example.com/webhook/llms-feed","events":["intelligence.high_significance"],"active":true,"created_at":"2026-02-15T10:00:00.000Z","updated_at":"2026-02-15T10:00:00.000Z"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Authentication required. Provide a valid Bearer token.","code":"unauthorized","status":401}}}},"403":{"description":"Requires pro tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Webhooks require pro tier","code":"forbidden","status":403}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Failed to list webhooks","code":"internal_error","status":500}}}}}},"post":{"operationId":"createWebhook","summary":"Register a new webhook","description":"Creates a new webhook endpoint. The signing secret is returned only once at creation time -- store it securely. Requires pro tier.","tags":["Webhooks"],"security":[{"BearerAuth":[]}],"x-rate-limit":{"pro":"50000 requests/day"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateRequest"},"example":{"url":"https://example.com/webhook/llms-feed","events":["intelligence.high_significance"]}}}},"responses":{"201":{"description":"Webhook created. Secret is only returned once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateResponse"},"example":{"webhook":{"id":"550e8400-e29b-41d4-a716-446655440000","url":"https://example.com/webhook/llms-feed","events":["intelligence.high_significance"],"active":true,"created_at":"2026-03-01T12:00:00.000Z"},"secret":"whsec_aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789ABCD"}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Invalid or missing webhook URL. Must be http:// or https://","code":"bad_request","status":400}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Authentication required. Provide a valid Bearer token.","code":"unauthorized","status":401}}}},"403":{"description":"Requires pro tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Webhooks require pro tier","code":"forbidden","status":403}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Failed to create webhook","code":"internal_error","status":500}}}}}},"delete":{"operationId":"deleteWebhook","summary":"Deactivate a webhook","description":"Soft-deletes a webhook by setting it to inactive. The webhook ID is passed as a query parameter. Requires pro tier.","tags":["Webhooks"],"security":[{"BearerAuth":[]}],"x-rate-limit":{"pro":"50000 requests/day"},"parameters":[{"name":"id","in":"query","required":true,"description":"UUID of the webhook to deactivate","schema":{"type":"string","format":"uuid"},"example":"550e8400-e29b-41d4-a716-446655440000"}],"responses":{"200":{"description":"Webhook deactivated","content":{"application/json":{"schema":{"type":"object","properties":{"deactivated":{"type":"boolean","example":true},"id":{"type":"string","format":"uuid"}},"required":["deactivated","id"]},"example":{"deactivated":true,"id":"550e8400-e29b-41d4-a716-446655440000"}}}},"400":{"description":"Missing webhook id parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Missing webhook id parameter","code":"bad_request","status":400}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Authentication required. Provide a valid Bearer token.","code":"unauthorized","status":401}}}},"403":{"description":"Requires pro tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Webhooks require pro tier","code":"forbidden","status":403}}}},"404":{"description":"Webhook not found or already deactivated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Webhook not found or already deactivated","code":"not_found","status":404}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Failed to deactivate webhook","code":"internal_error","status":500}}}}}}},"/api/v1/keys/rotate":{"post":{"operationId":"rotateApiKey","summary":"Rotate API key","description":"Generates a new API key and invalidates the current one. The new plaintext key is returned once and cannot be retrieved again. Optionally keeps the old key valid for 24 hours with ?grace=true.","tags":["Keys"],"security":[{"BearerAuth":[]}],"x-rate-limit":{"starter":"5000 requests/day","pro":"50000 requests/day"},"parameters":[{"name":"grace","in":"query","description":"If 'true', keep the old key valid for 24 hours during transition","required":false,"schema":{"type":"string","enum":["true"]},"example":"true"}],"responses":{"200":{"description":"Key rotated successfully. Store the new key securely.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyRotateResponse"},"example":{"new_key":"ltf_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678901","rotated_at":"2026-03-01T12:00:00.000Z","note":"Store this key securely. Your old key is now invalid."}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Authentication required. Provide a valid Bearer token.","code":"unauthorized","status":401}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Rate limit exceeded","code":"rate_limited","status":429}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Failed to rotate API key","code":"internal_error","status":500}}}}}}},"/api/v1/diffs/{id}":{"get":{"operationId":"getDiffById","summary":"Get diff detail by ID","description":"Returns diff metadata (lines/links added/removed) along with previous and current snapshot metadata (no full content). No authentication required.","tags":["Feed"],"parameters":[{"name":"id","in":"path","required":true,"description":"UUID of the diff","schema":{"type":"string","format":"uuid"},"example":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"}],"responses":{"200":{"description":"Diff detail with previous and current snapshot metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiffDetailResponse"},"example":{"diff":{"id":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","vendor_slug":"anthropic","lines_added":12,"lines_removed":3,"links_added":["https://docs.anthropic.com/tool-use"],"links_removed":[],"created_at":"2026-02-28T10:00:00.000Z"},"previous_snapshot":{"id":"11111111-2222-3333-4444-555555555555","byte_size":14336,"line_count":330,"fetched_at":"2026-02-27T08:00:00.000Z"},"current_snapshot":{"id":"66666666-7777-8888-9999-aaaaaaaaaaaa","byte_size":15360,"line_count":342,"fetched_at":"2026-02-28T08:00:00.000Z"}}}}},"400":{"description":"Invalid diff ID format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Invalid diff ID format","code":"bad_request","status":400}}}},"404":{"description":"Diff not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Diff not found","code":"not_found","status":404}}}}}}},"/api/v1/cron/status":{"get":{"operationId":"getCronStatus","summary":"Get cron job status","description":"Returns the latest run status for each cron job (fetch, analysis, etc.). Requires authentication (any tier).","tags":["Operations"],"security":[{"BearerAuth":[]}],"x-rate-limit":{"starter":"5000 requests/day","pro":"50000 requests/day"},"responses":{"200":{"description":"Latest status for each cron job","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronStatusResponse"},"example":{"jobs":[{"name":"fetch-llms-txt","last_run_at":"2026-03-01T06:00:00.000Z","finished_at":"2026-03-01T06:05:23.000Z","status":"completed","summary":{"total":334,"changed":5,"errors":2,"not_modified":312},"error":null},{"name":"intelligence-batch","last_run_at":"2026-03-01T07:00:00.000Z","finished_at":"2026-03-01T07:12:45.000Z","status":"completed","summary":{"analyzed":5,"skipped":0},"error":null}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Authentication required","code":"unauthorized","status":401}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Rate limit exceeded","code":"rate_limited","status":429}}}}}}},"/api/v1/stripe/checkout":{"post":{"operationId":"createCheckoutSession","summary":"Create a Stripe checkout session","description":"Creates a Stripe checkout session for subscribing to a paid tier. Returns a redirect URL to Stripe's hosted checkout page.","tags":["Billing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"},"example":{"tier":"starter"}}}},"responses":{"200":{"description":"Checkout session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"},"example":{"url":"https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4e5f6"}}}},"400":{"description":"Invalid tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Invalid tier. Must be starter or pro.","code":"bad_request","status":400}}}},"500":{"description":"Checkout session creation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Failed to create checkout session","code":"internal_error","status":500}}}}}}}},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key passed as a Bearer token. Keys are prefixed with `ltf_`. Requests without an API key receive free-tier access (100 requests/day, limited features)."}},"schemas":{"ErrorResponse":{"type":"object","description":"Standard error response returned by all endpoints on failure","properties":{"error":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Machine-readable error code (e.g. not_found, unauthorized, rate_limited, bad_request, forbidden, internal_error)"},"status":{"type":"integer","description":"HTTP status code"}},"required":["error","code","status"],"example":{"error":"Vendor not found","code":"not_found","status":404}},"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["ok"],"description":"Service status"},"version":{"type":"string","description":"Application version from package.json"},"timestamp":{"type":"string","format":"date-time","description":"Current server time in ISO 8601"},"db_connected":{"type":"boolean","description":"Whether the database is reachable"}},"required":["status","version","timestamp","db_connected"]},"VendorSummary":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"category":{"$ref":"#/components/schemas/VendorCategory"}},"required":["name","slug","domain","category"]},"VendorCategory":{"type":"string","enum":["ai-platform","developer-tools","database","payments","cloud","data-analytics","integration","security"]},"SnapshotMeta":{"type":"object","properties":{"content_hash":{"type":"string","description":"SHA-256 hash of the content"},"byte_size":{"type":"integer","description":"Content size in bytes"},"line_count":{"type":"integer","description":"Number of lines in the content"},"link_count":{"type":"integer","description":"Number of URLs found in the content"},"fetched_at":{"type":"string","format":"date-time","description":"When the content was last fetched"}},"required":["content_hash","byte_size","line_count","link_count","fetched_at"]},"RecentChange":{"type":"object","nullable":true,"properties":{"lines_added":{"type":"integer"},"lines_removed":{"type":"integer"},"detected_at":{"type":"string","format":"date-time"}},"required":["lines_added","lines_removed","detected_at"]},"DiffContent":{"type":"object","nullable":true,"description":"Full diff content (starter/pro tiers only)","properties":{"lines_added":{"type":"integer"},"lines_removed":{"type":"integer"},"diff_text":{"type":"string","description":"Unified-style diff text with +/- prefixed lines"},"created_at":{"type":"string","format":"date-time"}},"required":["lines_added","lines_removed","diff_text","created_at"]},"FeedEntry":{"type":"object","properties":{"vendor":{"$ref":"#/components/schemas/VendorSummary"},"latest":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/SnapshotMeta"}]},"recent_change":{"$ref":"#/components/schemas/RecentChange"},"diff_content":{"$ref":"#/components/schemas/DiffContent"}},"required":["vendor","latest","recent_change"]},"CursorPaginationMeta":{"type":"object","description":"Cursor-based pagination metadata. Used by /api/v1/feed. To paginate, pass the `next_cursor` value as the `cursor` query parameter in the next request. When `has_more` is false, there are no more pages.","properties":{"count":{"type":"integer","description":"Number of items in this page"},"next_cursor":{"type":"string","format":"uuid","nullable":true,"description":"Pass as ?cursor= to fetch the next page. Null when no more pages."},"has_more":{"type":"boolean","description":"True when more pages are available"}},"required":["count","has_more"]},"OffsetPaginationMeta":{"type":"object","description":"Offset-based pagination metadata. Used by /api/v1/vendors/search and other list endpoints. Increment `offset` by `limit` to fetch the next page.","properties":{"count":{"type":"integer","description":"Number of items in this page"},"limit":{"type":"integer","description":"Maximum items per page"},"offset":{"type":"integer","description":"Number of items skipped"}},"required":["count","limit"]},"FeedResponse":{"type":"object","properties":{"_meta":{"type":"object","description":"Response metadata including cursor-based pagination info","properties":{"service":{"type":"string"},"version":{"type":"string"},"count":{"type":"integer","description":"Number of items in this page"},"next_cursor":{"type":"string","format":"uuid","nullable":true,"description":"Pass as ?cursor= to fetch the next page. Null when no more pages."},"has_more":{"type":"boolean","description":"True when more pages are available"},"vendor_count":{"type":"integer"},"tier":{"$ref":"#/components/schemas/PricingTier"},"updated_at":{"type":"string","format":"date-time"}},"required":["service","version","count","has_more","vendor_count","tier","updated_at"]},"feed":{"type":"array","items":{"$ref":"#/components/schemas/FeedEntry"}}},"required":["_meta","feed"]},"VendorListItem":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"category":{"$ref":"#/components/schemas/VendorCategory"},"latest":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/SnapshotMeta"}]}},"required":["name","slug","domain","category","latest"]},"VendorListResponse":{"type":"object","properties":{"count":{"type":"integer"},"vendors":{"type":"array","items":{"$ref":"#/components/schemas/VendorListItem"}}},"required":["count","vendors"]},"VendorSearchFilters":{"type":"object","properties":{"q":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"status":{"type":"string"},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["status","limit","offset"]},"VendorSearchItem":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"category":{"$ref":"#/components/schemas/VendorCategory"},"status":{"type":"string","enum":["active","paused","unreachable"]}},"required":["name","slug","domain","category","status"]},"VendorSearchResponse":{"type":"object","properties":{"_meta":{"type":"object","description":"Response metadata including offset-based pagination info","properties":{"count":{"type":"integer","description":"Number of items in this page"},"filters":{"$ref":"#/components/schemas/VendorSearchFilters"}},"required":["count","filters"]},"vendors":{"type":"array","items":{"$ref":"#/components/schemas/VendorSearchItem"}}},"required":["_meta","vendors"]},"VendorDetail":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"category":{"$ref":"#/components/schemas/VendorCategory"},"status":{"type":"string","enum":["active","paused","unreachable"]},"llms_txt_url":{"type":"string","format":"uri"},"llms_full_txt_url":{"type":"string","format":"uri","nullable":true}},"required":["name","slug","domain","category","status","llms_txt_url"]},"SnapshotDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content_hash":{"type":"string"},"byte_size":{"type":"integer"},"line_count":{"type":"integer"},"link_count":{"type":"integer"},"fetched_at":{"type":"string","format":"date-time"},"http_status":{"type":"integer"},"response_time_ms":{"type":"integer"},"security_score":{"type":"integer","description":"0-5 security risk score (0 = safe, >= 3 = blocked)"}},"required":["id","content_hash","byte_size","line_count","link_count","fetched_at","http_status","response_time_ms","security_score"]},"DiffDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"previous_snapshot_id":{"type":"string","format":"uuid"},"current_snapshot_id":{"type":"string","format":"uuid"},"lines_added":{"type":"integer"},"lines_removed":{"type":"integer"},"links_added":{"type":"array","items":{"type":"string"}},"links_removed":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"}},"required":["id","previous_snapshot_id","current_snapshot_id","lines_added","lines_removed","links_added","links_removed","created_at"]},"VendorDetailResponse":{"type":"object","properties":{"vendor":{"$ref":"#/components/schemas/VendorDetail"},"snapshots":{"type":"array","items":{"$ref":"#/components/schemas/SnapshotDetail"},"description":"Last 10 snapshots (metadata only, no content)"},"diffs":{"type":"array","items":{"$ref":"#/components/schemas/DiffDetail"},"description":"Last 10 diffs"}},"required":["vendor","snapshots","diffs"]},"VendorContentResponse":{"type":"object","properties":{"content":{"type":"string","description":"Raw llms.txt content"},"metadata":{"type":"object","properties":{"content_hash":{"type":"string"},"byte_size":{"type":"integer"},"line_count":{"type":"integer"},"link_count":{"type":"integer"},"fetched_at":{"type":"string","format":"date-time"}},"required":["content_hash","byte_size","line_count","link_count","fetched_at"]}},"required":["content","metadata"]},"StatsResponse":{"type":"object","properties":{"vendors":{"type":"integer","description":"Number of active vendors"},"snapshots":{"type":"integer","description":"Total snapshots stored"},"diffs":{"type":"integer","description":"Total diffs computed"},"total_bytes_tracked":{"type":"integer","description":"Sum of all snapshot byte sizes"},"category_breakdown":{"type":"object","description":"Vendor count per category","additionalProperties":{"type":"integer"}},"status_breakdown":{"type":"object","description":"Vendor count per status","additionalProperties":{"type":"integer"}}},"required":["vendors","snapshots","diffs","total_bytes_tracked","category_breakdown","status_breakdown"]},"PricingTier":{"type":"string","enum":["free","starter","pro"]},"PricingConfig":{"type":"object","properties":{"tier":{"$ref":"#/components/schemas/PricingTier"},"monthly_price_usd":{"type":"number"},"requests_per_day":{"type":"integer","description":"Daily rate limit for this tier"},"vendor_access":{"type":"string","enum":["public-5","all","all-plus-custom"]},"history_days":{"type":"integer","description":"Number of days of history accessible"},"diff_access":{"type":"boolean","description":"Whether diff content is included in feed responses"},"api_access":{"type":"boolean","description":"Whether raw content API is accessible"},"webhooks":{"type":"boolean","description":"Whether webhook registration is available"}},"required":["tier","monthly_price_usd","requests_per_day","vendor_access","history_days","diff_access","api_access","webhooks"]},"PricingResponse":{"type":"object","properties":{"free":{"$ref":"#/components/schemas/PricingConfig"},"starter":{"$ref":"#/components/schemas/PricingConfig"},"pro":{"$ref":"#/components/schemas/PricingConfig"}},"required":["free","starter","pro"]},"IntelligenceCategory":{"type":"string","enum":["new-feature","deprecation","pricing-change","docs-restructure","api-change","sdk-update","model-release","security-advisory","bug-fix","content-expansion","content-reduction","formatting-only"]},"IntelligenceReport":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vendor":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"}},"required":["name","slug","domain"]},"summary":{"type":"string","description":"Human-readable change description generated by Claude"},"significance":{"type":"integer","minimum":1,"maximum":5,"description":"1 (trivial formatting) to 5 (breaking API change)"},"categories":{"type":"array","items":{"$ref":"#/components/schemas/IntelligenceCategory"},"description":"Classified change types"},"sections_added":{"type":"array","items":{"type":"string"},"description":"New documentation sections"},"sections_removed":{"type":"array","items":{"type":"string"},"description":"Removed documentation sections"},"sections_modified":{"type":"array","items":{"type":"string"},"description":"Modified documentation sections"},"key_quotes":{"type":"array","items":{"type":"string"},"description":"Notable quotes from the changed content"},"byte_size_change_pct":{"type":"number","description":"Percentage change in byte size"},"analysis_mode":{"type":"string","enum":["realtime","batch"],"description":"Whether analysis was done in real-time or via batch cron"},"created_at":{"type":"string","format":"date-time"}},"required":["id","vendor","summary","significance","categories","sections_added","sections_removed","sections_modified","key_quotes","byte_size_change_pct","analysis_mode","created_at"]},"IntelligenceResponse":{"type":"object","properties":{"_meta":{"type":"object","properties":{"service":{"type":"string"},"tier":{"$ref":"#/components/schemas/PricingTier"},"count":{"type":"integer"},"filters":{"type":"object","properties":{"vendor":{"type":"string","nullable":true},"since":{"type":"string","nullable":true},"min_significance":{"type":"integer"},"category":{"type":"string","nullable":true},"limit":{"type":"integer"},"history_days":{"type":"integer","nullable":true,"description":"Tier-based history limit in days (null for pro = unlimited)"}}}},"required":["service","tier","count","filters"]},"intelligence":{"type":"array","items":{"$ref":"#/components/schemas/IntelligenceReport"}}},"required":["_meta","intelligence"]},"WebhookEventType":{"type":"string","enum":["intelligence.high_significance"]},"Webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","url","events","active","created_at","updated_at"]},"WebhookListResponse":{"type":"object","properties":{"_meta":{"type":"object","properties":{"count":{"type":"integer"},"tier":{"$ref":"#/components/schemas/PricingTier"}},"required":["count","tier"]},"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}},"required":["_meta","webhooks"]},"WebhookCreateRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"HTTPS endpoint to receive webhook payloads"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"},"minItems":1,"description":"Event types to subscribe to. Currently only 'intelligence.high_significance' is available."}},"required":["url","events"]},"WebhookCreateResponse":{"type":"object","properties":{"webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}},"required":["id","url","events","active","created_at"]},"secret":{"type":"string","description":"Webhook signing secret prefixed with 'whsec_'. Only returned once at creation time -- store securely."}},"required":["webhook","secret"]},"KeyRotateResponse":{"type":"object","properties":{"new_key":{"type":"string","description":"The new API key prefixed with 'ltf_' (only shown once)"},"rotated_at":{"type":"string","format":"date-time","description":"Timestamp of the rotation"},"note":{"type":"string","description":"Security reminder to store the key"},"grace_period":{"type":"string","description":"Present only when ?grace=true was used. Indicates old key validity period."}},"required":["new_key","rotated_at","note"]},"CronJob":{"type":"object","properties":{"name":{"type":"string","description":"Job name (e.g. fetch-llms-txt, intelligence-batch)"},"last_run_at":{"type":"string","format":"date-time"},"finished_at":{"type":"string","format":"date-time","nullable":true},"status":{"type":"string","enum":["running","completed","failed"]},"summary":{"type":"object","nullable":true,"description":"Job-specific summary data"},"error":{"type":"string","nullable":true,"description":"Error message if status is failed"}},"required":["name","last_run_at","status"]},"CronStatusResponse":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/CronJob"}}},"required":["jobs"]},"CheckoutRequest":{"type":"object","properties":{"tier":{"type":"string","enum":["starter","pro"],"description":"Pricing tier to subscribe to"}},"required":["tier"]},"CheckoutResponse":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Stripe checkout session URL to redirect the user to"}},"required":["url"]},"DiffSnapshotMeta":{"type":"object","description":"Snapshot metadata (no content) for a diff endpoint","properties":{"id":{"type":"string","format":"uuid"},"byte_size":{"type":"integer"},"line_count":{"type":"integer"},"fetched_at":{"type":"string","format":"date-time"}},"required":["id","byte_size","line_count","fetched_at"]},"DiffDetailEndpoint":{"type":"object","description":"Diff metadata returned by GET /api/v1/diffs/:id","properties":{"id":{"type":"string","format":"uuid"},"vendor_slug":{"type":"string"},"lines_added":{"type":"integer"},"lines_removed":{"type":"integer"},"links_added":{"type":"array","items":{"type":"string","format":"uri"}},"links_removed":{"type":"array","items":{"type":"string","format":"uri"}},"created_at":{"type":"string","format":"date-time"}},"required":["id","vendor_slug","lines_added","lines_removed","links_added","links_removed","created_at"]},"DiffDetailResponse":{"type":"object","properties":{"diff":{"$ref":"#/components/schemas/DiffDetailEndpoint"},"previous_snapshot":{"$ref":"#/components/schemas/DiffSnapshotMeta"},"current_snapshot":{"$ref":"#/components/schemas/DiffSnapshotMeta"}},"required":["diff","previous_snapshot","current_snapshot"]},"RateLimitInfo":{"type":"object","description":"Rate limiting information. All authenticated responses include X-RateLimit-* headers.","properties":{"headers":{"type":"object","properties":{"X-RateLimit-Limit":{"type":"integer","description":"Maximum requests allowed per day for the authenticated tier"},"X-RateLimit-Remaining":{"type":"integer","description":"Remaining requests for the current day"},"X-RateLimit-Reset":{"type":"integer","description":"Unix timestamp (seconds) when the rate limit resets (midnight UTC)"}}},"tiers":{"type":"object","properties":{"free":{"type":"integer","description":"100 requests per day","example":100},"starter":{"type":"integer","description":"5,000 requests per day","example":5000},"pro":{"type":"integer","description":"50,000 requests per day","example":50000}}}}}}}}