{"openapi":"3.1.0","info":{"title":"PageCompass Agent Gateway","version":"v1","description":"Anonymous recommendations and optional PCL1-/PCBT1- Bearer access to a shared shelf with saved history. Library management is documented at /api/library/v1/openapi.json. REST, tool manifests, Skills, and MCP all delegate to the existing canonical recommendation spine.","x-pagecompass-bot-instructions":["Start at /.well-known/pagecompass-agent.json.","Preserve the user's complete natural-language request, especially hard-constraint words such as no, only, avoid, without, and must.","Omit session_id on the first turn; reuse the returned agent-<UUID> on later turns.","Use /agent/v1/recommend when the user changes constraints or direction.","Use /agent/v1/recommend/more when the user wants another slate under the same ask.","Carry exclude_book_ids to avoid repeats. A spine failure is HTTP 503 with error.retryable true and Retry-After, never a 200 with prose."]},"servers":[{"url":"https://pagecompass.onrender.com"}],"externalDocs":{"description":"PageCompass development guide for AI clients","url":"https://pagecompass.onrender.com/development"},"security":[{},{"bearerAuth":[]}],"paths":{"/agent/v1/recommend":{"post":{"summary":"Recommend books","description":"Thin adapter over PageCompass's existing website recommendation path. This operation does not contain ranking or scoring logic.","security":[{},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["query"],"properties":{"query":{"type":"string","minLength":1,"maxLength":2000},"session_id":{"type":"string","pattern":"^agent-[0-9a-fA-F-]{36}$","maxLength":42},"exclude_book_ids":{"type":"array","maxItems":100,"items":{"type":"string"}},"user_profile":{"$ref":"#/components/schemas/UserProfile"},"feedback":{"$ref":"#/components/schemas/Feedback"}}}}}},"responses":{"200":{"description":"Recommendation response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationResponse"}}}},"400":{"$ref":"#/components/responses/ErrorResponse"},"401":{"$ref":"#/components/responses/ErrorResponse"},"429":{"$ref":"#/components/responses/ErrorResponse"},"502":{"$ref":"#/components/responses/ErrorResponse"},"503":{"$ref":"#/components/responses/ErrorResponse"},"504":{"$ref":"#/components/responses/ErrorResponse"}}}},"/agent/v1/recommend/more":{"post":{"summary":"Get more recommendations","description":"Thin adapter over PageCompass's existing website recommendation path. This operation does not contain ranking or scoring logic.","security":[{},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["query","session_id"],"properties":{"query":{"type":"string","minLength":1,"maxLength":2000},"session_id":{"type":"string","pattern":"^agent-[0-9a-fA-F-]{36}$","maxLength":42},"exclude_book_ids":{"type":"array","maxItems":100,"items":{"type":"string"}},"user_profile":{"$ref":"#/components/schemas/UserProfile"},"feedback":{"$ref":"#/components/schemas/Feedback"}}}}}},"responses":{"200":{"description":"Recommendation response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationResponse"}}}},"400":{"$ref":"#/components/responses/ErrorResponse"},"401":{"$ref":"#/components/responses/ErrorResponse"},"429":{"$ref":"#/components/responses/ErrorResponse"},"502":{"$ref":"#/components/responses/ErrorResponse"},"503":{"$ref":"#/components/responses/ErrorResponse"},"504":{"$ref":"#/components/responses/ErrorResponse"}}}},"/agent/v1/meta":{"get":{"summary":"Discover PageCompass agent capabilities","security":[],"responses":{"200":{"description":"Capability document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/agent/v1/health":{"get":{"summary":"Agent gateway health and non-sensitive counters","security":[],"responses":{"200":{"description":"Healthy agent gateway; recent_recommendation_success_rate is a 0–1 fraction or null when no samples exist","content":{"application/json":{"schema":{"type":"object"}}}},"503":{"description":"Recommendation service is degraded: more than 50% server-side failures over at least five recent calls","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":false},"status":{"const":"degraded"},"recent_recommendation_success_rate":{"type":["number","null"],"minimum":0,"maximum":1}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Optional PCL1- recovery key or PCBT1- assistant Bearer for shared shelf context/history; gateway keys follow deployment mode. Omit credentials only for intentionally anonymous recommendations."}},"schemas":{"UserProfile":{"type":"object","additionalProperties":false,"properties":{"interested_books":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["title","author"],"properties":{"title":{"type":"string","maxLength":500},"author":{"type":"string","maxLength":500}}}},"read_books":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["title","author"],"properties":{"title":{"type":"string","maxLength":500},"author":{"type":"string","maxLength":500}}}},"loved_books":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["title","author"],"properties":{"title":{"type":"string","maxLength":500},"author":{"type":"string","maxLength":500}}}},"rejected_books":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["title","author"],"properties":{"title":{"type":"string","maxLength":500},"author":{"type":"string","maxLength":500}}}},"previously_shown":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["title","author"],"properties":{"title":{"type":"string","maxLength":500},"author":{"type":"string","maxLength":500}}}}}},"Feedback":{"type":"object","additionalProperties":false,"properties":{"on_primary_id":{"type":"string","minLength":1,"maxLength":200,"description":"ID of the primary recommendation the user is reacting to."},"outcome":{"type":"string","enum":["reject","accept","keep"],"description":"Structured reaction to the current primary recommendation."},"reasons":{"type":"array","maxItems":8,"items":{"type":"string","enum":["too_dark","too_slow","not_my_vibe","not_cozy","writing_style","wrong_genre","wrong_subgenre","too_light_novel","not_hard_sf","too_long","too_short"]},"description":"Optional structured reasons for the reaction."},"note":{"type":"string","maxLength":500,"description":"Short free-text clarification from the user."}}},"ConstraintCheck":{"type":"object","additionalProperties":false,"required":["matched_hard","uncertain","failed"],"properties":{"matched_hard":{"type":"array","items":{"type":"string"}},"uncertain":{"type":"array","items":{"type":"string"}},"failed":{"type":"array","items":{"type":"string"}}}},"AgentBook":{"type":"object","additionalProperties":false,"required":["id","title","author","genres","primary_reason_line"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"author":{"type":"string"},"reason":{"type":["string","null"]},"pitch":{"type":["string","null"]},"cover_url":{"type":["string","null"]},"genres":{"type":"array","items":{"type":"string"}},"sub_genres":{"type":"array","items":{"type":"string"},"description":"Catalog-verifiable subgenre tags (not inferred from blurbs)."},"form":{"type":["string","null"],"description":"Coarse work form: fiction, nonfiction, or a more specific form such as memoir or sampler."},"primary_reason_line":{"type":"array","items":{"type":"string"}},"page_count":{"type":["integer","null"],"minimum":1},"constraint_check":{"$ref":"#/components/schemas/ConstraintCheck"}}},"RecommendationResponse":{"type":"object","additionalProperties":false,"required":["api_version","request_id","session_id","source","recommendation","next_actions"],"properties":{"api_version":{"const":"v1"},"request_id":{"type":"string"},"session_id":{"type":"string","pattern":"^agent-[0-9a-fA-F-]{36}$","maxLength":42},"account_id":{"type":"string","description":"Verified shared-shelf account when a library Bearer is used"},"library_id":{"type":"string"},"history_id":{"type":"string"},"reader_context":{"type":"object","properties":{"source":{"const":"saved_shelf"},"saved_book_count":{"type":"integer"}}},"source":{"const":"pagecompass_canonical_recommendation_spine"},"recommendation":{"type":"object","additionalProperties":false,"required":["primary","alternatives","zero_result","zero_result_reason","decision_support","refinement_chips","constraint_blockers"],"properties":{"primary":{"anyOf":[{"$ref":"#/components/schemas/AgentBook"},{"type":"null"}]},"alternatives":{"type":"array","items":{"$ref":"#/components/schemas/AgentBook"}},"zero_result":{"type":"boolean"},"zero_result_reason":{"type":["string","null"]},"reader_message":{"type":["string","null"]},"decision_support":{"type":["object","null"],"additionalProperties":true},"refinement_chips":{"type":"array","items":{"type":"object"}},"constraint_blockers":{"type":"array","items":{"type":"string"}},"nearby_picks":{"type":"array","items":{"$ref":"#/components/schemas/AgentBook"}},"nearby_note":{"type":["string","null"]}}},"next_actions":{"type":"array","items":{"type":"object"}},"hearing":{"type":["object","null"],"additionalProperties":true,"description":"Bot-facing echo of how PageCompass heard the request. Known fields are documented below; future non-breaking fields may be added.","properties":{"request_mode":{"type":"string"},"spine_request_mode":{"type":["string","null"]},"search_mode":{"type":"string"},"title_hint":{"type":["string","null"]},"source":{"type":"string"},"query_echo":{"type":"string"},"conversation_turn":{"type":"string","enum":["recommend","more"]},"turn_kind":{"type":"string","enum":["explore","refine","more"]},"hard_constraints":{"type":"array","items":{"type":"string"}},"soft_preferences":{"type":"array","items":{"type":"string"}},"feedback_received":{"type":"boolean"}}},"cache":{"type":"object","additionalProperties":false,"required":["hit","ttl_ms"],"properties":{"hit":{"type":"boolean"},"ttl_ms":{"type":"integer","minimum":0}}}}},"ErrorResponse":{"type":"object","additionalProperties":false,"required":["api_version","request_id","error"],"properties":{"api_version":{"const":"v1"},"request_id":{"type":"string"},"error":{"type":"object","additionalProperties":false,"required":["code","message","retryable"],"properties":{"code":{"type":"string","description":"Includes INVALID_JSON for malformed request JSON."},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{}}}}}},"responses":{"ErrorResponse":{"description":"Deterministic PageCompass agent error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}