{"openapi":"3.1.0","info":{"title":"OTInstaller Registry API","version":"1","summary":"The public registry of OSINT tools and guides that ot installs from.","description":"Public reads need no sign-in and are cached at the edge (Cache-Control says for how long); every JSON read has an ETag, so If-None-Match gets a 304. Errors are {error: {code, message, hint, docs}} (https://otinstaller.com/schema/error-v1.json), with codes at https://otinstaller.com/docs/errors. 429s carry Retry-After. Signed-in calls take an ot_ token as a bearer token; each operation's x-scope names the scope a token needs. Times are Unix milliseconds. Guide: https://otinstaller.com/docs/api","license":{"name":"Apache-2.0","identifier":"Apache-2.0"},"contact":{"url":"https://github.com/OTInstaller/feedback/issues"}},"servers":[{"url":"https://api.otinstaller.com/v1"}],"externalDocs":{"url":"https://otinstaller.com/docs/api"},"tags":[{"name":"Registry","description":"Searching and reading packages; no sign-in"},{"name":"Content","description":"READMEs, docs and guide pages"},{"name":"Auth","description":"Signing in, in a browser or with a device code"},{"name":"Account","description":"The signed-in user and their API tokens"},{"name":"Publishing","description":"Imports, manifests and sources"},{"name":"Owners","description":"Yanks, deprecations, transfers and backups"},{"name":"Trust","description":"Reports to the reviewers"}],"paths":{"/assets/{file}":{"get":{"operationId":"get_asset","tags":["Content"],"summary":"An image from a README, guide or docs page, by SHA-256","responses":{"200":{"description":"The image","content":{"image/*":{"schema":{"type":"string","format":"binary"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"string"}}],"security":[]}},"/auth/device/start":{"post":{"operationId":"device_start","tags":["Auth"],"summary":"Start a device sign-in, as `ot login` does","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceStart"}}}},"400":{"$ref":"#/components/responses/Error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"enum":["github","gitlab","osintverse"]}}}}}},"security":[]}},"/auth/device/token":{"post":{"operationId":"device_token","tags":["Auth"],"summary":"Poll a device sign-in; answers status pending, slow_down, expired, denied or ok with a token","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceToken"}}}},"400":{"$ref":"#/components/responses/Error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["device_code"],"properties":{"provider":{"enum":["github","gitlab","osintverse"]},"device_code":{"type":"string"},"token_name":{"type":"string"},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}},"expires_in_days":{"type":"integer","minimum":1,"maximum":365}}}}}},"security":[]}},"/auth/logout":{"post":{"operationId":"logout","tags":["Auth"],"summary":"End the browser session","responses":{"204":{"description":"No content"},"400":{"$ref":"#/components/responses/Error"}},"security":[]}},"/auth/{provider}/callback":{"get":{"operationId":"web_login_callback","tags":["Auth"],"summary":"OAuth callback (redirects)","responses":{"302":{"description":"Redirect"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}}],"security":[]}},"/auth/{provider}/login":{"get":{"operationId":"web_login","tags":["Auth"],"summary":"Start a browser sign-in (redirects)","responses":{"302":{"description":"Redirect"},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}},{"name":"redirect","in":"query","required":false,"schema":{"type":"string"},"description":"Where to return on the site"}],"security":[]}},"/feedback":{"post":{"operationId":"send_feedback","tags":["Registry"],"summary":"Feedback to the team (anonymous unless signed in)","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"kind":{"enum":["bug","idea","question","other"]},"message":{"type":"string"},"email":{"type":"string"},"about":{"type":"string"},"client":{"type":"string"},"source":{"enum":["cli","web"]}}}}}},"x-scope":"feedback","security":[{},{"bearer":[]},{"session":[]}],"description":"Anonymous, or with a token that has the feedback scope."}},"/guides":{"get":{"operationId":"search_guides","tags":["Registry"],"summary":"Search guides (as /tools?kind=guide)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResult"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"}},"security":[]}},"/guides/{ns}/{name}":{"get":{"operationId":"get_guide","tags":["Content"],"summary":"A guide and its pages","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"},"410":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"security":[]}},"/guides/{ns}/{name}/{version}":{"get":{"operationId":"get_guide_version","tags":["Content"],"summary":"A guide version","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"A version, or latest"}],"security":[]}},"/guides/{ns}/{name}/{version}/pages/{path}":{"get":{"operationId":"read_guide","tags":["Content"],"summary":"One guide page (?format=html or md)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"A version, or latest"},{"name":"path","in":"path","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"enum":["html","md"]},"description":"html (default) or md"}],"security":[]}},"/health":{"get":{"operationId":"health","tags":["Registry"],"summary":"Liveness check","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"}},"security":[]}},"/imports":{"get":{"operationId":"list_imports","tags":["Publishing"],"summary":"Your import drafts","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}},"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."},"post":{"operationId":"start_import","tags":["Publishing"],"summary":"Start importing a repository (or up to 50)","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/imports/{id}":{"get":{"operationId":"get_import","tags":["Publishing"],"summary":"An import draft","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."},"patch":{"operationId":"edit_import","tags":["Publishing"],"summary":"Change an import draft","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/imports/{id}/finish":{"post":{"operationId":"finish_import","tags":["Publishing"],"summary":"Finish an import: a pull request, or a registry-held manifest","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/installs":{"post":{"operationId":"count_install","tags":["Registry"],"summary":"Anonymous install count (one per address, version and day)","responses":{"204":{"description":"No content"},"400":{"$ref":"#/components/responses/Error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tool","version"],"properties":{"tool":{"type":"string"},"version":{"type":"string"},"client":{"enum":["cli","mcp","ci"]}}}}}},"security":[]}},"/me":{"get":{"operationId":"whoami","tags":["Account"],"summary":"The signed-in user, linked accounts and namespaces","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}},"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."}},"/me/backups":{"get":{"operationId":"list_my_backups","tags":["Owners"],"summary":"Backups of your packages","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}},"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."}},"/me/publish-jobs":{"get":{"operationId":"list_publish_jobs","tags":["Publishing"],"summary":"Your recent publish attempts and their problems","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}},"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."}},"/me/repos":{"get":{"operationId":"list_repos","tags":["Publishing"],"summary":"Repositories you can import","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}},"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."}},"/me/tokens":{"get":{"operationId":"list_tokens","tags":["Account"],"summary":"Your API tokens (never their values)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"tokens":{"type":"array","items":{"$ref":"#/components/schemas/Token"}}}}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}},"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."},"post":{"operationId":"create_token","tags":["Account"],"summary":"Create an API token; it is shown once","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenCreated"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":60},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"},"description":"Default: read, publish, manage, feedback. A token can't create one with scopes it lacks."},"expires_in_days":{"type":"integer","minimum":1,"maximum":365,"description":"Default 90"}}}}}},"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/me/tokens/{id}":{"delete":{"operationId":"revoke_token","tags":["Account"],"summary":"Revoke an API token","responses":{"204":{"description":"No content"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/me/transfers":{"get":{"operationId":"list_my_transfers","tags":["Owners"],"summary":"Transfers and claims involving you","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}},"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."}},"/namespaces/{ns}":{"get":{"operationId":"get_namespace","tags":["Registry"],"summary":"A publisher and its packages","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"}],"security":[]}},"/openapi.json":{"get":{"operationId":"get_openapi","tags":["Registry"],"summary":"This document","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"}},"security":[]}},"/packages/{ns}/{name}/backups":{"get":{"operationId":"list_backups","tags":["Owners"],"summary":"A package's backups","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."},"patch":{"operationId":"set_backup_settings","tags":["Owners"],"summary":"Opt out of (or back into) git backups","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/packages/{ns}/{name}/backups/restore":{"post":{"operationId":"restore_backup","tags":["Owners"],"summary":"A signed link to download a backup","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/packages/{ns}/{name}/manifest":{"put":{"operationId":"edit_held_manifest","tags":["Publishing"],"summary":"Replace a registry-held manifest","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/packages/{ns}/{name}/manifest/pr":{"post":{"operationId":"move_manifest_to_repo","tags":["Publishing"],"summary":"Open a pull request moving a registry-held manifest into the repository","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/packages/{ns}/{name}/source":{"post":{"operationId":"switch_source","tags":["Publishing"],"summary":"Switch a package's source repository","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/packages/{ns}/{name}/sync":{"post":{"operationId":"sync_package","tags":["Publishing"],"summary":"Check the source repository for new release tags now","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/packages/{ns}/{name}/sync-log":{"get":{"operationId":"get_sync_log","tags":["Publishing"],"summary":"Recent sync events","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."}},"/pivots":{"get":{"operationId":"suggest_pivots","tags":["Registry"],"summary":"Tools that take what other tools found, through the pivot map","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pivots"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"400":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated entity types, such as email,subdomain"}],"security":[]}},"/removed":{"get":{"operationId":"list_removed","tags":["Registry"],"summary":"Removed packages and versions (transparency)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"}},"security":[]}},"/sources/gitlab":{"post":{"operationId":"connect_gitlab","tags":["Publishing"],"summary":"Connect a GitLab project","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/sources/{id}":{"delete":{"operationId":"disconnect_source","tags":["Publishing"],"summary":"Disconnect a source","responses":{"204":{"description":"No content"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"x-scope":"publish","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the publish scope."}},"/tools":{"get":{"operationId":"search_tools","tags":["Registry"],"summary":"Search tools and guides","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResult"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"400":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Words to search for"},{"name":"input","in":"query","required":false,"schema":{"type":"string"},"description":"Only packages taking this input type"},{"name":"output","in":"query","required":false,"schema":{"type":"string"},"description":"Only tools finding this entity type"},{"name":"category","in":"query","required":false,"schema":{"type":"string"},"description":"A category slug"},{"name":"runtime","in":"query","required":false,"schema":{"enum":["docker","pipx"]},"description":"docker or pipx"},{"name":"kind","in":"query","required":false,"schema":{"enum":["tool","guide"]},"description":"tool or guide"},{"name":"level","in":"query","required":false,"schema":{"type":"string"},"description":"Guides: beginner, intermediate or advanced"},{"name":"format","in":"query","required":false,"schema":{"type":"string"},"description":"Guides: guide or reference"},{"name":"lang","in":"query","required":false,"schema":{"type":"string"},"description":"Guides: a language code"},{"name":"sort","in":"query","required":false,"schema":{"enum":["relevance","installs","stars","updated","health"]},"description":"relevance (default), installs, stars, updated, or health (healthy tools by their last passing nightly check first)"},{"name":"no_keys","in":"query","required":false,"schema":{"type":"string"},"description":"1: only tools that need no API key"},{"name":"passive_only","in":"query","required":false,"schema":{"type":"string"},"description":"1: only tools that run offline, touch no target and collect no personal data"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100},"description":"1 to 100 (default 25)"},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"next_cursor from the previous page"}],"security":[]}},"/tools/{ns}/{name}":{"get":{"operationId":"get_tool","tags":["Registry"],"summary":"A package: its listing, trust status and latest manifest","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolDetail"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"},"410":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"security":[]}},"/tools/{ns}/{name}/claim":{"post":{"operationId":"claim_package","tags":["Owners"],"summary":"Claim a community wrapper of your own tool","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/tools/{ns}/{name}/deprecate":{"post":{"operationId":"deprecate_package","tags":["Owners"],"summary":"Mark a package deprecated","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string"},"replacement":{"type":"string"}}}}}},"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."},"delete":{"operationId":"undeprecate_package","tags":["Owners"],"summary":"Remove a deprecation","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/tools/{ns}/{name}/docs":{"get":{"operationId":"list_tool_docs","tags":["Content"],"summary":"A tool's docs pages","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"security":[]}},"/tools/{ns}/{name}/docs/{path}":{"get":{"operationId":"get_tool_doc","tags":["Content"],"summary":"One docs page (?format=html or md)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"path","in":"path","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"enum":["html","md"]},"description":"html (default) or md"}],"security":[]}},"/tools/{ns}/{name}/guides":{"get":{"operationId":"list_tool_guides","tags":["Content"],"summary":"Guides that use a tool","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"security":[]}},"/tools/{ns}/{name}/permissions":{"get":{"operationId":"get_permissions","tags":["Owners"],"summary":"What the signed-in user may do with a package","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."}},"/tools/{ns}/{name}/readme":{"get":{"operationId":"get_readme","tags":["Content"],"summary":"A package's README, rendered","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"security":[]}},"/tools/{ns}/{name}/reports":{"post":{"operationId":"report_package","tags":["Trust"],"summary":"Report a package to the reviewers","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"enum":["malware","policy","impersonation","license","broken","other"]},"details":{"type":"string"},"version":{"type":"string"}}}}}},"x-scope":"feedback","security":[{},{"bearer":[]},{"session":[]}],"description":"Anonymous, or with a token that has the feedback scope."}},"/tools/{ns}/{name}/transfer":{"post":{"operationId":"offer_transfer","tags":["Owners"],"summary":"Offer a package to another namespace","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/tools/{ns}/{name}/versions":{"get":{"operationId":"list_versions","tags":["Registry"],"summary":"Published, yanked and removed versions","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"},"410":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"}],"security":[]}},"/tools/{ns}/{name}/{version}":{"get":{"operationId":"get_version","tags":["Registry"],"summary":"One version","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"},"410":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"A version, or latest"}],"security":[]}},"/tools/{ns}/{name}/{version}/manifest":{"get":{"operationId":"get_manifest","tags":["Registry"],"summary":"What ot installs: the manifest, signer, scan status and backup locations","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManifestResponse"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"},"410":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"A version, or latest"}],"security":[]}},"/tools/{ns}/{name}/{version}/scans":{"get":{"operationId":"get_scans","tags":["Registry"],"summary":"Scan and check results for a version","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"},"410":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"A version, or latest"}],"security":[]}},"/tools/{ns}/{name}/{version}/unyank":{"post":{"operationId":"unyank_version","tags":["Owners"],"summary":"Undo a yank","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"A version, or latest"}],"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/tools/{ns}/{name}/{version}/wheel/{file}":{"get":{"operationId":"get_wheel","tags":["Registry"],"summary":"The registry's copy of a wheel (install fallback)","responses":{"200":{"description":"The wheel","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"A version, or latest"},{"name":"file","in":"path","required":true,"schema":{"type":"string"}}],"security":[]}},"/tools/{ns}/{name}/{version}/yank":{"post":{"operationId":"yank_version","tags":["Owners"],"summary":"Hide a version from search and latest","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"},"description":"Namespace"},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Package name"},{"name":"version","in":"path","required":true,"schema":{"type":"string"},"description":"A version, or latest"}],"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/transfers/{id}":{"get":{"operationId":"get_transfer","tags":["Owners"],"summary":"A transfer or claim","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"x-scope":"read","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the read scope."}},"/transfers/{id}/accept":{"post":{"operationId":"accept_transfer","tags":["Owners"],"summary":"Accept a transfer","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/transfers/{id}/decline":{"post":{"operationId":"decline_transfer","tags":["Owners"],"summary":"Decline a transfer","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/transfers/{id}/verify":{"post":{"operationId":"verify_claim","tags":["Owners"],"summary":"Check a pending claim again","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/RateLimited"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"x-scope":"manage","security":[{"bearer":[]},{"session":[]}],"description":"Needs a sign-in: the session cookie, or an API token with the manage scope."}},"/types":{"get":{"operationId":"list_types","tags":["Registry"],"summary":"Input types, entity types, categories and the pivot map","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Types"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"}},"security":[]}},"/facets":{"get":{"operationId":"facet_counts","tags":["Registry"],"summary":"How many visible packages match each facet value","description":"Counts over tools (or guides with kind=guide) for the site's filter rail: inputs, outputs, categories, runtimes, and how many need no key. Counts ignore other filters, so they describe the catalogue, not a search.","parameters":[{"name":"kind","in":"query","required":false,"schema":{"enum":["tool","guide"]},"description":"tool (default) or guide"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Facets"}}}},"304":{"description":"Not modified: the If-None-Match ETag still matches"},"400":{"$ref":"#/components/responses/Error"}},"security":[]}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An ot_ API token from `ot login`, `ot token create` or POST /me/tokens. Tokens have scopes (x-scope on each operation); staff actions need the staff scope, which tokens get only when a signed-in reviewer or admin creates them on the website."},"session":{"type":"apiKey","in":"cookie","name":"ot_session","description":"The website's session (all of the user's powers)"}},"responses":{"Error":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Too many requests; retry after Retry-After seconds","headers":{"Retry-After":{"schema":{"type":"integer"}},"RateLimit-Policy":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"title":"OTInstaller error, version 1","description":"The registry API's error body, and what ot prints on stderr (one line) when JSON output is on. Readers must ignore keys they don't know.","type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","pattern":"^[a-z][a-z0-9_]*$","description":"Stable and documented at docs."},"message":{"type":"string"},"hint":{"type":"string","description":"What to do next, often an ot command."},"docs":{"type":"string","format":"uri","description":"https://otinstaller.com/docs/errors#<code>"},"exit_code":{"type":"integer","description":"ot only: the exit code ot returns."},"request_id":{"type":"string","description":"Identifies a failed registry request in its logs."},"problems":{"type":"array","description":"Each problem with a manifest or request, most specific first.","items":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"path":{"type":"string"},"message":{"type":"string"},"hint":{"type":"string"}}}}}}}},"Scope":{"enum":["read","publish","manage","feedback","staff"]},"Ethics":{"type":"object","properties":{"touches_target":{"type":"boolean"},"auth_required":{"type":"boolean"},"collects_personal_data":{"type":"boolean"},"notifies_target":{"type":"boolean","description":"Present only when the publisher says; unset on a tool that touches the target means it may"}}},"ToolSummary":{"type":"object","required":["namespace","name","kind","summary","latest_version"],"properties":{"namespace":{"type":"string"},"name":{"type":"string"},"kind":{"enum":["tool","guide"]},"summary":{"type":"string"},"latest_version":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"inputs":{"type":"array","items":{"type":"string"},"description":"Input types"},"outputs":{"type":"array","items":{"type":"string","description":"Usually one of the manifest's entity types"}},"runtime":{"type":["string","null"]},"stars":{"type":"integer"},"installs_30d":{"type":"integer"},"health":{"type":"string"},"verified":{"type":"boolean"},"signed":{"type":"boolean"},"needs_keys":{"type":"boolean"},"manifest_held_by_registry":{"type":"boolean"},"community_packaged":{"type":"boolean"},"source_unavailable":{"type":"boolean"},"status":{"type":"string"},"ethics":{"$ref":"#/components/schemas/Ethics","description":"Tools only"},"egress":{"type":"boolean","description":"Tools only: whether runs go online"},"title":{"type":["string","null"]},"level":{"type":["string","null"]},"format":{"type":["string","null"]},"language":{"type":"string"},"needs_update":{"type":"boolean"},"health_checked_at":{"type":["integer","null"],"description":"When the nightly health check last ran, in Unix milliseconds; null when never"}}},"SearchResult":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/ToolSummary"}},"total":{"type":"integer"},"total_capped":{"type":"boolean"},"next_cursor":{"type":"string"}}},"ToolDetail":{"allOf":[{"$ref":"#/components/schemas/ToolSummary"},{"type":"object","properties":{"repo_url":{"type":"string"},"homepage":{"type":["string","null"]},"license":{"type":"string"},"deprecated_message":{"type":"string"},"deprecated_replacement":{"type":"string"},"moved_to":{"type":"string"},"manifest":{"$ref":"https://otinstaller.com/schema/v1.json"}}}]},"ManifestResponse":{"type":"object","properties":{"ref":{"type":"string"},"version":{"type":"string"},"status":{"type":"string"},"removed_reason":{"type":"string"},"signer_identity":{"type":"string"},"signer_issuer":{"type":"string"},"scan_status":{"type":"string"},"health":{"type":"string"},"verified_publisher":{"type":"boolean"},"source_unavailable":{"type":"boolean"},"moved_to":{"type":"string"},"manifest":{"oneOf":[{"$ref":"https://otinstaller.com/schema/v1.json"},{"type":"null"}],"description":"The manifest without optional fields added after ot v0.12, which older ot rejects"},"manifest_full":{"$ref":"https://otinstaller.com/schema/v1.json","description":"The whole manifest; present only when `manifest` leaves fields out"},"mirror_image":{"type":"string"},"wheel_url":{"type":"string"}}},"Page":{"type":"object","properties":{"ref":{"type":"string"},"version":{"type":"string"},"path":{"type":"string"},"title":{"type":"string"},"position":{"type":"integer"},"pages":{"type":"integer"},"format":{"enum":["html","md"]},"body":{"type":"string"},"toc":{},"prev":{},"next":{}}},"Types":{"type":"object","properties":{"inputs":{"type":"array","items":{"type":"string"}},"outputs":{"type":"array","items":{"type":"string"}},"categories":{"type":"array","items":{"type":"string"}},"pivots":{"type":"object","description":"spec/pivots.json: entity type to the inputs it can feed","additionalProperties":{"type":"array","items":{"type":"object","properties":{"input":{"type":"string"},"attr":{"type":"string"},"transform":{"type":"string"}}}}}}},"Pivots":{"type":"object","properties":{"pivots":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/ToolSummary"}}},"inputs":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"unmapped":{"type":"array","items":{"type":"string"}}}},"Me":{"type":"object","properties":{"login":{"type":"string"},"admin":{"type":"boolean"},"reviewer":{"type":"boolean"},"accounts":{"type":"array","items":{"type":"object"}},"namespaces":{"type":"array","items":{"type":"object"}}}},"Token":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}},"scoped":{"type":"boolean","description":"false for tokens from before scopes, which can do everything their user can"},"expires_at":{"type":["integer","null"]},"last_used_at":{"type":["integer","null"]},"created_at":{"type":"integer"},"current":{"type":"boolean"}}},"TokenCreated":{"type":"object","properties":{"id":{"type":"string"},"token":{"type":"string"},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}},"expires_at":{"type":["integer","null"]},"note":{"type":"string"}}},"DeviceStart":{"type":"object","properties":{"provider":{"type":"string"},"device_code":{"type":"string"},"user_code":{"type":"string"},"verification_uri":{"type":"string"},"interval":{"type":"integer"},"expires_in":{"type":"integer"}}},"DeviceToken":{"type":"object","properties":{"status":{"enum":["pending","slow_down","expired","denied","ok"]},"token":{"type":"string"},"login":{"type":"string"},"provider":{"type":"string"},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}},"expires_at":{"type":["integer","null"]}}},"Facets":{"type":"object","required":["kind","inputs","outputs","categories","runtimes","no_keys"],"properties":{"kind":{"enum":["tool","guide"]},"inputs":{"type":"object","additionalProperties":{"type":"integer"}},"outputs":{"type":"object","additionalProperties":{"type":"integer"}},"categories":{"type":"object","additionalProperties":{"type":"integer"}},"runtimes":{"type":"object","additionalProperties":{"type":"integer"}},"no_keys":{"type":"integer","description":"Packages that need no API key"}}}}}}