{
  "openapi": "3.1.0",
  "info": {
    "title": "OpenAgents API",
    "version": "4.0.0",
    "description": "Every route under /api/v1, plus checkout, the billing portal, the Stripe and GitHub webhooks, Connect onboarding, and the internal cron routes (bearer CRON_SECRET). Reads are unauthenticated; writes accept a session cookie or a scoped personal access token (Authorization: Bearer oa_...). Rate limits and error shapes are documented per operation.",
    "license": {
      "name": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://openagents-nu.vercel.app",
      "description": "Hosted instance"
    },
    {
      "url": "http://localhost:3000",
      "description": "Local development"
    }
  ],
  "tags": [
    {
      "name": "packages",
      "description": "Browse, fetch, and download packages and their files"
    },
    {
      "name": "versions",
      "description": "Per-version metadata and downloads"
    },
    {
      "name": "search",
      "description": "Full-text search, tags"
    },
    {
      "name": "publish",
      "description": "Publishing new packages and versions"
    },
    {
      "name": "lifecycle",
      "description": "Status changes, deprecation, deletion, reports"
    },
    {
      "name": "reviews",
      "description": "Star ratings and written reviews"
    },
    {
      "name": "analytics",
      "description": "Download/star/rating stats for a package"
    },
    {
      "name": "tokens",
      "description": "Personal access tokens"
    },
    {
      "name": "users",
      "description": "Profiles and the current session"
    },
    {
      "name": "admin",
      "description": "Moderation queue and reports (admin only)"
    },
    {
      "name": "payments",
      "description": "Checkout, billing portal, webhook, Stripe Connect"
    },
    {
      "name": "collections",
      "description": "Curated, ordered lists of packages"
    },
    {
      "name": "sources",
      "description": "GitHub auto-sync: linking a package to a repo for automatic republishing"
    },
    {
      "name": "account",
      "description": "Data export and account deletion"
    },
    {
      "name": "auth",
      "description": "Auth.js sign-in/callback/session"
    },
    {
      "name": "organizations",
      "description": "Shared publisher identities with member roles"
    },
    {
      "name": "trust-safety",
      "description": "Publish-time content scanning and security advisories"
    },
    {
      "name": "refunds",
      "description": "Buyer-initiated refund requests and seller/admin resolution"
    },
    {
      "name": "ops",
      "description": "Cron-driven maintenance and platform-wide analytics (internal / admin)"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "oa_<40 hex>",
        "description": "Personal access token, `Authorization: Bearer oa_<40 hex>`. Scopes: read, publish, star, download, review. A route that accepts a token also accepts a browser session cookie, which is treated as having every scope."
      },
      "sessionCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "authjs.session-token",
        "description": "Auth.js v5 session cookie, set after sign-in at /signin. Unrestricted — behaves as every token scope at once."
      },
      "cronSecret": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "CRON_SECRET",
        "description": "Bearer token matching the deployment's CRON_SECRET env var, used only by the internal /api/cron/* routes. Not a user credential — never accepted on any other route."
      }
    },
    "parameters": {
      "owner": {
        "name": "owner",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Package owner handle."
      },
      "name": {
        "name": "name",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Package name."
      },
      "version": {
        "name": "version",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "A published semver version string."
      },
      "handle": {
        "name": "handle",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "A collection owner's handle."
      },
      "slug": {
        "name": "slug",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "A collection's slug, unique per owner."
      },
      "orgHandle": {
        "name": "handle",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "An organization's handle."
      },
      "userHandle": {
        "name": "userHandle",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "A user handle, e.g. an organization member being removed."
      },
      "advisoryId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "A security advisory's id."
      },
      "refundId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "A refund request's id."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Present only alongside validation failures (e.g. publish)."
          }
        }
      },
      "Pricing": {
        "type": "object",
        "required": [
          "model",
          "amountCents",
          "currency"
        ],
        "properties": {
          "model": {
            "type": "string",
            "enum": [
              "free",
              "one-time",
              "subscription"
            ]
          },
          "amountCents": {
            "type": "integer",
            "minimum": 0,
            "description": "For subscription, the amount charged per interval."
          },
          "currency": {
            "type": "string",
            "description": "3-letter lowercase ISO 4217 code."
          },
          "interval": {
            "type": "string",
            "enum": [
              "month",
              "year"
            ],
            "description": "Required when model is subscription; absent/ignored otherwise."
          }
        }
      },
      "ManifestInput": {
        "type": "object",
        "required": [
          "name",
          "type",
          "required"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "string",
              "number",
              "boolean",
              "path",
              "url"
            ]
          },
          "required": {
            "type": "boolean"
          },
          "description": {
            "type": "string"
          },
          "default": {}
        }
      },
      "Manifest": {
        "type": "object",
        "description": "Parsed openagent.yaml, camelCase (source manifest keys are snake_case). See src/content/docs/package-format.md.",
        "required": [
          "schema",
          "name",
          "owner",
          "version",
          "kind",
          "title",
          "summary",
          "license",
          "pricing",
          "entry",
          "files"
        ],
        "properties": {
          "schema": {
            "type": "integer",
            "enum": [
              1
            ]
          },
          "name": {
            "type": "string",
            "pattern": "^[a-z0-9-]{2,64}$"
          },
          "owner": {
            "type": "string",
            "pattern": "^[a-z0-9-]{2,64}$"
          },
          "version": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "workflow",
              "harness",
              "rules",
              "skill"
            ]
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "maxLength": 160
          },
          "license": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "runtimes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pricing": {
            "$ref": "#/components/schemas/Pricing"
          },
          "entry": {
            "type": "string"
          },
          "files": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "inputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ManifestInput"
            }
          },
          "requires": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "\"owner/name@range\" dependencies. Resolved (with transitive requires, cycle/conflict reporting) by CLI 0.3.0's `add`; not auto-installed server-side."
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9]*(?:[ -][a-z0-9]+)*$"
            },
            "maxItems": 20,
            "description": "Short verb phrases naming what the package does, e.g. \"reconcile csv\". Matched by `q` in GET /api/v1/packages and GET /api/v1/search, alongside tags/title/summary/name."
          },
          "homepage": {
            "type": "string",
            "format": "uri"
          },
          "repository": {
            "type": "string",
            "format": "uri"
          },
          "origin": {
            "$ref": "#/components/schemas/ManifestOrigin"
          },
          "evidence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ManifestEvidence"
            },
            "maxItems": 20
          },
          "attestedBy": {
            "$ref": "#/components/schemas/ManifestAttestation"
          }
        }
      },
      "ManifestOrigin": {
        "type": "object",
        "description": "Where this package's content originally came from, when it wasn't authored directly against this registry.",
        "required": [
          "repo",
          "commit"
        ],
        "properties": {
          "repo": {
            "type": "string",
            "description": "\"owner/repo\" or a full URL — any git host."
          },
          "commit": {
            "type": "string",
            "pattern": "^[0-9a-f]{7,40}$"
          }
        }
      },
      "ManifestEvidence": {
        "type": "object",
        "required": [
          "url",
          "kind"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "kind": {
            "type": "string",
            "maxLength": 40,
            "description": "Free-form, e.g. \"repo\", \"benchmark\", \"citation\", \"test-run\", \"scan\"."
          },
          "note": {
            "type": "string",
            "maxLength": 500
          }
        }
      },
      "ManifestAttestation": {
        "type": "object",
        "description": "Who (agent or person) actually ran the publish, distinct from `owner`.",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "runId": {
            "type": "string",
            "maxLength": 100,
            "description": "Identifies the specific run that produced this publish, for an automated agent."
          }
        }
      },
      "PackageSummary": {
        "type": "object",
        "required": [
          "id",
          "owner",
          "name",
          "title",
          "summary",
          "kind",
          "tags",
          "capabilities",
          "runtimes",
          "pricing",
          "version",
          "license",
          "stats",
          "featured",
          "source",
          "updatedAt",
          "ownerType"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "\"owner/name\""
          },
          "owner": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "workflow",
              "harness",
              "rules",
              "skill"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "See Manifest.capabilities."
          },
          "runtimes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pricing": {
            "$ref": "#/components/schemas/Pricing"
          },
          "version": {
            "type": "string"
          },
          "license": {
            "type": "string"
          },
          "stats": {
            "type": "object",
            "properties": {
              "downloads": {
                "type": "integer"
              },
              "stars": {
                "type": "integer"
              },
              "ratingAverage": {
                "type": "number",
                "nullable": true
              },
              "ratingCount": {
                "type": "integer"
              }
            }
          },
          "featured": {
            "type": "boolean"
          },
          "source": {
            "type": "string",
            "enum": [
              "seed",
              "db"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "live",
              "unlisted",
              "deprecated"
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "ownerType": {
            "type": "string",
            "enum": [
              "user",
              "org"
            ],
            "description": "Whether `owner` names a user handle or an organization handle."
          }
        }
      },
      "PackageVersionSummary": {
        "type": "object",
        "required": [
          "version",
          "publishedAt"
        ],
        "properties": {
          "version": {
            "type": "string"
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "changelog": {
            "type": "string"
          }
        }
      },
      "Package": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PackageSummary"
          },
          {
            "type": "object",
            "properties": {
              "manifest": {
                "$ref": "#/components/schemas/Manifest"
              },
              "readme": {
                "type": "string"
              },
              "files": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "size": {
                      "type": "integer"
                    }
                  }
                }
              },
              "versions": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PackageVersionSummary"
                }
              },
              "latestVersion": {
                "type": "string"
              },
              "deprecation": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "message": {
                    "type": "string"
                  },
                  "replacementId": {
                    "type": "string"
                  }
                }
              },
              "createdAt": {
                "type": "string",
                "format": "date-time"
              },
              "advisories": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Advisory"
                },
                "description": "Open (non-withdrawn) advisories, newest first."
              },
              "verifiedSource": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "repo": {
                    "type": "string"
                  },
                  "ref": {
                    "type": "string"
                  },
                  "lastSyncedAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                },
                "description": "Set once a linked GitHub source has synced at least once."
              }
            }
          }
        ]
      },
      "CatalogPage": {
        "type": "object",
        "required": [
          "items",
          "total"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PackageSummary"
            }
          },
          "total": {
            "type": "integer"
          },
          "correctedQuery": {
            "type": "string",
            "description": "Present when `q` was typo-corrected before matching."
          },
          "facets": {
            "type": "object",
            "description": "Present when the request included `?facets=1`.",
            "properties": {
              "kind": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer"
                }
              },
              "runtime": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer"
                }
              },
              "tag": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer"
                }
              },
              "price": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "CatalogExportEntry": {
        "type": "object",
        "description": "One line of GET /api/v1/catalog.ndjson.",
        "required": [
          "id",
          "owner",
          "name",
          "kind",
          "title",
          "summary",
          "version",
          "license",
          "tags",
          "capabilities",
          "runtimes",
          "pricing",
          "updatedAt",
          "downloadSha256"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "\"owner/name\""
          },
          "owner": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "workflow",
              "harness",
              "rules",
              "skill"
            ]
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "license": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "See Manifest.capabilities."
          },
          "runtimes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pricing": {
            "$ref": "#/components/schemas/Pricing"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "downloadSha256": {
            "type": "string",
            "description": "Hex-encoded sha256 of the same gzip tarball GET .../download serves."
          }
        }
      },
      "Token": {
        "type": "object",
        "required": [
          "id",
          "name",
          "prefix",
          "scopes",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string",
            "description": "First 8 characters of the token, for telling tokens apart in the UI."
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "read",
                "publish",
                "star",
                "download"
              ]
            }
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "revokedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "TokenCreated": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Token"
          },
          {
            "type": "object",
            "required": [
              "token"
            ],
            "properties": {
              "token": {
                "type": "string",
                "description": "Plaintext token, `oa_` + 40 hex. Shown exactly once."
              }
            }
          }
        ]
      },
      "Review": {
        "type": "object",
        "required": [
          "id",
          "user",
          "rating",
          "createdAt",
          "updatedAt",
          "verifiedPurchase"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "user": {
            "type": "object",
            "properties": {
              "handle": {
                "type": "string"
              },
              "name": {
                "type": "string",
                "nullable": true
              },
              "image": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "rating": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "verifiedPurchase": {
            "type": "boolean"
          },
          "helpfulCount": {
            "type": "integer"
          }
        }
      },
      "ReviewList": {
        "type": "object",
        "required": [
          "items",
          "average",
          "count",
          "total",
          "histogram"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Review"
            }
          },
          "average": {
            "type": "number",
            "nullable": true
          },
          "count": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "histogram": {
            "type": "object",
            "description": "Count of reviews at each star rating, independent of sort/limit/offset.",
            "properties": {
              "1": {
                "type": "integer"
              },
              "2": {
                "type": "integer"
              },
              "3": {
                "type": "integer"
              },
              "4": {
                "type": "integer"
              },
              "5": {
                "type": "integer"
              }
            }
          }
        }
      },
      "Profile": {
        "type": "object",
        "properties": {
          "handle": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "image": {
            "type": "string",
            "nullable": true
          },
          "bio": {
            "type": "string",
            "nullable": true
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "packages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PackageSummary"
            }
          }
        }
      },
      "Stats": {
        "type": "object",
        "properties": {
          "downloads": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer"
              },
              "byDay": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "day": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              },
              "byVersion": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              },
              "byRuntime": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "stars": {
            "type": "integer"
          },
          "rating": {
            "type": "object",
            "properties": {
              "average": {
                "type": "number",
                "nullable": true
              },
              "count": {
                "type": "integer"
              }
            }
          }
        }
      },
      "CollectionItem": {
        "type": "object",
        "required": [
          "owner",
          "name",
          "position",
          "addedAt"
        ],
        "properties": {
          "owner": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "position": {
            "type": "integer"
          },
          "addedAt": {
            "type": "string",
            "format": "date-time"
          },
          "package": {
            "$ref": "#/components/schemas/PackageSummary",
            "description": "Inlined so a client can render the collection without a request per item."
          }
        }
      },
      "Collection": {
        "type": "object",
        "required": [
          "id",
          "ownerHandle",
          "slug",
          "title",
          "isPublic",
          "featured",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "ownerHandle": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isPublic": {
            "type": "boolean"
          },
          "featured": {
            "type": "boolean"
          },
          "itemCount": {
            "type": "integer",
            "description": "Present on list responses; omitted in favor of a full `items` array on the single-collection GET."
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CollectionItem"
            },
            "description": "Present only on GET /api/v1/collections/{handle}/{slug}."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CollectionList": {
        "type": "object",
        "required": [
          "items",
          "total"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Collection"
            }
          },
          "total": {
            "type": "integer"
          }
        }
      },
      "PackageSource": {
        "type": "object",
        "required": [
          "id",
          "repo"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "repo": {
            "type": "string",
            "description": "\"github-owner/repo\"."
          },
          "ref": {
            "type": "string",
            "nullable": true,
            "description": "Branch or tag; null means the repo's default branch / the pushed tag."
          },
          "subdir": {
            "type": "string",
            "nullable": true
          },
          "webhookUrl": {
            "type": "string",
            "description": "\"/api/webhooks/github/{id}\" — present on PUT/GET."
          },
          "secret": {
            "type": "string",
            "description": "Shown exactly once, on the PUT response that creates the link. Never returned by GET."
          },
          "lastSyncedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastResult": {
            "type": "string",
            "nullable": true,
            "description": "e.g. \"published 1.3.0\", \"up to date\", or an error message from the last sync attempt."
          }
        }
      },
      "Badge": {
        "type": "object",
        "description": "Query parameters accepted by GET .../badge. The response itself is an image/svg+xml body, not JSON.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "version",
              "downloads",
              "stars",
              "rating"
            ],
            "default": "version"
          }
        }
      },
      "AccountExport": {
        "type": "object",
        "description": "Everything tied to the signed-in account. The response itself is a JSON file download (Content-Disposition: attachment), not an inline API shape a client is expected to type against.",
        "properties": {
          "profile": {
            "$ref": "#/components/schemas/Profile"
          },
          "packages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Package"
            }
          },
          "purchases": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "reviews": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Review"
            }
          },
          "tokens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Token"
            }
          },
          "stars": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "\"owner/name\" ids."
            }
          },
          "collections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Collection"
            }
          },
          "exportedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BillingPortal": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "Stripe-hosted billing portal session URL; redirect the subscriber here."
          }
        }
      },
      "Organization": {
        "type": "object",
        "required": [
          "handle",
          "displayName",
          "createdAt"
        ],
        "properties": {
          "handle": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "bio": {
            "type": "string",
            "nullable": true
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "avatarUrl": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrganizationMember"
            }
          }
        }
      },
      "OrganizationMember": {
        "type": "object",
        "required": [
          "handle",
          "role"
        ],
        "properties": {
          "handle": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "role": {
            "type": "string",
            "enum": [
              "owner",
              "admin",
              "member"
            ]
          }
        }
      },
      "Advisory": {
        "type": "object",
        "required": [
          "id",
          "owner",
          "name",
          "severity",
          "title",
          "body",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "owner": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "enum": [
              "low",
              "moderate",
              "high",
              "critical"
            ]
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "affectedVersions": {
            "type": "string",
            "nullable": true,
            "description": "Semver range, e.g. \"<1.3.0\"; null means all versions."
          },
          "fixedInVersion": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "withdrawnAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "ScanResult": {
        "type": "object",
        "required": [
          "score",
          "flags"
        ],
        "properties": {
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "0 (clean) .. 100 (high risk)."
          },
          "flags": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "prompt-injection-override",
                "hidden-text",
                "credential-network-combo",
                "network-unknown-host",
                "destructive-command",
                "leaked-secret",
                "obfuscated-eval"
              ]
            }
          }
        }
      },
      "Diff": {
        "type": "object",
        "required": [
          "from",
          "to",
          "files",
          "summary",
          "truncated"
        ],
        "properties": {
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "path",
                "status"
              ],
              "properties": {
                "path": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "added",
                    "removed",
                    "modified",
                    "unchanged"
                  ]
                },
                "hunks": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "header": {
                        "type": "string"
                      },
                      "lines": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": [
                                "context",
                                "add",
                                "del"
                              ]
                            },
                            "text": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "summary": {
            "type": "object",
            "properties": {
              "filesChanged": {
                "type": "integer"
              },
              "additions": {
                "type": "integer"
              },
              "deletions": {
                "type": "integer"
              }
            }
          },
          "truncated": {
            "type": "boolean"
          }
        }
      },
      "RefundRequest": {
        "type": "object",
        "required": [
          "id",
          "purchaseId",
          "reason",
          "status",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "purchaseId": {
            "type": "string",
            "format": "uuid"
          },
          "reason": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "approved",
              "denied",
              "refunded"
            ]
          },
          "sellerNote": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "ValidateResult": {
        "type": "object",
        "required": [
          "valid",
          "manifestIssues",
          "readmeFindings"
        ],
        "properties": {
          "valid": {
            "type": "boolean"
          },
          "manifestIssues": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "readmeFindings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "rule": {
                  "type": "string",
                  "enum": [
                    "missing-title",
                    "missing-install-usage",
                    "missing-example",
                    "todo-placeholder",
                    "too-short",
                    "broken-relative-link",
                    "missing-tags-runtimes-homepage-hint"
                  ]
                },
                "message": {
                  "type": "string"
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "error",
                    "warning"
                  ]
                }
              }
            }
          }
        }
      },
      "Analytics": {
        "type": "object",
        "required": [
          "downloads",
          "publishes",
          "revenue",
          "topPackages",
          "scanFlags"
        ],
        "properties": {
          "downloads": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer"
              },
              "byDay": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "day": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "publishes": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer"
              },
              "byDay": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "day": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "revenue": {
            "type": "object",
            "properties": {
              "totalCents": {
                "type": "integer"
              },
              "byDay": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "day": {
                      "type": "string"
                    },
                    "amountCents": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "topPackages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "owner": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "downloads": {
                  "type": "integer"
                }
              }
            }
          },
          "scanFlags": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Count of publishes flagged per rule id, over the window."
          }
        }
      }
    }
  },
  "paths": {
    "/api/v1/packages": {
      "get": {
        "tags": [
          "packages",
          "search"
        ],
        "summary": "List/filter packages",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Matched against name, title, summary, owner, tags, and capabilities."
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "workflow",
                "harness",
                "rules",
                "skill"
              ]
            }
          },
          {
            "name": "runtime",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "price",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "free",
                "paid"
              ]
            }
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "owner",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "downloads",
                "stars",
                "updated",
                "name",
                "trending"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 24,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "facets",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Set to 1 to include the `facets` field in the response."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogPage"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog.ndjson": {
      "get": {
        "tags": [
          "packages",
          "search"
        ],
        "summary": "Bulk/incremental export: every package as newline-delimited JSON",
        "description": "Streams one JSON object per line (application/x-ndjson) — a manifest summary, version, tags, kind, updatedAt, and the tarball's downloadSha256 — for every live/deprecated package. Pass `since` (the newest `updatedAt` a previous pull already has) to get only what changed since then, so a mirror never has to page /api/v1/packages one package at a time.",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only packages updated at or after this ISO 8601 date-time. Omit for a full export."
          }
        ],
        "responses": {
          "200": {
            "description": "OK — newline-delimited JSON, one CatalogExportEntry per line",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "string",
                  "description": "Newline-delimited JSON; each line is a CatalogExportEntry object.",
                  "items": {
                    "$ref": "#/components/schemas/CatalogExportEntry"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid since",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}": {
      "get": {
        "tags": [
          "packages"
        ],
        "summary": "List one owner's packages",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogPage"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}": {
      "get": {
        "tags": [
          "packages"
        ],
        "summary": "Fetch one package: manifest, README, files, versions",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Package"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/versions": {
      "get": {
        "tags": [
          "versions"
        ],
        "summary": "List a package's published versions",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "versions": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PackageVersionSummary"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/versions/{version}": {
      "get": {
        "tags": [
          "versions"
        ],
        "summary": "Fetch the manifest/README for one specific published version",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "$ref": "#/components/parameters/version"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Package"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/versions/{version}/download": {
      "get": {
        "tags": [
          "versions"
        ],
        "summary": "Download the tarball for a specific version",
        "description": "Sets `ETag` and `X-Checksum-Sha256`. Free packages are served with an immutable cache-control (a version's tarball never changes once published). `If-None-Match` matching the current ETag returns 304.",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "$ref": "#/components/parameters/version"
          }
        ],
        "responses": {
          "200": {
            "description": "Tarball",
            "content": {
              "application/gzip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "X-Checksum-Sha256": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched)"
          },
          "402": {
            "description": "Payment required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "head": {
        "tags": [
          "versions"
        ],
        "summary": "Same as GET with no body; never counts as a download",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "$ref": "#/components/parameters/version"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/download": {
      "get": {
        "tags": [
          "packages",
          "versions"
        ],
        "summary": "Download the latest version's tarball",
        "description": "Equivalent to the versions/{latest}/download route for the package's current `latestVersion`. Also sets `ETag` and `X-Checksum-Sha256`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "name": "runtime",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Informational: which runtime is installing, recorded for install analytics."
          }
        ],
        "responses": {
          "200": {
            "description": "Tarball",
            "content": {
              "application/gzip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "X-Checksum-Sha256": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched)"
          },
          "402": {
            "description": "Payment required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "head": {
        "tags": [
          "packages"
        ],
        "summary": "Same as GET with no body; never counts as a download",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/files/{path}": {
      "get": {
        "tags": [
          "packages"
        ],
        "summary": "Read one raw file from the package",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "name": "path",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Read the file as of a specific published version instead of latest."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "description": "Payment required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/star": {
      "get": {
        "tags": [
          "packages"
        ],
        "summary": "Star count and whether the current caller has starred",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stars": {
                      "type": "integer"
                    },
                    "starred": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "packages"
        ],
        "summary": "Toggle the current caller's star",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "star"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stars": {
                      "type": "integer"
                    },
                    "starred": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Token missing the star scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/status": {
      "post": {
        "tags": [
          "lifecycle"
        ],
        "summary": "Change lifecycle status, or delete",
        "description": "Owner or admin only. `{status, message?, replacementId?}` sets lifecycle status; `{action: \"delete\"}` deletes, but only when the package has zero purchases (409 otherwise) and isn't a seed package (400).",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "status"
                    ],
                    "properties": {
                      "status": {
                        "type": "string",
                        "enum": [
                          "live",
                          "unlisted",
                          "deprecated"
                        ]
                      },
                      "message": {
                        "type": "string"
                      },
                      "replacementId": {
                        "type": "string"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "action"
                    ],
                    "properties": {
                      "action": {
                        "type": "string",
                        "enum": [
                          "delete"
                        ]
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Package"
                }
              }
            }
          },
          "400": {
            "description": "Seed package, or invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not owner/admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Delete requested but purchases exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/report": {
      "post": {
        "tags": [
          "lifecycle"
        ],
        "summary": "Report a package for moderation",
        "description": "Anonymous reporting allowed; rate-limited per IP.",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string",
                    "enum": [
                      "prompt-injection",
                      "malware",
                      "license",
                      "spam",
                      "other"
                    ]
                  },
                  "details": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Recorded"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/reviews": {
      "get": {
        "tags": [
          "reviews"
        ],
        "summary": "List reviews and the rating summary",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "newest",
                "rating",
                "helpful"
              ],
              "default": "newest"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewList"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "reviews"
        ],
        "summary": "Create or update the current user's review (upsert)",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "review"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "rating"
                ],
                "properties": {
                  "rating": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5
                  },
                  "body": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Review"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Owners can't review their own package",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "reviews"
        ],
        "summary": "Delete the current user's review",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "review"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/stats": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Download/star/rating stats for a package",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stats"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Full-text search across name, title, summary, tags, capabilities, owner",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Matched against name, title, summary, owner, tags, and capabilities."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 10,
              "maximum": 50
            }
          },
          {
            "name": "suggest",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Set to 1 for a slim { id, title, kind, ownerType } shape sized for a search-as-you-type dropdown; limit then defaults to 6 (max 10) instead of 10 (max 50)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogPage"
                }
              }
            }
          },
          "400": {
            "description": "Missing q",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tags": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "List every tag in use, with package counts",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tags": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "tag": {
                            "type": "string"
                          },
                          "count": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/publish": {
      "post": {
        "tags": [
          "publish"
        ],
        "summary": "Publish a package or a new version of one",
        "description": "Requires a session or a token with the publish scope. When REQUIRE_REVIEW=1, a brand-new package is created with status `pending` (owner-only until an admin approves); publishing a new version of an existing live package is unaffected.",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "files"
                ],
                "properties": {
                  "files": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "path",
                        "content"
                      ],
                      "properties": {
                        "path": {
                          "type": "string"
                        },
                        "content": {
                          "type": "string",
                          "description": "UTF-8 text, or base64 when encoding is \"base64\"."
                        },
                        "encoding": {
                          "type": "string",
                          "enum": [
                            "utf8",
                            "base64"
                          ],
                          "default": "utf8"
                        },
                        "mode": {
                          "type": "integer",
                          "enum": [
                            420,
                            493
                          ],
                          "description": "POSIX file mode: 420 (0o644, default) or 493 (0o755, executable)."
                        }
                      }
                    }
                  },
                  "changelog": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "live",
                        "unlisted"
                      ]
                    },
                    "scan": {
                      "$ref": "#/components/schemas/ScanResult"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Reserved owner, or token missing the publish scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Version already published",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Database not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/publish/import": {
      "post": {
        "tags": [
          "publish"
        ],
        "summary": "Publish from a public GitHub repository",
        "description": "Fetches files from a public GitHub repo URL and publishes them as if submitted directly. Same validation, limits, and REQUIRE_REVIEW behavior as POST /api/v1/publish. If the repo has its own openagent.yaml at the resolved ref/subdir, that always wins; otherwise the optional `manifest` field, when given, is validated the same way and used instead. Either way, the published manifest's `origin` is forced to the actual repo/commit fetched (and, when `manifest` is what's used, `attested_by` is forced to identify the caller) per the provenance fields in the package format.",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "repo"
                ],
                "properties": {
                  "repo": {
                    "type": "string",
                    "description": "github.com/{owner}/{repo}[/tree/{ref}/{subdir}], or the equivalent fields split out."
                  },
                  "ref": {
                    "type": "string"
                  },
                  "subdir": {
                    "type": "string"
                  },
                  "changelog": {
                    "type": "string"
                  },
                  "manifest": {
                    "type": "string",
                    "description": "A draft openagent.yaml (raw YAML text) to use only when the repo at the resolved ref/subdir has no openagent.yaml of its own. A manifest already in the repo always wins and this field is ignored. The proposal goes through the same schema validation, file-existence check, and ownership rules (e.g. a machine-authenticated caller may still only publish under \"wolfe\") as any other manifest; a repo with neither its own manifest nor a usable proposal here is refused with 400."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "live",
                        "unlisted"
                      ]
                    },
                    "scan": {
                      "$ref": "#/components/schemas/ScanResult"
                    },
                    "manifestSource": {
                      "type": "string",
                      "enum": [
                        "repo",
                        "proposed"
                      ],
                      "description": "Which manifest governed this import: \"repo\" if openagent.yaml was already in the repo (the `manifest` request field, if any, was ignored), \"proposed\" if the repo had none and the `manifest` request field was used instead."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, repo/ref/subdir could not be resolved, or the repo has no openagent.yaml and the proposed `manifest` failed validation or listed a file that doesn't exist in the repo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tokens": {
      "get": {
        "tags": [
          "tokens"
        ],
        "summary": "List the current user's tokens (never returns the plaintext)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tokens": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Token"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "tokens"
        ],
        "summary": "Create a token",
        "description": "Session only — a token cannot mint another token. Max 20 tokens per user.",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "read",
                        "publish",
                        "star",
                        "download"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — plaintext token shown once",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenCreated"
                }
              }
            }
          },
          "400": {
            "description": "At the 20-token limit, or invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tokens/{id}": {
      "delete": {
        "tags": [
          "tokens"
        ],
        "summary": "Revoke a token",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Revoked"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found / not yours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "The current requester (session or token)",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "handle": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string",
                      "nullable": true
                    },
                    "image": {
                      "type": "string",
                      "nullable": true
                    },
                    "via": {
                      "type": "string",
                      "enum": [
                        "session",
                        "token"
                      ]
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/users/{handle}": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "Public profile and packages for a handle",
        "parameters": [
          {
            "name": "handle",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/profile": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "The current user's editable profile",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "users"
        ],
        "summary": "Update the current user's profile",
        "description": "handle is only changeable while the user owns zero packages.",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "bio": {
                    "type": "string"
                  },
                  "website": {
                    "type": "string"
                  },
                  "handle": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                }
              }
            }
          },
          "400": {
            "description": "handle change rejected (packages exist), or invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account/export": {
      "get": {
        "tags": [
          "account"
        ],
        "summary": "Download everything tied to the signed-in account as JSON",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "JSON file download",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountExport"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account": {
      "delete": {
        "tags": [
          "account"
        ],
        "summary": "Permanently delete the signed-in account",
        "description": "Blocked while the account owns a package with at least one sale, or holds an active subscription (as buyer or as a seller with active subscribers).",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "string",
                    "description": "Must exactly equal the caller's own handle."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "400": {
            "description": "confirm doesn't match the handle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Owns a package with sales, or holds an active subscription",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/collections": {
      "get": {
        "tags": [
          "collections"
        ],
        "summary": "List collections",
        "parameters": [
          {
            "name": "featured",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          },
          {
            "name": "owner",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 24,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionList"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "collections"
        ],
        "summary": "Create a collection",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title"
                ],
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string",
                    "description": "Defaults to a slugified title."
                  },
                  "description": {
                    "type": "string"
                  },
                  "isPublic": {
                    "type": "boolean",
                    "default": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Token missing the publish scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Caller already has a collection with this slug",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/collections/{handle}/{slug}": {
      "get": {
        "tags": [
          "collections"
        ],
        "summary": "Fetch one collection, including its items",
        "parameters": [
          {
            "$ref": "#/components/parameters/handle"
          },
          {
            "$ref": "#/components/parameters/slug"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection"
                }
              }
            }
          },
          "404": {
            "description": "Not found, or unlisted and caller isn't the owner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "collections"
        ],
        "summary": "Update a collection",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/handle"
          },
          {
            "$ref": "#/components/parameters/slug"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "isPublic": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not owner/admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "collections"
        ],
        "summary": "Delete a collection",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/handle"
          },
          {
            "$ref": "#/components/parameters/slug"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not owner/admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/collections/{handle}/{slug}/items/{owner}/{name}": {
      "put": {
        "tags": [
          "collections"
        ],
        "summary": "Add, reorder, or annotate a package in a collection",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/handle"
          },
          {
            "$ref": "#/components/parameters/slug"
          },
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "owner": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "note": {
                    "type": "string"
                  },
                  "position": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionItem"
                }
              }
            }
          },
          "400": {
            "description": "Package doesn't exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not owner/admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "collections"
        ],
        "summary": "Remove a package from a collection",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/handle"
          },
          {
            "$ref": "#/components/parameters/slug"
          },
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "204": {
            "description": "Removed"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not owner/admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/collections/{handle}/{slug}": {
      "post": {
        "tags": [
          "admin",
          "collections"
        ],
        "summary": "Toggle a collection's editorial featured flag",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/handle"
          },
          {
            "$ref": "#/components/parameters/slug"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "featured"
                ],
                "properties": {
                  "featured": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/badge": {
      "get": {
        "tags": [
          "packages"
        ],
        "summary": "Embeddable SVG status badge",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "version",
                "downloads",
                "stars",
                "rating"
              ],
              "default": "version"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "SVG badge",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/source": {
      "put": {
        "tags": [
          "sources"
        ],
        "summary": "Link a package to a GitHub repository",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "repo"
                ],
                "properties": {
                  "repo": {
                    "type": "string"
                  },
                  "ref": {
                    "type": "string"
                  },
                  "subdir": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated an existing link",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageSource"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageSource"
                }
              }
            }
          },
          "400": {
            "description": "repo/subdir couldn't be resolved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not owner/admin, or token missing publish",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "sources"
        ],
        "summary": "Read the linked GitHub source (no secret)",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageSource"
                }
              }
            }
          },
          "404": {
            "description": "No source linked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "sources"
        ],
        "summary": "Unlink a GitHub source",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "204": {
            "description": "Unlinked"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not owner/admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No source linked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/source/sync": {
      "post": {
        "tags": [
          "sources"
        ],
        "summary": "Trigger a sync now, without waiting for a webhook",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "Nothing to sync",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "synced": {
                      "type": "boolean"
                    },
                    "reason": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Published a new version",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No source linked, or import failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not owner/admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/queue": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Pending packages and open reports",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/packages/{owner}/{name}": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Approve/reject/feature a pending or existing package",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/reports/{id}": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Resolve or dismiss a report",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/openapi": {
      "get": {
        "tags": [
          "packages"
        ],
        "summary": "This document",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/{rest}": {
      "description": "Catch-all for any /api/v1/* path that doesn't match a defined route.",
      "get": {
        "tags": [
          "packages"
        ],
        "summary": "Unmatched route",
        "responses": {
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "packages"
        ],
        "summary": "Unmatched route",
        "responses": {
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "packages"
        ],
        "summary": "Unmatched route",
        "responses": {
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "packages"
        ],
        "summary": "Unmatched route",
        "responses": {
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "packages"
        ],
        "summary": "Unmatched route",
        "responses": {
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/{nextauth}": {
      "description": "Auth.js v5 sign-in, callback, session, and CSRF endpoints (GitHub, Google).",
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "Auth.js GET routes (session, csrf, providers, callback)",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Auth.js POST routes (signin, signout, callback)",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/checkout": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Create a Stripe Checkout session for a paid package",
        "description": "One-time mode for pricing.model \"one-time\"; subscription mode (a reused Stripe Customer, application_fee_percent applied on every renewal) for \"subscription\".",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "owner",
                  "name"
                ],
                "properties": {
                  "owner": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Purchase can't proceed (free package, already owned, already subscribed, or buying your own package)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Payments not enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/billing/portal": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Create a Stripe billing portal session for the current subscriber",
        "description": "Lets a subscriber update their payment method or cancel a subscription without contacting support.",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingPortal"
                }
              }
            }
          },
          "400": {
            "description": "No Stripe Customer for this account (never subscribed)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Payments not enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/webhooks/stripe": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Stripe webhook receiver",
        "description": "Called by Stripe, verified against STRIPE_WEBHOOK_SECRET. Not intended for direct client calls. Handles checkout.session.completed/async_payment_succeeded/async_payment_failed, charge.refunded, charge.dispute.created/closed, invoice.paid, invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted, the Accounts v2 recipient-configuration events, and the legacy account.updated fallback.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "503": {
            "description": "Payments not enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/webhooks/github/{id}": {
      "post": {
        "tags": [
          "sources"
        ],
        "summary": "GitHub release/tag-push receiver for one linked package source",
        "description": "Verified against the source's per-link secret (HMAC over the raw body, compared to X-Hub-Signature-256), falling back to SOURCE_WEBHOOK_KEY/AUTH_SECRET for the outer request. Imports the manifest at the released/tagged ref and publishes a new version only when its version is strictly greater than the currently published one. Not intended for direct client calls.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "synced": {
                      "type": "boolean"
                    },
                    "version": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Signature didn't verify",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown source id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/connect/onboard": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Create a Stripe Connect onboarding link for the current user",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Payments not enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/collections/{handle}/{slug}/items": {
      "put": {
        "summary": "Add or update a package in a collection (owner or admin)",
        "tags": [
          "Collections"
        ],
        "parameters": [
          {
            "name": "handle",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "owner",
                  "name"
                ],
                "properties": {
                  "owner": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "note": {
                    "type": "string"
                  },
                  "position": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Item added or updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionItem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or too many items"
          },
          "401": {
            "description": "Unauthenticated"
          },
          "403": {
            "description": "Not the owner"
          },
          "404": {
            "description": "Collection or package not found"
          },
          "429": {
            "description": "Rate limited"
          },
          "503": {
            "description": "Database not configured"
          }
        }
      }
    },
    "/api/v1/orgs": {
      "get": {
        "tags": [
          "organizations"
        ],
        "summary": "List organizations, or the caller's own memberships",
        "parameters": [
          {
            "name": "member",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "me"
              ]
            },
            "description": "Set to `me` (session/token required) to list only organizations the caller belongs to."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 24,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Organization"
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "?member=me without a session/token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "organizations"
        ],
        "summary": "Create an organization",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "handle",
                  "displayName"
                ],
                "properties": {
                  "handle": {
                    "type": "string"
                  },
                  "displayName": {
                    "type": "string"
                  },
                  "bio": {
                    "type": "string"
                  },
                  "website": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Organization"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or reserved handle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Handle already taken",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{handle}": {
      "get": {
        "tags": [
          "organizations"
        ],
        "summary": "Fetch one organization",
        "parameters": [
          {
            "$ref": "#/components/parameters/orgHandle"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Organization"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "organizations"
        ],
        "summary": "Update an organization",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/orgHandle"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "displayName": {
                    "type": "string"
                  },
                  "bio": {
                    "type": "string"
                  },
                  "website": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Organization"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an owner/admin member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "organizations"
        ],
        "summary": "Delete an organization",
        "description": "Owner member only, and only once the organization owns zero packages.",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/orgHandle"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an owner member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Organization still owns one or more packages",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{handle}/members": {
      "put": {
        "tags": [
          "organizations"
        ],
        "summary": "Add a member, or change an existing member's role",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/orgHandle"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "handle",
                  "role"
                ],
                "properties": {
                  "handle": {
                    "type": "string"
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "owner",
                      "admin",
                      "member"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK — the updated membership list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OrganizationMember"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`handle` isn't a known user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an owner/admin member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Organization doesn't exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orgs/{handle}/members/{userHandle}": {
      "delete": {
        "tags": [
          "organizations"
        ],
        "summary": "Remove a member, or leave",
        "description": "Owner/admin member to remove someone else; any member can remove themself. The organization's last remaining owner can't leave.",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/orgHandle"
          },
          {
            "$ref": "#/components/parameters/userHandle"
          }
        ],
        "responses": {
          "204": {
            "description": "Removed"
          },
          "400": {
            "description": "userHandle is the organization's last remaining owner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an owner/admin, and not removing self",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Organization doesn't exist, or userHandle isn't a member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/transfer": {
      "post": {
        "tags": [
          "packages",
          "organizations"
        ],
        "summary": "Transfer a package to another user or organization",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "publish"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "to"
                ],
                "properties": {
                  "to": {
                    "type": "string",
                    "description": "A user or organization handle."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK — the updated package",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Package"
                }
              }
            }
          },
          "400": {
            "description": "`to` doesn't exist, or names an org the caller isn't an owner/admin member of",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not the current owner/admin, or token missing publish",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Package doesn't exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/advisories": {
      "get": {
        "tags": [
          "trust-safety"
        ],
        "summary": "List open advisories for a package",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Advisory"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Package doesn't exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "trust-safety"
        ],
        "summary": "Post a security advisory (admin only)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "severity",
                  "title",
                  "body"
                ],
                "properties": {
                  "severity": {
                    "type": "string",
                    "enum": [
                      "low",
                      "moderate",
                      "high",
                      "critical"
                    ]
                  },
                  "title": {
                    "type": "string"
                  },
                  "body": {
                    "type": "string"
                  },
                  "affectedVersions": {
                    "type": "string"
                  },
                  "fixedInVersion": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Advisory"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Package doesn't exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/advisories/{id}": {
      "patch": {
        "tags": [
          "trust-safety"
        ],
        "summary": "Edit or withdraw a security advisory (admin only)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "$ref": "#/components/parameters/advisoryId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "severity": {
                    "type": "string",
                    "enum": [
                      "low",
                      "moderate",
                      "high",
                      "critical"
                    ]
                  },
                  "title": {
                    "type": "string"
                  },
                  "body": {
                    "type": "string"
                  },
                  "affectedVersions": {
                    "type": "string"
                  },
                  "fixedInVersion": {
                    "type": "string"
                  },
                  "withdraw": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Advisory"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Package or advisory id doesn't exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/scans": {
      "get": {
        "tags": [
          "trust-safety",
          "admin"
        ],
        "summary": "Recently-published versions by scan score (admin only)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "name": "min",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 100
            },
            "description": "Minimum scan score to include."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "owner": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "version": {
                            "type": "string"
                          },
                          "score": {
                            "type": "integer"
                          },
                          "flags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "publishedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "status": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/packages/{owner}/{name}/versions/{version}/diff": {
      "get": {
        "tags": [
          "versions"
        ],
        "summary": "Per-file diff between two published versions",
        "parameters": [
          {
            "$ref": "#/components/parameters/owner"
          },
          {
            "$ref": "#/components/parameters/name"
          },
          {
            "$ref": "#/components/parameters/version"
          },
          {
            "name": "against",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Version to diff against; defaults to the version immediately before {version} in publish order."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Diff"
                }
              }
            }
          },
          "400": {
            "description": "`against` doesn't name a published version of this package",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Paid package, non-preview file, caller hasn't purchased/doesn't own it",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Package, version, or `against` doesn't exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/validate": {
      "post": {
        "tags": [
          "publish"
        ],
        "summary": "Validate package files without publishing",
        "description": "No authentication required; no side effects. Same `files` shape as POST /api/v1/publish.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "files"
                ],
                "properties": {
                  "files": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "path",
                        "content"
                      ],
                      "properties": {
                        "path": {
                          "type": "string"
                        },
                        "content": {
                          "type": "string"
                        },
                        "encoding": {
                          "type": "string",
                          "enum": [
                            "utf8",
                            "base64"
                          ],
                          "default": "utf8"
                        },
                        "mode": {
                          "type": "integer",
                          "enum": [
                            420,
                            493
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidateResult"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/refunds": {
      "get": {
        "tags": [
          "refunds"
        ],
        "summary": "List refund requests (as buyer or as seller)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "name": "mine",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "The caller's own requests as a buyer."
          },
          {
            "name": "seller",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Requests against packages the caller owns."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RefundRequest"
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "refunds"
        ],
        "summary": "Request a refund on a one-time purchase",
        "security": [
          {
            "sessionCookie": []
          },
          {
            "bearerToken": [
              "download"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "purchaseId",
                  "reason"
                ],
                "properties": {
                  "purchaseId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundRequest"
                }
              }
            }
          },
          "400": {
            "description": "Purchase is a subscription, or is more than 14 days old",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "purchaseId doesn't exist or isn't the caller's",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "A refund request already exists for this purchase",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/refunds/{id}": {
      "post": {
        "tags": [
          "refunds"
        ],
        "summary": "Approve or deny a refund request",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/refundId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "approve",
                      "deny"
                    ]
                  },
                  "note": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK — the updated refund request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundRequest"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not the seller and not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Refund request doesn't exist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Already resolved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/refunds": {
      "get": {
        "tags": [
          "refunds",
          "admin"
        ],
        "summary": "Every refund request across the platform (admin only)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "purchaseId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "owner": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "buyerHandle": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "resolvedAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/analytics": {
      "get": {
        "tags": [
          "ops",
          "admin"
        ],
        "summary": "Platform-wide analytics (admin only)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Analytics"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/cron/rollup-downloads": {
      "post": {
        "tags": [
          "ops"
        ],
        "summary": "Aggregate the prior day's download_events into download_rollups (daily)",
        "description": "Internal — invoked by Vercel Cron, not intended for direct client calls.",
        "security": [
          {
            "cronSecret": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "processed": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or incorrect bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/cron/cleanup": {
      "post": {
        "tags": [
          "ops"
        ],
        "summary": "Expire stale rate-limit windows and abandoned checkout artifacts (hourly)",
        "description": "Internal — invoked by Vercel Cron, not intended for direct client calls.",
        "security": [
          {
            "cronSecret": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "processed": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or incorrect bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/cron/review-reminders": {
      "post": {
        "tags": [
          "ops"
        ],
        "summary": "Email reminders for packages stuck in review/scan-flagged status (daily)",
        "description": "Internal — invoked by Vercel Cron, not intended for direct client calls.",
        "security": [
          {
            "cronSecret": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "processed": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or incorrect bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/cron/daily": {
      "get": {
        "summary": "Run every scheduled job once (rollup, cleanup, review reminders)",
        "tags": [
          "ops"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "All jobs ran; per-job results keyed by name"
          },
          "401": {
            "description": "Missing or wrong CRON_SECRET"
          },
          "500": {
            "description": "At least one job failed (results still included)"
          },
          "503": {
            "description": "CRON_SECRET not configured"
          }
        }
      }
    },
    "/api/v1": {
      "get": {
        "summary": "Bare API prefix — not an endpoint; returns the standard JSON 404 with a pointer to the docs",
        "tags": [
          "meta"
        ],
        "responses": {
          "404": {
            "description": "Always: { error: \"not found; see /docs/api for the endpoint list\" }",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  }
}
