{"openapi":"3.0.3","info":{"title":"Paranor Agent API","description":"Structured content for AI agents: unified index (articles, episodes, streams, video, timeline), profile, booking, media kit, speaking. Rate-limited endpoints (e.g. guest-kit, MCP call, transcription, L402 payment-request) return X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset on every response; 429 responses include Retry-After. See agent-api and REFACTOR_FUTURE_READINESS for the full contract.","version":"0.1.0"},"servers":[{"url":"https://api.paranor.app"}],"paths":{"/api/agent":{"get":{"summary":"API index (discovery)","description":"Lists all endpoints, version, changelogUrl, docsUrl, statusUrl, events. Use HEAD or GET as health check. When rate limiting is enforced, the response may optionally include rateLimitPerMinute and quotaRemaining (PPB 79) so agents discover policy from the index. All Agent API responses include X-Paranor-API-Version (same as index version) and X-Request-Id (echo or generated). Supports conditional GET: response includes ETag and Last-Modified; send If-None-Match or If-Modified-Since for 304 when unchanged.","responses":{"200":{"description":"API index with endpoints and version. May include optional rateLimitPerMinute and quotaRemaining when rate limiting is in effect.","headers":{"X-Paranor-API-Version":{"schema":{"type":"string"},"description":"API version (same as body.version)"},"X-Request-Id":{"schema":{"type":"string"},"description":"Request correlation ID (echoed from request or generated)"},"ETag":{"schema":{"type":"string"},"description":"Opaque validator for conditional GET; send If-None-Match with this value for 304"},"Last-Modified":{"schema":{"type":"string"},"description":"HTTP-date; send If-Modified-Since for 304"}},"content":{"application/json":{"schema":{"type":"object","required":["name","description","version","endpoints","events"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"version":{"type":"string"},"docsUrl":{"type":"string","format":"uri"},"statusUrl":{"type":"string","format":"uri","description":"Canonical status page URL (subdomain-ready via env)."},"openApiUrl":{"type":"string","format":"uri"},"changelogUrl":{"type":"string","format":"uri"},"rateLimitPerMinute":{"type":"integer","minimum":0,"description":"Optional policy hint when rate limiting is enforced."},"quotaRemaining":{"type":"integer","minimum":0,"description":"Optional quota hint when quotas are enforced."},"events":{"type":"array","items":{"type":"object","required":["id","description"],"properties":{"id":{"type":"string","enum":["dot.approved","content.published","guest_kit.generated","changelog.updated","content_index.digest"]},"description":{"type":"string"}}}},"endpoints":{"type":"object"}}}}}},"304":{"description":"Not Modified (when If-None-Match or If-Modified-Since matches); empty body"}},"parameters":[{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"},"description":"ETag from previous 200; server returns 304 when unchanged"},{"name":"If-Modified-Since","in":"header","required":false,"schema":{"type":"string"},"description":"HTTP-date from previous Last-Modified; server returns 304 when unchanged"}]}},"/api/agent/discovery-bundle":{"get":{"summary":"Discovery bundle (single-call bootstrap)","description":"Returns links (llmsTxt, agentCard, apiIndex, openApi, changelog, nexus), version, capabilities, docsUrl, statusUrl, fallbackDocsUrl, fallbackStatusUrl, landingPayloadUrl, and optional l402 info. Use when you want one request to bootstrap instead of llms.txt + Agent Card + index. Always free; no auth. See agent-api Discovery section.","responses":{"200":{"description":"Discovery bundle with links, version, capabilities, landingPayloadUrl","content":{"application/json":{"schema":{"type":"object"},"example":{"version":"0.1.0","links":{"llmsTxt":"https://api.paranor.app/llms.txt","apiIndex":"https://api.paranor.app/api/agent","openApi":"https://api.paranor.app/api/agent/openapi.json"},"capabilities":["mcp.v1","webhooks.v1"],"docsUrl":"https://api.paranor.app/docs","statusUrl":"https://api.paranor.app/status","landingPayloadUrl":"https://api.paranor.app/api/landing-payload"}}}}}}},"/api/agent/negotiate":{"post":{"summary":"Capability negotiation","description":"Send { capabilities: [\"mcp.v1\", \"sandbox.v1\", ...] } (your supported protocols). Response includes serverCapabilities, clientCapabilities, compatible, unsupported, and recommendation (array of { flow, endpoints, note } with best-fit integration guidance). Always free; no auth. See agent-api Discovery section.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"capabilities":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Negotiation result with recommendation","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/landing-payload":{"get":{"summary":"Landing payload","description":"Machine-readable JSON for product landing: hero (heading, subheading), ctas (label, href, primary), discoveryLinks (llmsTxt, agentsMd, agent, apiAgent, nexusCreators, docs, status). Use for agent bootstrap without HTML parsing. Always free; no auth. See agent-api Discovery section.","responses":{"200":{"description":"Landing payload with hero, ctas, discoveryLinks","content":{"application/json":{"schema":{"type":"object"},"example":{"hero":{"heading":"One Index. One API.","subheading":"Be discoverable by shows and AI."},"ctas":[{"label":"Discover Creators","href":"https://api.paranor.app/nexus","primary":true}],"discoveryLinks":{"llmsTxt":"https://api.paranor.app/llms.txt","agent":"https://api.paranor.app/agent","apiAgent":"https://api.paranor.app/api/agent","docs":"https://api.paranor.app/docs","status":"https://api.paranor.app/status"}}}}}}}},"/api/agent/health":{"get":{"summary":"Health check","description":"Lightweight availability check. Returns 200 with version and status. No auth; always free. Use before discovery workflows. Response includes X-Paranor-API-Version and X-Request-Id.","responses":{"200":{"description":"Service operational","headers":{"X-Paranor-API-Version":{"schema":{"type":"string"},"description":"API version (matches index)"},"X-Request-Id":{"schema":{"type":"string"},"description":"Request correlation ID"}},"content":{"application/json":{"schema":{"type":"object","required":["version","status"],"properties":{"version":{"type":"string","description":"API version (matches index)"},"status":{"type":"string","enum":["operational"],"description":"Service status"}}}}}}}}},"/api/agent/widget":{"get":{"summary":"Meta-only discovery widget snippets","description":"Returns copyable link and JSON-LD snippets for embedding agent discovery metadata on external websites.","responses":{"200":{"description":"Widget metadata and snippets","content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["meta-only"]},"baseUrl":{"type":"string","format":"uri"},"snippets":{"type":"object","properties":{"htmlMetaLinks":{"type":"string"},"jsonLd":{"type":"string"},"markdown":{"type":"string"}}}}}}}}}}},"/api/agent/profile":{"get":{"summary":"Creator profile","description":"Name, bio, topics, content index URL, stats (e.g. totalApiCalls30d), indexUpdatedAt, links, and optional Nostr config (`nostrIdentity`, `nostr`). Use stats and indexUpdatedAt for freshness checks. May include stats.agentOriginCalls30d when agent-origin logging is enabled; agents can self-identify via header X-Paranor-Source: agent for attribution. Supports conditional GET: response includes ETag and Last-Modified; send If-None-Match or If-Modified-Since for 304 when unchanged. Sandbox: ?sandbox=1 or X-Paranor-Sandbox: true returns deterministic mock with _sandbox: true (PPB 128).","parameters":[{"name":"sandbox","in":"query","required":false,"schema":{"type":"string","enum":["1","true"]},"description":"Return mock profile with _sandbox: true; no live data (PPB 128). Header X-Paranor-Sandbox: true equivalent."},{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"},"description":"ETag from previous 200; server returns 304 when unchanged"},{"name":"If-Modified-Since","in":"header","required":false,"schema":{"type":"string"},"description":"HTTP-date from previous Last-Modified; server returns 304 when unchanged"}],"responses":{"200":{"description":"Creator profile JSON","headers":{"ETag":{"schema":{"type":"string"},"description":"Opaque validator for conditional GET"},"Last-Modified":{"schema":{"type":"string"},"description":"HTTP-date"}}},"304":{"description":"Not Modified (when If-None-Match or If-Modified-Since matches)"}}}},"/api/agent/content-index":{"get":{"summary":"Unified content index","description":"All content in one list. Optional: ?type=, ?types=, ?dateFrom=, ?dateTo=, ?tag=, ?topic=, ?digest=7d|30d, ?count=true, ?limit= (max 1000), ?offset=, ?format=json|ndjson. Sandbox: ?sandbox=1 or X-Paranor-Sandbox: true returns deterministic mock items for agent testing (no L402, no live data). When items/count is 0, optional emptyReason. Part of pitch-match flow (PPB 109): use ?tag=/?topic= with GET /api/agent/booking and POST /api/agent/booking-request for theme-based creator discovery and outreach. x-paranor-flow: Thematic Newsletter Curator Agent — digest → content-index?topic= → shortlist → booking-request (see REFACTOR_FUTURE_READINESS \"Thematic Newsletter Curator Agent\" and agent-api). Response headers: ETag, Last-Modified, X-Content-Index-Max-Limit (1000). Conditional GET (304 when unchanged).","parameters":[{"name":"tag","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by theme or keyword (matches themeIds/keywords, case-insensitive)"},{"name":"topic","in":"query","required":false,"schema":{"type":"string"},"description":"Alias for tag; filter by theme or keyword (matches themeIds/keywords, case-insensitive)"},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["json","ndjson"]},"description":"Response format. ndjson streams one JSON object per line for bundle consumption."},{"name":"sandbox","in":"query","required":false,"schema":{"type":"string","enum":["1","true"]},"description":"Return deterministic mock items with _sandbox: true (PPB 76, 128). Header X-Paranor-Sandbox: true equivalent."},{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"},"description":"ETag from previous 200; server returns 304 when unchanged"},{"name":"If-Modified-Since","in":"header","required":false,"schema":{"type":"string"},"description":"HTTP-date from previous Last-Modified; server returns 304 when unchanged"}],"responses":{"200":{"description":"Content index (or count). When items/count is 0, may include emptyReason. With sandbox=1, returns mock items with _sandbox: true.","headers":{"ETag":{"schema":{"type":"string"},"description":"Opaque validator for conditional GET"},"Last-Modified":{"schema":{"type":"string"},"description":"HTTP-date"},"X-Content-Index-Max-Limit":{"schema":{"type":"integer"},"description":"Max limit per request (e.g. 1000)"}},"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"},"url":{"type":"string"},"date":{"type":"string","description":"YYYY-MM-DD"},"lastModified":{"type":"string","description":"HTTP-date per item for If-Modified-Since; enables sync use cases"},"engagementScore":{"type":"number","description":"Optional likes+restacks score when analytics visibility is enabled"},"socialLinks":{"type":"array","description":"Optional post-publish links for article items","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"url":{"type":"string","format":"uri"},"sortOrder":{"type":"number"}}}}}},"description":"Each item may include lastModified (HTTP-date) for conditional GET and sync."},"count":{"type":"number"},"total":{"type":"number"},"emptyReason":{"type":"string","enum":["index_empty","filter","l402_required","per_surface_visibility"],"description":"Present when items/count is 0; explains why."},"syndicationRights":{"type":"object","description":"When creator has syndication enabled (PPB 122): available, attribution, terms, l402Required.","properties":{"available":{"type":"boolean"},"attribution":{"type":"string"},"terms":{"type":"string"},"l402Required":{"type":"boolean"}}}}},"example":{"count":0,"items":[],"publication":"Example Publication","authorName":"Example Creator","contentIndexUrl":"https://api.paranor.app/api/agent/content-index","emptyReason":"index_empty"}}}},"304":{"description":"Not Modified (when If-None-Match or If-Modified-Since matches)"}}}},"/api/agent/content-index/bundle":{"get":{"summary":"NDJSON bundle alias for content-index","description":"Convenience route for bundle exports. Equivalent to GET /api/agent/content-index?format=ndjson with the same filters and limits.","responses":{"200":{"description":"NDJSON content stream (one JSON object per line)"}}}},"/api/agent/booking":{"get":{"summary":"Booking info","description":"Topics, sample questions, links for show producers. Response includes sampleQuestions (array) and links.bookingRequest (URL for POST). Part of the Automated PR & Booking Agent use case: discover from index → booking/speaking for fit → media-kit → content-index for pre-brief → POST /api/agent/booking-request. See agent-api (docsUrl) for full flow. Sandbox: ?sandbox=1 or X-Paranor-Sandbox: true returns mock with _sandbox: true (PPB 128).","parameters":[{"name":"sandbox","in":"query","required":false,"schema":{"type":"string","enum":["1","true"]},"description":"Return mock booking with _sandbox: true (PPB 128). Header X-Paranor-Sandbox: true equivalent."}],"responses":{"200":{"description":"Booking info with sampleQuestions and links.bookingRequest","content":{"application/json":{"schema":{"type":"object","properties":{"sampleQuestions":{"type":"array","items":{"type":"string"},"description":"Sample interview questions for show producers"},"topics":{"type":"array","items":{"type":"string"},"description":"Topic/expertise hints for pitch-match; use with content-index ?topic= to shortlist creators by theme (PPB 178)"},"links":{"type":"object","properties":{"bookingRequest":{"type":"string","format":"uri","description":"URL for POST /api/agent/booking-request"}}}}}}}}}}},"/api/agent/show-prep":{"get":{"summary":"Show prep briefing pack","description":"Deterministic briefing payload composed from profile + content index for producers and agent workflows.","parameters":[{"name":"showUrl","in":"query","required":true,"schema":{"type":"string","format":"uri"},"description":"Producer/show URL requesting the briefing pack."},{"name":"topic","in":"query","required":false,"schema":{"type":"string"},"description":"Optional topic filter applied to content-index matching."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":25},"description":"Max number of top Dots to include (default 8)."}],"responses":{"200":{"description":"Show-prep briefing payload"},"400":{"description":"Missing/invalid showUrl","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/agent/media-kit":{"get":{"summary":"Media kit","description":"Approved copy, blurbs, stats. Add ?format=pdf for PDF. Sandbox: ?sandbox=1 or X-Paranor-Sandbox: true returns mock with _sandbox: true (PPB 128).","parameters":[{"name":"sandbox","in":"query","required":false,"schema":{"type":"string","enum":["1","true"]},"description":"Return mock media-kit with _sandbox: true (PPB 128)."}]}},"/api/agent/speaking":{"get":{"summary":"Speaking profile","description":"Bio, topics, past talks. Add ?format=pdf for one-sheet. Sandbox: ?sandbox=1 or X-Paranor-Sandbox: true returns mock with _sandbox: true (PPB 128).","parameters":[{"name":"sandbox","in":"query","required":false,"schema":{"type":"string","enum":["1","true"]},"description":"Return mock speaking with _sandbox: true (PPB 128)."}]}},"/api/agent/changelog":{"get":{"summary":"Changelog","description":"Machine-readable changelog. Response: version, changelogUrl, entries (date, summary, changes, optional breaking, optional capabilities). When an entry has capabilities, it describes a capability change; agents can compare and re-call POST /api/agent/negotiate if needed (PPB 168). Supports conditional GET: ETag and Last-Modified; send If-None-Match or If-Modified-Since for 304 when unchanged.","responses":{"200":{"description":"Changelog with version, changelogUrl, entries","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string"},"changelogUrl":{"type":"string","format":"uri"},"entries":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","description":"YYYY-MM-DD"},"summary":{"type":"string"},"changes":{"type":"array","items":{"type":"string"}},"breaking":{"type":"boolean","description":"Optional; when true, entry describes breaking changes"},"capabilities":{"type":"array","items":{"type":"string"},"description":"Optional; when present, entry describes capability change (e.g. l402.v1); agents should re-negotiate if differing from known capabilities"}}}}}}}}}}}},"/api/agent/articles":{"get":{"summary":"Dots list","description":"All articles with metadata. Pagination: ?limit=, ?offset=."}},"/api/agent/articles/{id}":{"get":{"summary":"Article detail","description":"Single article by id."}},"/api/agent/timeline-entries":{"get":{"summary":"Timeline entries","description":"Event timeline entries."}},"/api/agent/episodes":{"get":{"summary":"Episodes","description":"Podcast/RSS episodes."}},"/api/agent/stream-videos":{"get":{"summary":"Streams & video","description":"Stream and video entries."}},"/api/agent/transcribe":{"post":{"summary":"Transcribe remote audio/video URL","description":"Body: { sourceUrl: string }. L402-gated when enabled; rate-limited with X-RateLimit-* headers.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sourceUrl"],"properties":{"sourceUrl":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Transcription completed"},"400":{"description":"Invalid sourceUrl","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"$ref":"#/components/responses/RateLimit429"},"500":{"description":"Provider or network failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/agent/webhook-subscribe":{"post":{"summary":"Subscribe to webhook events","description":"Submit callbackUrl (HTTPS) and events (from API index events array). Creator approves in Paranor → Intelligence. For content_index.digest, include digestSchedule and digestWindow; payload shape see schema ContentIndexDigestPayload.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["callbackUrl","events"],"properties":{"callbackUrl":{"type":"string","format":"uri","description":"HTTPS URL for event payloads"},"events":{"type":"array","items":{"type":"string","enum":["dot.approved","content.published","guest_kit.generated","changelog.updated","content_index.digest"]}},"digestSchedule":{"type":"string","enum":["daily","weekly"],"description":"Optional: request scheduled content digest delivery (content_index.digest event)"},"digestWindow":{"type":"string","enum":["7d","30d"],"description":"Optional: time window for digest content; use with digestSchedule"}}},"examples":{"minimal":{"summary":"Minimal (dot.approved)","value":{"callbackUrl":"https://your-server.com/webhook","events":["dot.approved"]}},"withDigest":{"summary":"With content_index.digest","value":{"callbackUrl":"https://your-server.com/webhook","events":["content_index.digest"],"digestSchedule":"weekly","digestWindow":"7d"}}}}}},"responses":{"200":{"description":"Subscription created","content":{"application/json":{"schema":{"type":"object","properties":{"subscriptionId":{"type":"string"},"status":{"type":"string","enum":["pending","approved","rejected"]}}}}}},"400":{"description":"Invalid body (e.g. missing callbackUrl or events)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"},"example":{"error":{"code":"bad_request","message":"callbackUrl and events are required","details":{"field":"body"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/agent/booking-request":{"post":{"summary":"Submit a booking request","description":"Agents or humans submit show name and optional details. Creator sees requests in Paranor → Intelligence. Part of PR/booking and auto-curation flows (see agent-api use cases). x-paranor-flow: Thematic Newsletter Curator Agent — digest → content-index?topic= → shortlist → booking-request (see REFACTOR_FUTURE_READINESS \"Thematic Newsletter Curator Agent\" and agent-api).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["showName"],"properties":{"showName":{"type":"string"},"showUrl":{"type":"string","format":"uri"},"timeframe":{"type":"string"},"message":{"type":"string"},"source":{"type":"string","enum":["agent","human"],"default":"human"}}},"example":{"showName":"My Podcast","showUrl":"https://example.com/podcast","source":"human"}}}},"responses":{"200":{"description":"Request created","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string"},"status":{"type":"string"}}}}}},"400":{"description":"Invalid body (e.g. missing showName)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"},"example":{"error":{"code":"bad_request","message":"showName is required","details":{"field":"body"}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/agent/register-agent-tier":{"post":{"summary":"Register for Agent tier (free slice)","description":"Agents that cannot pay register with metadata (name, purpose, whyNoPayment). Returns free slice: count + first N items; rate limit; enticement to upgrade. When L402 is enabled, 402 on paywalled resources may include tiers; choose pay_or_work and use work-offer/work-submit for task-for-access. x-paranor-flow: Phase 1 Agent tier.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Agent or client name"},"purpose":{"type":"string","description":"Why the agent needs access"},"whyNoPayment":{"type":"string","description":"Optional; why agent cannot pay"}}}}}},"responses":{"200":{"description":"Registration accepted; free slice and rate limit apply"},"400":{"description":"Invalid body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/agent/work-offer":{"post":{"summary":"Request a work-for-access task (Pay-or-Work)","description":"When 402 response includes pay_or_work tier, POST with resourceId (and optional paymentContextToken, articleId) to receive a verifiable micro-task. Complete the task and POST to work-submit to receive the same access token as payment. Task types: label_classify, summarize, match, micro_survey. x-paranor-flow: Phase 2 Pay-or-Work.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["resourceId"],"properties":{"resourceId":{"type":"string","description":"Resource that requires access (e.g. content-index)"},"paymentContextToken":{"type":"string","description":"Optional; from 402 if provided"},"articleId":{"type":"string","description":"Optional; for article-scoped tasks"}}}}}},"responses":{"200":{"description":"Task spec with taskId, type, description, submitUrl"},"400":{"description":"Invalid or missing resourceId","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"402":{"description":"Payment or work required; 402 body may include tiers"}}}},"/api/agent/work-submit":{"post":{"summary":"Submit work-for-access result","description":"After completing the task from work-offer, POST taskId and submission. On verification, response includes accessToken and resourceId; use Authorization: L402 <accessToken> to access the resource.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["taskId","submission"],"properties":{"taskId":{"type":"string"},"submission":{"type":"object","description":"Task-type-specific result (e.g. label, summary, match answer)"}}}}}},"responses":{"200":{"description":"Verified; accessToken and resourceId returned"},"400":{"description":"Invalid taskId or submission","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/mcp/call":{"get":{"summary":"MCP tool execution (GET not supported)","description":"Returns 405 Method Not Allowed. Use POST to execute tools. Response body: error.code method_not_allowed, details.supportedMethods: [\"POST\"].","responses":{"405":{"description":"Method Not Allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"},"example":{"error":{"code":"method_not_allowed","message":"GET is not allowed","details":{"supportedMethods":["POST"]}}}}}}}},"post":{"summary":"Execute MCP tool","description":"POST body: { tool: string, arguments?: object }. Rate-limited: responses include X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset; 429 includes Retry-After.","responses":{"200":{"description":"Tool result"},"429":{"$ref":"#/components/responses/RateLimit429"}}}},"/api/nexus/creators":{"get":{"summary":"Nexus creator search (org-level)","description":"Search opted-in creators by topic, tag, keyword. Nexus is Paranor.app org-level; self-hosted instances report via POST /api/nexus/register. Rate limited 60/min.","parameters":[{"name":"topic","in":"query","required":false,"schema":{"type":"string"}},{"name":"tag","in":"query","required":false,"schema":{"type":"string"}},{"name":"keyword","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Creators list with total; each has indexUrl, agentBaseUrl (may point to self-hosted)"},"429":{"$ref":"#/components/responses/RateLimit429"}}}},"/api/nexus/feed":{"get":{"summary":"Nexus lightweight feed (org-level)","description":"Lightweight feed of creator entries for agent polling. Cursor-based pagination.","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Entries with tenantId, indexUrl, agentBaseUrl, updatedAt; nextCursor when more"},"429":{"$ref":"#/components/responses/RateLimit429"}}}},"/api/l402/verify":{"post":{"summary":"L402 payment verification","description":"Verify Lightning payment and receive access token. Body: { payment_context_token } or { paymentHash }. Used after paying invoice in L402 flow.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"payment_context_token":{"type":"string"},"paymentHash":{"type":"string"}}}}}},"responses":{"200":{"description":"Access token for Authorization: L402 <token>"},"400":{"description":"Invalid or unpaid"},"429":{"$ref":"#/components/responses/RateLimit429"}}}}},"components":{"responses":{"RateLimit429":{"description":"Rate limited. Retry after Retry-After seconds. All rate-limited Agent API endpoints (guest-kit, MCP call, transcribe, L402 payment-request) use this header contract.","headers":{"Retry-After":{"schema":{"type":"string"},"description":"Seconds until retry"},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Max requests per window"},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining in window"},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix timestamp when window resets"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retryAfterSeconds":60}}}}}}},"schemas":{"ContentIndexDigestPayload":{"description":"Webhook payload for content_index.digest (POST to callback when digestSchedule + digestWindow are set)","type":"object","required":["event","digest","count","items","deliveredAt"],"properties":{"event":{"type":"string","enum":["content_index.digest"]},"digest":{"type":"string","enum":["7d","30d"]},"count":{"type":"integer"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","nullable":true,"description":"Source URL or null"},"date":{"type":"string","description":"YYYY-MM-DD"}}}},"deliveredAt":{"type":"string","format":"date-time"}},"example":{"event":"content_index.digest","digest":"7d","count":2,"items":[{"id":"dot-abc","title":"Recent Article","url":"https://example.com/article","date":"2026-03-05"},{"id":"dot-def","title":"Another Post","url":null,"date":"2026-03-03"}],"deliveredAt":"2026-03-07T12:00:00.000Z"}},"AgentApiError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["not_found","payment_required","rate_limited","bad_request","method_not_allowed","internal_error"]},"message":{"type":"string"},"details":{"type":"object"}}}}}}}}