{
  "openapi": "3.1.0",
  "info": {
    "title": "RepoCritics Public API",
    "version": "1.0.0",
    "summary": "Pre-processed open-source knowledge for developers and AI agents.",
    "description": "Read-only JSON over the RepoCritics corpus: critic and audience scores, community wiki pages, reviews and category/tag discovery.\n\nThe point of the API is to save an agent from re-parsing thousand-token GitHub pages on every question \u2014 the summarising has already happened. No authentication. Every endpoint is rate limited to 100 requests per IP per 24 hours, reported in the `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers on every response; the endpoints that return a `meta` object repeat it there as `meta.rate_limit`. Exceeding the quota returns 429 with `Retry-After`.\n\nThis document is referenced from /.well-known/ai-catalog.json so that ARD registries can index the API rather than the marketing site.",
    "license": {
      "name": "Proprietary content, freely readable API"
    },
    "contact": {
      "url": "https://repocritics.com/about"
    }
  },
  "servers": [
    {
      "url": "https://repocritics.com/api/v1"
    }
  ],
  "paths": {
    "/categories": {
      "get": {
        "operationId": "listCategories",
        "summary": "Every category, with the tag filters that define it",
        "responses": {
          "200": {
            "description": "Category list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "categories": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Category"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/tags": {
      "get": {
        "operationId": "listTags",
        "summary": "Every tag present on a wiki page",
        "responses": {
          "200": {
            "description": "Tag list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "tags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/popular": {
      "get": {
        "operationId": "listPopular",
        "summary": "Highest-scoring repositories, optionally within one category",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category slug, e.g. devtools"
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked repositories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "count": {
                          "type": "integer"
                        },
                        "results": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Repo"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/search": {
      "get": {
        "operationId": "searchRepos",
        "summary": "Full-text search across the corpus",
        "description": "Matches against the indexed search vector, not a substring scan, so ordinary prose queries work.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Free-text query"
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Restrict to one category slug"
          }
        ],
        "responses": {
          "200": {
            "description": "Matching repositories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "query": {
                          "type": "string"
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "count": {
                          "type": "integer"
                        },
                        "results": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Repo"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/repos/{platform}/{owner}/{name}": {
      "get": {
        "operationId": "getRepo",
        "summary": "One repository with its scores and reviews",
        "parameters": [
          {
            "$ref": "#/components/parameters/Platform"
          },
          {
            "$ref": "#/components/parameters/Owner"
          },
          {
            "$ref": "#/components/parameters/Name"
          }
        ],
        "responses": {
          "200": {
            "description": "Repository detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "repo": {
                          "$ref": "#/components/schemas/Repo"
                        },
                        "review_count": {
                          "type": "integer"
                        },
                        "reviews": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/repos/{platform}/{owner}/{name}/wiki": {
      "get": {
        "operationId": "getRepoWiki",
        "summary": "The community wiki page for one repository",
        "description": "Markdown maintained at github.com/repocritics/wiki and synced here. This is the endpoint worth reaching for first \u2014 it is the summarised form the whole site exists to produce.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Platform"
          },
          {
            "$ref": "#/components/parameters/Owner"
          },
          {
            "$ref": "#/components/parameters/Name"
          }
        ],
        "responses": {
          "200": {
            "description": "Wiki page",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "canonical_url": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "description": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "wiki": {
                      "$ref": "#/components/schemas/Wiki"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/repos/{platform}/{owner}/{name}/reviews": {
      "get": {
        "operationId": "listRepoReviews",
        "summary": "Community reviews for one repository",
        "parameters": [
          {
            "$ref": "#/components/parameters/Platform"
          },
          {
            "$ref": "#/components/parameters/Owner"
          },
          {
            "$ref": "#/components/parameters/Name"
          }
        ],
        "responses": {
          "200": {
            "description": "Reviews",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "repo_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "reviews": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/reports/{repoId}": {
      "get": {
        "operationId": "getAiReport",
        "summary": "Cached AI deep-analysis report, when one exists",
        "description": "Read-only cache check. Returns 200 with the cached report when one is live, and 404 with ok=false when none has been generated for the repository \u2014 a miss is an absent resource, not an empty success.",
        "parameters": [
          {
            "name": "repoId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A live cached report",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "cached": {
                      "const": true
                    },
                    "report": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No cached report for this repository",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": false
                    },
                    "cached": {
                      "const": false
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "repoId is not a UUID"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "Platform": {
        "name": "platform",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "examples": [
            "github"
          ]
        }
      },
      "Owner": {
        "name": "owner",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "examples": [
            "facebook"
          ]
        }
      },
      "Name": {
        "name": "name",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "examples": [
            "react"
          ]
        }
      }
    },
    "responses": {
      "NotFound": {
        "description": "No such repository in the corpus",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded; retry after the interval in the Retry-After header",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until the window resets"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "const": "RATE_LIMITED"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Meta": {
        "type": "object",
        "description": "Present on every response that carries a rate limit.",
        "properties": {
          "api_version": {
            "type": "string",
            "examples": [
              "v1"
            ]
          },
          "rate_limit": {
            "type": "object",
            "properties": {
              "limit": {
                "type": "integer",
                "examples": [
                  100
                ]
              },
              "remaining": {
                "type": "integer"
              },
              "reset_at": {
                "type": "integer",
                "description": "Unix milliseconds"
              }
            }
          }
        }
      },
      "Category": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "tag_filters": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sort_order": {
            "type": "integer"
          },
          "featured": {
            "type": "boolean",
            "description": "Whether it appears in the site's topic bar"
          }
        }
      },
      "Repo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "platform": {
            "type": "string"
          },
          "owner": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "stars": {
            "type": [
              "integer",
              "null"
            ]
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "critics_score": {
            "type": [
              "number",
              "null"
            ],
            "description": "Reviewer-weighted score"
          },
          "audience_score": {
            "type": [
              "number",
              "null"
            ],
            "description": "General-audience score"
          },
          "final_score": {
            "type": [
              "number",
              "null"
            ]
          },
          "archived": {
            "type": "boolean"
          },
          "staleness": {
            "type": [
              "string",
              "null"
            ],
            "description": "active, stale, dormant"
          }
        }
      },
      "Wiki": {
        "type": "object",
        "properties": {
          "content_md": {
            "type": [
              "string",
              "null"
            ],
            "description": "Markdown body"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "github_path": {
            "type": [
              "string",
              "null"
            ],
            "description": "Path of the source markdown inside github.com/repocritics/wiki"
          },
          "synced_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "word_count": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      }
    }
  }
}
