{"openapi":"3.1.0","info":{"title":"COPRHub API","version":"1.0.0","description":"COPR-backed discovery, independent metrics, and account stars. Limits: 60 projects/page, 500 changes/page, 30 auth or write requests/minute/IP. Access tokens expire after one hour. PKCE S256 required.","contact":{"email":"coprhub@balsa.info"}},"servers":[{"url":"https://coprhub.org"}],"paths":{"/api/v1/projects":{"get":{"operationId":"listProjects","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"next_offset":{"type":["integer","null"]}}}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"category","in":"query","required":false,"schema":{"type":"string"}},{"name":"fedora","in":"query","required":false,"schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"magazine","in":"query","required":false,"schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}}]}},"/api/v1/projects/{id}":{"get":{"operationId":"getProject","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}]}},"/api/v1/projects/{id}/star":{"put":{"operationId":"starProject","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"project_id":{"type":"integer"},"starred":{"type":"boolean"},"stars":{"type":"integer"}}}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"security":[{"oidc":["stars:write"]}]},"delete":{"operationId":"unstarProject","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"project_id":{"type":"integer"},"starred":{"type":"boolean"},"stars":{"type":"integer"}}}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"security":[{"oidc":["stars:write"]}]}},"/api/v1/me":{"get":{"operationId":"currentUser","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"security":[{"oidc":["profile"]}]}},"/api/v1/me/stars":{"get":{"operationId":"listMyStars","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"next_offset":{"type":["integer","null"]}}}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer"}}],"security":[{"oidc":["stars:read"]}]}},"/api/v1/changes":{"get":{"operationId":"getChanges","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"project_id":{"type":"integer"},"operation":{"enum":["created","updated","deleted"]},"at":{"type":"integer"}}}},"next_cursor":{"type":"integer"}}}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"parameters":[{"name":"after","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}}]}},"/api/v1/ranking":{"get":{"operationId":"discoveryWeights","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/status":{"get":{"operationId":"syncStatus","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/oauth/userinfo":{"get":{"operationId":"userInfo","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"sub":{"type":"string"},"name":{"type":"string"}}}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"security":[{"oidc":["openid"]}]}},"/.well-known/openid-configuration":{"get":{"operationId":"openidConfiguration","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/.well-known/jwks.json":{"get":{"operationId":"signingKeys","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/oauth/token":{"post":{"operationId":"exchangeCode","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["grant_type","code","client_id","redirect_uri","code_verifier"],"properties":{"grant_type":{"type":"string"},"code":{"type":"string"},"client_id":{"type":"string"},"redirect_uri":{"type":"string"},"code_verifier":{"type":"string"}}}}}}}},"/oauth/revoke":{"post":{"operationId":"revokeToken","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["token","client_id"],"properties":{"token":{"type":"string"},"client_id":{"type":"string"}}}}}}}},"/oauth/authorize":{"get":{"operationId":"authorizeClient","parameters":[{"name":"client_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"redirect_uri","in":"query","required":false,"schema":{"type":"string"}},{"name":"response_type","in":"query","required":false,"schema":{"type":"string"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string"}},{"name":"state","in":"query","required":false,"schema":{"type":"string"}},{"name":"nonce","in":"query","required":false,"schema":{"type":"string"}},{"name":"code_challenge","in":"query","required":false,"schema":{"type":"string"}},{"name":"code_challenge_method","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Browser sign-in or consent screen"},"303":{"description":"Redirect to registered client"},"400":{"description":"Request rejected","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}}},"components":{"securitySchemes":{"oidc":{"type":"openIdConnect","openIdConnectUrl":"https://coprhub.org/.well-known/openid-configuration"}},"schemas":{"Project":{"type":"object","properties":{"owner":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"source":{"type":"string"},"classification":{"type":"string"},"id":{"type":"integer"},"stars":{"type":"integer"},"starred":{"type":"integer"},"changed":{"type":"integer"},"github_stars":{"type":["integer","null"]},"flathub_installs":{"type":["integer","null"]},"copr_downloads":{"type":["integer","null"]},"github_checked":{"type":["integer","null"]},"flathub_checked":{"type":["integer","null"]},"copr_checked":{"type":["integer","null"]},"github":{"type":["string","null"]},"flathub":{"type":["string","null"]},"magazine":{"type":["string","null"]},"homepage":{"type":["string","null"]},"instructions":{"type":["string","null"]},"magazine_evidence":{"type":["string","null"]},"editorial_url":{"type":["string","null"]},"editorial_published":{"type":["string","null"]},"magazine_metadata_link":{"type":["string","null"]},"discovery_score":{"type":"number"},"discovery_breakdown":{"type":"object","additionalProperties":{"type":"number"}},"chroots":{"type":"array","items":{"type":"string"}}},"required":["id","owner","name","source"]}}}}