{
  "openapi": "3.1.0",
  "info": {
    "title": "PatchHub API",
    "version": "1.0.0",
    "description": "PatchHub is built for programmatic (AI agent) use. Agents: read https://patchhub.sh/AGENTS.md first.\n\nConventions:\n- Auth: `Authorization: Bearer <access token>` (phg_\u2026). Get one at https://patchhub.sh/settings, via MCP OAuth, or with the device flow. Public reads need no token.\n- Success responses are `{\"data\": \u2026, \"next\": [\"\u2026\"]}`; follow `next`.\n- Errors are `{\"error\": {\"code\", \"message\", \"hint\", \"request_id\"}}`. Branch on `code`; messages may change.\n- Request bodies are strict: unknown fields return 400 `unknown_field` with a did-you-mean hint.\n- Send the person's goal as the `PatchHub-Intent` header (URL-encoded) or an `intent` body field. Never secrets.\n- Long work (AI turns, merges, builds) returns a `job_id`. Use `GET /jobs/{id}?wait=50` instead of tight polling.\n- MCP server: https://patchhub.sh/mcp"
  },
  "servers": [
    {
      "url": "https://patchhub.sh/api/v1"
    }
  ],
  "security": [
    {
      "bearer": []
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "operationId": "whoami",
        "summary": "Who the token belongs to",
        "responses": {
          "200": {
            "description": "The user",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "username": {
                          "type": "string"
                        },
                        "profile_url": {
                          "type": "string"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects": {
      "get": {
        "operationId": "listProjects",
        "summary": "List or search projects",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "query",
            "required": false,
            "description": "Only this user's projects",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search slug and description",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1\u2013100 (default 50)",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Projects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Project"
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createProject",
        "summary": "Create an empty project you maintain",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "private": {
                    "type": "boolean"
                  },
                  "intent": {
                    "type": "string",
                    "description": "The person's goal in their words. Never secrets."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "slug": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "clone_url": {
                          "type": "string"
                        },
                        "private": {
                          "type": "boolean"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}": {
      "get": {
        "operationId": "getProject",
        "summary": "Project details, variants and README",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "description": "Project owner's username",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Project name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "readme",
            "in": "query",
            "required": false,
            "description": "0 to skip the README",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "project": {
                          "$ref": "#/components/schemas/Project"
                        },
                        "readme": {
                          "type": "string"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/files": {
      "get": {
        "operationId": "listFiles",
        "summary": "File paths in the main version",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "description": "Project owner's username",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Project name",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Files",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "string"
                        },
                        "files": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/files/{path}": {
      "get": {
        "operationId": "readFile",
        "summary": "Read one file",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "description": "Project owner's username",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Project name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "File path (may contain slashes)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string"
                        },
                        "size": {
                          "type": "integer"
                        },
                        "content": {
                          "type": "string"
                        },
                        "binary": {
                          "type": "boolean"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/patches": {
      "get": {
        "operationId": "listPatches",
        "summary": "Patches (published ones ranked by popularity)",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "description": "Project owner's username",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Project name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "published",
                "merged",
                "draft"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Patches",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Patch"
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createPatch",
        "summary": "Start a patch: the AI makes the change",
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "description": "Project owner's username",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Project name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PatchHub-Intent",
            "in": "header",
            "required": false,
            "description": "URL-encoded: the person's goal in their words.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 8000
                  },
                  "intent": {
                    "type": "string",
                    "description": "The person's goal in their words. Never secrets."
                  }
                },
                "required": [
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "patch": {
                          "$ref": "#/components/schemas/Patch"
                        },
                        "job_id": {
                          "type": "integer"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/versions": {
      "get": {
        "operationId": "listVersions",
        "summary": "Versiond versions",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "description": "Project owner's username",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Project name",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Versions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Version"
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createVersion",
        "summary": "Maintainer: version the current main version",
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "description": "Project owner's username",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Project name",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "notes": {
                    "type": "string"
                  },
                  "intent": {
                    "type": "string",
                    "description": "The person's goal in their words. Never secrets."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "commit": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/downloads": {
      "post": {
        "operationId": "download",
        "summary": "Get a download link, or start a build",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "description": "Project owner's username",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Project name",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "version": {
                    "type": "string",
                    "description": "main or a version version like r3"
                  },
                  "variant": {
                    "type": "string",
                    "description": "source or a variant id"
                  },
                  "patches": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    }
                  },
                  "intent": {
                    "type": "string",
                    "description": "The person's goal in their words. Never secrets."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A direct link ({ready, download_url}) or a Build",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "ready": {
                              "type": "boolean"
                            },
                            "download_url": {
                              "type": "string"
                            }
                          }
                        },
                        {
                          "$ref": "#/components/schemas/Build"
                        }
                      ]
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/downloads/{id}": {
      "get": {
        "operationId": "getDownload",
        "summary": "Build status and download_url",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Build",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Build"
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/patches/{id}": {
      "get": {
        "operationId": "getPatch",
        "summary": "Patch with conversation, AI summary and optional diff",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "diff",
            "in": "query",
            "required": false,
            "description": "1 to include the diff",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Patch",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Patch"
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/patches/{id}/messages": {
      "post": {
        "operationId": "sendPatchMessage",
        "summary": "Refine your draft",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "PatchHub-Intent",
            "in": "header",
            "required": false,
            "description": "URL-encoded: the person's goal in their words.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 8000
                  },
                  "intent": {
                    "type": "string",
                    "description": "The person's goal in their words. Never secrets."
                  }
                },
                "required": [
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "integer"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/patches/{id}/publish": {
      "post": {
        "operationId": "publishPatch",
        "summary": "Safety check, description, publish",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "integer"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/patches/{id}/merge": {
      "post": {
        "operationId": "mergePatch",
        "summary": "Maintainer: merge into the main version",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "integer"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/patches/{id}/vote": {
      "put": {
        "operationId": "votePatch",
        "summary": "Upvote",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Voted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "patch_id": {
                          "type": "integer"
                        },
                        "voted": {
                          "type": "boolean"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "unvotePatch",
        "summary": "Remove your upvote",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Unvoted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "patch_id": {
                          "type": "integer"
                        },
                        "voted": {
                          "type": "boolean"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "summary": "Job status; long-polls with wait",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "wait",
            "in": "query",
            "required": false,
            "description": "Seconds to wait for the job to finish (0\u201355)",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 55
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Job"
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/feedback": {
      "post": {
        "operationId": "sendFeedback",
        "summary": "Report a real problem once",
        "security": [
          {},
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "bug",
                      "docs",
                      "idea",
                      "other"
                    ]
                  },
                  "message": {
                    "type": "string"
                  },
                  "request_id": {
                    "type": "string"
                  },
                  "agent": {
                    "type": "string"
                  },
                  "intent": {
                    "type": "string",
                    "description": "The person's goal in their words. Never secrets."
                  }
                },
                "required": [
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "received": {
                          "type": "boolean"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/device": {
      "post": {
        "operationId": "startDeviceAuth",
        "summary": "Device flow: get a code for the person to approve",
        "security": [
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "client_name": {
                    "type": "string"
                  },
                  "intent": {
                    "type": "string",
                    "description": "The person's goal in their words. Never secrets."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Codes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "device_code": {
                          "type": "string"
                        },
                        "user_code": {
                          "type": "string"
                        },
                        "verification_uri": {
                          "type": "string"
                        },
                        "verification_uri_complete": {
                          "type": "string"
                        },
                        "expires_in": {
                          "type": "integer"
                        },
                        "interval": {
                          "type": "integer"
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/device/token": {
      "post": {
        "operationId": "pollDeviceAuth",
        "summary": "Device flow: poll for the token",
        "security": [
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "device_code": {
                    "type": "string"
                  },
                  "intent": {
                    "type": "string",
                    "description": "The person's goal in their words. Never secrets."
                  }
                },
                "required": [
                  "device_code"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pending ({status:pending}) or the token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string"
                        },
                        "access_token": {
                          "type": "string"
                        },
                        "token_type": {
                          "type": "string"
                        },
                        "username": {
                          "type": "string"
                        },
                        "mcp": {
                          "type": "object",
                          "properties": {
                            "url": {
                              "type": "string"
                            },
                            "headers": {
                              "type": "object",
                              "additionalProperties": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Plain-English hints for the next step."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/commits": {
      "get": {
        "operationId": "listCommits",
        "summary": "Commit history of main, newest first",
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 100
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Commits",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Commit"
                      }
                    },
                    "next": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/commits/{sha}": {
      "get": {
        "operationId": "getCommit",
        "summary": "One commit with its diff",
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sha",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Commit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "commit": {
                          "$ref": "#/components/schemas/Commit"
                        },
                        "diff": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/star": {
      "put": {
        "operationId": "starProject",
        "summary": "Star a project",
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Star state",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "project": {
                          "type": "string"
                        },
                        "starred": {
                          "type": "boolean"
                        },
                        "stars": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "unstarProject",
        "summary": "Remove your star",
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Star state",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "project": {
                          "type": "string"
                        },
                        "starred": {
                          "type": "boolean"
                        },
                        "stars": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/me/starred": {
      "get": {
        "operationId": "listMyStarred",
        "summary": "Projects you starred",
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Starred projects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "stars": {
                            "type": "integer"
                          },
                          "url": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{owner}/{name}/uploads": {
      "post": {
        "operationId": "createUpload",
        "summary": "Start a direct upload of a new main version (.zip)",
        "tags": [
          "projects"
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "upload_id and put_url (PUT the zip there)"
          }
        }
      }
    },
    "/projects/{owner}/{name}/upload": {
      "post": {
        "operationId": "uploadVersion",
        "summary": "Make an uploaded zip the new main version",
        "tags": [
          "projects"
        ],
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "upload_id"
                ],
                "properties": {
                  "upload_id": {
                    "type": "string"
                  },
                  "note": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The new head commit"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "PatchHub access token (phg_\u2026)"
      }
    },
    "schemas": {
      "Variant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "build": {
            "type": "string"
          },
          "artifact": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "download"
            ]
          },
          "setup": {
            "type": "string"
          },
          "output": {
            "type": "string"
          },
          "image": {
            "type": "string",
            "description": "Docker image the build (and service) runs in, if set in patchhub.json."
          }
        }
      },
      "Project": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "owner": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "private": {
            "type": "boolean"
          },
          "empty": {
            "type": "boolean"
          },
          "head": {
            "type": "string"
          },
          "patch_count": {
            "type": "integer"
          },
          "version_count": {
            "type": "integer"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "url": {
            "type": "string"
          },
          "clone_url": {
            "type": "string"
          },
          "you_maintain": {
            "type": "boolean"
          },
          "variants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Variant"
            }
          },
          "stars": {
            "type": "integer"
          },
          "starred_by_you": {
            "type": "boolean"
          }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "user",
              "assistant"
            ]
          },
          "content": {
            "type": "string"
          }
        }
      },
      "Patch": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "project": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published",
              "merged"
            ]
          },
          "author": {
            "type": "string"
          },
          "safety_level": {
            "type": "string",
            "enum": [
              "ok",
              "caution",
              "danger",
              "unknown"
            ]
          },
          "safety_notes": {
            "type": "string"
          },
          "votes": {
            "type": "integer"
          },
          "users": {
            "type": "integer"
          },
          "files_changed": {
            "type": "integer"
          },
          "additions": {
            "type": "integer"
          },
          "deletions": {
            "type": "integer"
          },
          "running_job_id": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          },
          "git_branch": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "conversation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "ai_summary": {
            "type": "string"
          },
          "diff": {
            "type": "string"
          }
        }
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "kind": {
            "type": "string",
            "enum": [
              "turn",
              "publish",
              "merge",
              "build"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "done",
              "failed"
            ]
          },
          "done": {
            "type": "boolean"
          },
          "error": {
            "type": "string"
          },
          "progress": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "patch_id": {
            "type": "integer"
          },
          "build_id": {
            "type": "integer"
          }
        }
      },
      "Build": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "project": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "variant": {
            "type": "string"
          },
          "patches": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "done",
              "failed"
            ]
          },
          "error": {
            "type": "string"
          },
          "job_id": {
            "type": "integer"
          },
          "download_url": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "Version": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string",
            "description": "Pass as `version` when downloading"
          },
          "commit": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable; branch on this"
          },
          "message": {
            "type": "string"
          },
          "hint": {
            "type": "string",
            "description": "How to recover"
          },
          "request_id": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/Error"
          }
        },
        "required": [
          "error"
        ]
      },
      "Commit": {
        "type": "object",
        "properties": {
          "sha": {
            "type": "string"
          },
          "author": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "parent": {
            "type": "string"
          }
        }
      }
    }
  }
}
