{
  "openapi": "3.1.0",
  "info": {
    "title": "pre.dev API",
    "description": "Public REST API for software specifications, browser automation, proposal assessment, and credit balance. Base URL: https://api.pre.dev. MCP is documented separately at https://docs.pre.dev/mcp/tools.",
    "version": "1.1.0",
    "contact": {
      "name": "pre.dev Support",
      "url": "https://pre.dev",
      "email": "support@pre.dev"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://pre.dev/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.pre.dev",
      "description": "Production API Server"
    }
  ],
  "security": [
    {
      "apiKeyAuth": []
    },
    {
      "xApiKey": []
    }
  ],
  "paths": {
    "/fast-spec": {
      "post": {
        "operationId": "generateFastSpec",
        "tags": [
          "Specifications"
        ],
        "summary": "Generate a fast spec",
        "description": "Supply JSON text or one multipart file. Use async=true for durable ID-based polling. Duplicate submissions create separate jobs; no idempotency key is supported.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpecRequest"
              },
              "example": {
                "input": "Build a team task manager with projects, assignees, and due dates.",
                "async": true
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FileUploadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Full result for synchronous requests; specId and pending status for asynchronous requests.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/SpecResponse"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "completed"
                              ]
                            }
                          }
                        }
                      ]
                    },
                    {
                      "$ref": "#/components/schemas/AsyncResponse"
                    }
                  ]
                },
                "examples": {
                  "submitted": {
                    "summary": "Async submission",
                    "value": {
                      "specId": "507f1f77bcf86cd799439011",
                      "status": "pending"
                    }
                  },
                  "completed": {
                    "summary": "Synchronous completion (illustrative)",
                    "value": {
                      "_id": "507f1f77bcf86cd799439011",
                      "endpoint": "fast_spec",
                      "status": "completed",
                      "success": true,
                      "progress": 100,
                      "codingAgentSpecMarkdown": "# Task manager\n\nProjects, assignments, and due dates."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient balance or a billing gate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl --fail-with-body https://api.pre.dev/fast-spec \\\n  -H \"Authorization: Bearer $PREDEV_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"input\": \"Build a team task manager with projects, assignees, and due dates.\",\n  \"async\": true\n}'"
          }
        ]
      }
    },
    "/deep-spec": {
      "post": {
        "operationId": "generateDeepSpec",
        "tags": [
          "Specifications"
        ],
        "summary": "Generate a deep spec",
        "description": "Supply JSON text or one multipart file. Use async=true for durable ID-based polling. Duplicate submissions create separate jobs; no idempotency key is supported.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpecRequest"
              },
              "example": {
                "input": "Build a team task manager with projects, assignees, and due dates.",
                "async": true
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FileUploadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Full result for synchronous requests; specId and pending status for asynchronous requests.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/SpecResponse"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "completed"
                              ]
                            }
                          }
                        }
                      ]
                    },
                    {
                      "$ref": "#/components/schemas/AsyncResponse"
                    }
                  ]
                },
                "examples": {
                  "submitted": {
                    "summary": "Async submission",
                    "value": {
                      "specId": "507f1f77bcf86cd799439011",
                      "status": "pending"
                    }
                  },
                  "completed": {
                    "summary": "Synchronous completion (illustrative)",
                    "value": {
                      "_id": "507f1f77bcf86cd799439011",
                      "endpoint": "deep_spec",
                      "status": "completed",
                      "success": true,
                      "progress": 100,
                      "codingAgentSpecMarkdown": "# Task manager\n\nProjects, assignments, and due dates."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient balance or a billing gate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl --fail-with-body https://api.pre.dev/deep-spec \\\n  -H \"Authorization: Bearer $PREDEV_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"input\": \"Build a team task manager with projects, assignees, and due dates.\",\n  \"async\": true\n}'"
          }
        ]
      }
    },
    "/spec-status/{specId}": {
      "get": {
        "operationId": "getSpecStatus",
        "tags": [
          "Specifications"
        ],
        "summary": "Get a spec",
        "description": "Poll until status is completed or failed. Includes available artifacts; progress alone is not a completion signal.",
        "parameters": [
          {
            "name": "specId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "24-character record ID.",
              "pattern": "^[a-fA-F0-9]{24}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current spec record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpecResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/list-specs": {
      "get": {
        "operationId": "listSpecs",
        "tags": [
          "Specifications"
        ],
        "summary": "List specs",
        "description": "Newest first. Summary records omit Markdown, JSON, graphs, and credit details. Unrecognized status or endpoint filters are ignored.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "endpoint",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "fast_spec",
                "deep_spec"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "processing",
                "completed",
                "failed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated spec summaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListSpecsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/find-specs": {
      "get": {
        "operationId": "findSpecs",
        "tags": [
          "Specifications"
        ],
        "summary": "Search specs",
        "description": "Newest first. Summary records omit Markdown, JSON, graphs, and credit details. Unrecognized status or endpoint filters are ignored.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Case-insensitive regular expression matched against spec input. Invalid syntax returns 500."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "endpoint",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "fast_spec",
                "deep_spec"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "processing",
                "completed",
                "failed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated spec summaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListSpecsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/credits-balance": {
      "get": {
        "operationId": "getCreditsBalance",
        "tags": [
          "Account"
        ],
        "summary": "Get credit balance",
        "description": "Returns the effective account or organization balance. Fractional credits are possible.",
        "responses": {
          "200": {
            "description": "Credit balance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditsBalanceResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/browser-agent": {
      "post": {
        "operationId": "runTask",
        "tags": [
          "Browser Agents"
        ],
        "summary": "Run browser tasks",
        "description": "Default: synchronous JSON. async=true returns an ID. stream=true takes precedence and returns SSE task_event, task_result, done (full result), or error. A matching retry key returns JSON even when stream=true. A disconnected client does not cancel execution.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Optional user-scoped 24-hour retry lookup. Reuse only for the same logical submission; concurrent first requests can still duplicate work."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              },
              "example": {
                "tasks": [
                  {
                    "url": "https://example.com",
                    "instruction": "Extract the main page heading.",
                    "output": {
                      "type": "object",
                      "properties": {
                        "heading": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "heading"
                      ]
                    },
                    "mode": "extract",
                    "maxSteps": 10,
                    "maxDurationSeconds": 60
                  }
                ],
                "async": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch result, asynchronous ID, or SSE stream. Inspect Content-Type before parsing. A done batch can contain failed tasks; inspect each task status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                },
                "examples": {
                  "submitted": {
                    "summary": "Async submission",
                    "value": {
                      "id": "507f1f77bcf86cd799439011",
                      "total": 1,
                      "completed": 0,
                      "results": [],
                      "totalCreditsUsed": 0,
                      "status": "processing"
                    }
                  },
                  "completed": {
                    "summary": "Completed run (illustrative)",
                    "value": {
                      "id": "507f1f77bcf86cd799439011",
                      "total": 1,
                      "completed": 1,
                      "results": [
                        {
                          "url": "https://example.com",
                          "status": "SUCCESS",
                          "data": {
                            "heading": "Example Domain"
                          },
                          "creditsUsed": 0.1
                        }
                      ],
                      "totalCreditsUsed": 0.1,
                      "status": "completed"
                    }
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "event: task_event\ndata: {\"taskIndex\":0,\"type\":\"navigation\",\"timestamp\":1788739200000,\"data\":{\"url\":\"https://example.com\"}}\n\nevent: task_result\ndata: {\"taskIndex\":0,\"status\":\"SUCCESS\",\"data\":{\"title\":\"Example Domain\"},\"creditsUsed\":0.1}\n\nevent: done\ndata: {\"id\":\"64b7f3e1c2a9d5e6f8a01234\",\"status\":\"completed\",\"total\":1,\"completed\":1,\"results\":[{\"status\":\"SUCCESS\",\"data\":{\"title\":\"Example Domain\"},\"creditsUsed\":0.1}],\"totalCreditsUsed\":0.1}\n\n"
              }
            }
          },
          "400": {
            "description": "Invalid task input, malformed or unresolvable URL, missing instructions/output schema, or oversized batch. No work is started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient balance or a billing gate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate or inflight limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Streaming capacity unavailable, or temporary DNS verification failure (URL_CHECK_UNAVAILABLE). No tasks start when input verification fails.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl --fail-with-body https://api.pre.dev/browser-agent \\\n  -H \"Authorization: Bearer $PREDEV_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"tasks\": [\n    {\n      \"url\": \"https://example.com\",\n      \"instruction\": \"Extract the main page heading.\",\n      \"output\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"heading\": {\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"heading\"\n        ]\n      },\n      \"mode\": \"extract\",\n      \"maxSteps\": 10,\n      \"maxDurationSeconds\": 60\n    }\n  ],\n  \"async\": true\n}'"
          }
        ]
      }
    },
    "/browser-agent/{id}": {
      "get": {
        "operationId": "getRun",
        "tags": [
          "Browser Agents"
        ],
        "summary": "Get browser task status",
        "description": "Use batch status for completion, then each task status for success. The completed counter includes placeholder slots.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "24-character record ID.",
              "pattern": "^[a-fA-F0-9]{24}$"
            }
          },
          {
            "name": "includeEvents",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Batch with available results and optional events.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                },
                "examples": {
                  "processing": {
                    "summary": "Processing with placeholders",
                    "value": {
                      "id": "507f1f77bcf86cd799439011",
                      "total": 1,
                      "completed": 1,
                      "results": [
                        {
                          "url": "https://example.com",
                          "status": "RUNNING",
                          "queuePosition": 0,
                          "attempts": 1
                        }
                      ],
                      "totalCreditsUsed": 0,
                      "status": "processing"
                    }
                  },
                  "completed": {
                    "summary": "Completed run (illustrative)",
                    "value": {
                      "id": "507f1f77bcf86cd799439011",
                      "total": 1,
                      "completed": 1,
                      "results": [
                        {
                          "url": "https://example.com",
                          "status": "SUCCESS",
                          "data": {
                            "heading": "Example Domain"
                          },
                          "creditsUsed": 0.1
                        }
                      ],
                      "totalCreditsUsed": 0.1,
                      "status": "completed"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/list-browser-agents": {
      "get": {
        "operationId": "listRuns",
        "tags": [
          "Browser Agents"
        ],
        "summary": "List browser runs",
        "description": "Newest first; use the detail endpoint for complete task results.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "processing",
                "completed",
                "failed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated run summaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListBatchesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/browser-agent-status": {
      "get": {
        "operationId": "browserAgentStatus",
        "tags": [
          "Browser Agents"
        ],
        "summary": "Get account queue status",
        "description": "Snapshot of your queue and current inflight cap; does not reserve capacity.",
        "responses": {
          "200": {
            "description": "Account queue snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrowserAgentStatus"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/browser-agent-capacity": {
      "get": {
        "operationId": "browserAgentCapacity",
        "tags": [
          "Browser Agents"
        ],
        "summary": "Get service capacity",
        "description": "Advisory service diagnostics. Prefer /browser-agent-status for admission decisions.",
        "responses": {
          "200": {
            "description": "Service capacity snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrowserCapacity"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/browser-agent/{id}/ws": {
      "get": {
        "operationId": "getLiveBrowser",
        "tags": [
          "Browser Agents"
        ],
        "summary": "Get a live browser URL",
        "description": "Returns a credential-bearing WebSocket URL for live JPEG frames. Availability depends on the execution path. No browser input control or recorded playback.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "24-character record ID.",
              "pattern": "^[a-fA-F0-9]{24}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Connect to the returned WebSocket URL.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LiveBrowserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/browser-agent/{id}/stream": {
      "get": {
        "operationId": "streamBrowserAgent",
        "tags": [
          "Browser Agents"
        ],
        "summary": "Watch an existing browser run",
        "description": "SSE: snapshot, batch_meta, task_event, task_result, done, error. The done payload is status only, unlike POST streaming. Already finished runs emit snapshot then done. No replay cursor; reconnect for a fresh snapshot, or poll after interruption.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "24-character record ID.",
              "pattern": "^[a-fA-F0-9]{24}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "SSE stream. Errors after headers arrive as error events, not new HTTP status codes.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "event: snapshot\ndata: {\"id\":\"64b7f3e1c2a9d5e6f8a01234\",\"status\":\"processing\",\"total\":1,\"completed\":1,\"results\":[{\"status\":\"PENDING\"}]}\n\nevent: batch_meta\ndata: {\"name\":\"Example lookup\",\"taskNames\":[\"Read title\"]}\n\nevent: task_result\ndata: {\"taskIndex\":0,\"status\":\"SUCCESS\",\"data\":{\"title\":\"Example Domain\"},\"creditsUsed\":0.1}\n\nevent: done\ndata: {\"status\":\"completed\"}\n\n"
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Streaming capacity unavailable; retry later or use polling.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "xApiKey": []
          },
          {
            "streamQueryKey": []
          }
        ]
      }
    },
    "/upload-proposal": {
      "post": {
        "operationId": "uploadProposal",
        "tags": [
          "Proposals"
        ],
        "summary": "Upload a proposal",
        "description": "Store a proposal from text or one supported file. proposalName is required.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadProposalRequest"
              },
              "example": {
                "proposalName": "Task manager implementation",
                "text": "Projects, assignees, and due dates delivered in three milestones."
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/UploadProposalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Stored proposal ID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadProposalResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl --fail-with-body https://api.pre.dev/upload-proposal \\\n  -H \"Authorization: Bearer $PREDEV_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"proposalName\": \"Task manager implementation\",\n  \"text\": \"Projects, assignees, and due dates delivered in three milestones.\"\n}'"
          }
        ]
      }
    },
    "/list-proposals": {
      "get": {
        "operationId": "listProposals",
        "tags": [
          "Proposals"
        ],
        "summary": "List proposals",
        "description": "Newest first in the caller context.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated proposals.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "proposals",
                    "total",
                    "hasMore"
                  ],
                  "properties": {
                    "proposals": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Proposal"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "hasMore": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/get-proposal/{proposalId}": {
      "get": {
        "operationId": "getProposal",
        "tags": [
          "Proposals"
        ],
        "summary": "Get a proposal",
        "description": "Retrieve a stored proposal by ID.",
        "parameters": [
          {
            "name": "proposalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "24-character record ID.",
              "pattern": "^[a-fA-F0-9]{24}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Stored proposal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Proposal"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/vet-proposal": {
      "post": {
        "operationId": "vetProposal",
        "tags": [
          "Proposals"
        ],
        "summary": "Vet a proposal",
        "description": "Compare an existing proposal, or upload and compare a new one, against a spec. Charges 100 credits before later proposal validation and lookup. Confirm inputs first; a failed request does not guarantee a refund. No async mode or idempotency key.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VetProposalRequest"
              },
              "example": {
                "specId": "507f1f77bcf86cd799439011",
                "proposalId": "507f1f77bcf86cd799439012"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/VetProposalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Assessment and proposal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VetProposalResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient balance or a billing gate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl --fail-with-body https://api.pre.dev/vet-proposal \\\n  -H \"Authorization: Bearer $PREDEV_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"specId\": \"507f1f77bcf86cd799439011\",\n  \"proposalId\": \"507f1f77bcf86cd799439012\"\n}'"
          }
        ]
      }
    },
    "/list-vetted-proposals": {
      "get": {
        "operationId": "listVettedProposals",
        "tags": [
          "Proposals"
        ],
        "summary": "List proposal assessments",
        "description": "Newest first. Each assessment includes a compact proposal name/file summary when available.",
        "parameters": [
          {
            "name": "specId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "24-character record ID.",
              "pattern": "^[a-fA-F0-9]{24}$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated assessments.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "vettedProposals",
                    "total",
                    "hasMore"
                  ],
                  "properties": {
                    "vettedProposals": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VettedProposalSummary"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "hasMore": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/get-vetted-proposal/{vettedProposalId}": {
      "get": {
        "operationId": "getVettedProposal",
        "tags": [
          "Proposals"
        ],
        "summary": "Get a proposal assessment",
        "description": "Fetch a saved assessment record.",
        "parameters": [
          {
            "name": "vettedProposalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "24-character record ID.",
              "pattern": "^[a-fA-F0-9]{24}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved assessment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VettedProposal"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or ineligible authentication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Access or trial eligibility denied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Request failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "Use a pre.dev API key from https://pre.dev/projects/key."
      },
      "xApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Alternative to Authorization: Bearer."
      },
      "streamQueryKey": {
        "type": "apiKey",
        "in": "query",
        "name": "apiKey",
        "description": "GET batch stream only. Prefer a header: URLs can be recorded in logs."
      }
    },
    "schemas": {
      "SpecRequest": {
        "type": "object",
        "required": [
          "input"
        ],
        "properties": {
          "input": {
            "type": "string",
            "description": "Project requirements. Include goals, users, constraints, and acceptance criteria.",
            "minLength": 1
          },
          "currentContext": {
            "type": "string",
            "description": "Existing system or specification as text; this is not a spec ID."
          },
          "docURLs": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "description": "Public documentation URLs; retrieval and downloadable archives are best effort."
          },
          "async": {
            "type": "boolean",
            "default": false,
            "description": "Return {specId, status: pending} immediately. Poll GET /spec-status/{specId}."
          }
        }
      },
      "FileUploadRequest": {
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "description": "One PDF, DOC, DOCX, TXT, JPEG, or PNG file, at most 20 MiB. Send the matching MIME type.",
            "format": "binary"
          },
          "input": {
            "type": "string",
            "description": "Requirements, used alone or with the file.",
            "minLength": 1
          },
          "currentContext": {
            "type": "string",
            "description": "Existing system context as text."
          },
          "docURLs": {
            "type": "string",
            "description": "JSON-encoded array of public documentation URLs.",
            "example": "[\"https://example.com/docs\"]"
          },
          "async": {
            "type": "boolean",
            "default": false
          }
        },
        "anyOf": [
          {
            "required": [
              "file"
            ]
          },
          {
            "required": [
              "input"
            ]
          }
        ]
      },
      "SpecResponse": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "_id": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "created": {
            "type": "string",
            "format": "date-time"
          },
          "endpoint": {
            "type": "string",
            "enum": [
              "fast_spec",
              "deep_spec"
            ],
            "description": "Which endpoint was used"
          },
          "input": {
            "type": "string",
            "description": "Original input text provided"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "success": {
            "type": "boolean",
            "description": "Whether the request succeeded"
          },
          "uploadedFileShortUrl": {
            "anyOf": [
              {
                "type": "string",
                "description": "Short URL for uploaded file (if file was uploaded)"
              },
              {
                "type": "null"
              }
            ]
          },
          "uploadedFileName": {
            "anyOf": [
              {
                "type": "string",
                "description": "Name of uploaded file (if file was uploaded)"
              },
              {
                "type": "null"
              }
            ]
          },
          "humanSpecUrl": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "description": "URL where the human-readable spec is hosted (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "totalHumanHours": {
            "anyOf": [
              {
                "type": "number",
                "description": "Estimated total hours for a human to implement the spec (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "architectureInfographicUrl": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "description": "URL to a visual architecture infographic/diagram for the specification (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "codingAgentSpecUrl": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "description": "URL where the coding agent spec format is hosted (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "codingAgentSpecJson": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CodingAgentSpecJson",
                "description": "Structured JSON spec optimized for AI coding assistants (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "codingAgentSpecMarkdown": {
            "anyOf": [
              {
                "type": "string",
                "description": "Markdown spec optimized for AI coding assistants (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "humanSpecJson": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/HumanSpecJson",
                "description": "Full structured JSON spec with hours, personas, and roles (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "humanSpecMarkdown": {
            "anyOf": [
              {
                "type": "string",
                "description": "Full markdown spec with all details for human review (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "executionTime": {
            "anyOf": [
              {
                "type": "integer",
                "description": "Processing time in milliseconds (only when completed or failed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "predevUrl": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "description": "pre.dev project URL (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "zippedDocsUrls": {
            "anyOf": [
              {
                "type": "array",
                "description": "Array of scraped documentation archives (only when completed). Empty array if no docURLs provided or scraping fails",
                "items": {
                  "$ref": "#/components/schemas/ZippedDocsUrl"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "errorMessage": {
            "anyOf": [
              {
                "type": "string",
                "description": "Error description (only when failed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "progress": {
            "anyOf": [
              {
                "type": "number",
                "description": "Completion percentage (0-100) while processing"
              },
              {
                "type": "null"
              }
            ]
          },
          "creditsUsed": {
            "anyOf": [
              {
                "type": "number",
                "description": "Measured credit usage; estimates are not fixed charges."
              },
              {
                "type": "null"
              }
            ]
          },
          "userFlowGraph": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SpecGraph",
                "description": "User flow graph with nodes representing user stories/flows and edges showing navigation paths (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "architectureGraph": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SpecGraph",
                "description": "System architecture graph with C1/C2 level nodes and their relationships (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "enrichedTechStack": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SpecEnrichedTechStackItem"
                },
                "description": "Enriched tech stack with detailed reasons, descriptions, and alternatives for each technology (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "progressMessage": {
            "anyOf": [
              {
                "type": "string",
                "description": "Human-readable progress description (e.g. 'Generating architecture...')"
              },
              {
                "type": "null"
              }
            ]
          },
          "currentContext": {
            "anyOf": [
              {
                "type": "string",
                "description": "Existing context supplied with generation."
              },
              {
                "type": "null"
              }
            ]
          },
          "specSource": {
            "anyOf": [
              {
                "type": "string",
                "description": "Origin of the request, such as api or mcp."
              },
              {
                "type": "null"
              }
            ]
          },
          "docURLs": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "Full specification/status record. Fields may be absent or null until available. Terminal status is completed or failed. executionTime is milliseconds."
      },
      "AsyncResponse": {
        "type": "object",
        "required": [
          "specId",
          "status"
        ],
        "properties": {
          "specId": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending"
            ]
          }
        }
      },
      "StatusResponse": {
        "$ref": "#/components/schemas/SpecResponse"
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string",
            "description": "Optional detail; not returned by every endpoint."
          },
          "code": {
            "type": "string",
            "description": "Machine-readable code when available."
          },
          "actionUrl": {
            "type": "string",
            "format": "uri"
          },
          "requiresSubscription": {
            "type": "boolean"
          },
          "trialsUsed": {
            "type": "integer"
          },
          "maxTrials": {
            "type": "integer"
          }
        },
        "additionalProperties": true
      },
      "InsufficientCreditsError": {
        "type": "object",
        "required": [
          "error",
          "message",
          "generationsAvailable"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "generationsAvailable": {
            "type": "number",
            "description": "Legacy field name containing the remaining credit balance, not a count of spec runs."
          }
        }
      },
      "ListSpecsResponse": {
        "type": "object",
        "required": [
          "specs",
          "total",
          "hasMore"
        ],
        "properties": {
          "specs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecSummary"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "hasMore": {
            "type": "boolean"
          }
        }
      },
      "ZippedDocsUrl": {
        "type": "object",
        "required": [
          "platform",
          "masterZipShortUrl"
        ],
        "properties": {
          "platform": {
            "type": "string",
            "description": "Hostname extracted from the documentation URL (e.g., 'stripe.com', 'docs.github.com')",
            "example": "stripe.com"
          },
          "masterZipShortUrl": {
            "type": "string",
            "format": "uri",
            "description": "Short URL to download the zipped documentation archive for this platform"
          },
          "masterMarkdownShortUrl": {
            "type": "string",
            "format": "uri",
            "description": "Optional short URL to consolidated markdown file for this platform"
          }
        }
      },
      "SpecCoreFunctionality": {
        "type": "object",
        "required": [
          "name",
          "description"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the core functionality"
          },
          "description": {
            "type": "string",
            "description": "Description of the functionality"
          },
          "priority": {
            "type": "string",
            "enum": [
              "High",
              "Medium",
              "Low"
            ],
            "description": "Priority level of the functionality"
          }
        }
      },
      "SpecTechStackItem": {
        "type": "object",
        "required": [
          "name",
          "category"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the technology"
          },
          "category": {
            "type": "string",
            "description": "Category of the technology (e.g., Frontend, Backend, Database)"
          }
        }
      },
      "SpecPersona": {
        "type": "object",
        "required": [
          "title",
          "description"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Title of the persona"
          },
          "description": {
            "type": "string",
            "description": "Description of the persona"
          },
          "primaryGoals": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Primary goals of the persona"
          },
          "painPoints": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Pain points of the persona"
          },
          "keyTasks": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Key tasks of the persona"
          }
        }
      },
      "SpecRole": {
        "type": "object",
        "required": [
          "name",
          "shortHand"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Full name of the role (e.g., Full Stack Developer)"
          },
          "shortHand": {
            "type": "string",
            "description": "Short abbreviation for the role (e.g., FSD)"
          }
        }
      },
      "CodingAgentSubTask": {
        "type": "object",
        "required": [
          "description",
          "complexity"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Subtask identifier"
          },
          "description": {
            "type": "string",
            "description": "Description of the subtask"
          },
          "complexity": {
            "type": "string",
            "enum": [
              "S",
              "M",
              "L",
              "XL"
            ],
            "description": "Complexity estimate"
          }
        }
      },
      "CodingAgentStory": {
        "type": "object",
        "required": [
          "title",
          "subTasks"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Story identifier (e.g., US-001)"
          },
          "title": {
            "type": "string",
            "description": "Title of the user story"
          },
          "description": {
            "type": "string",
            "description": "Description of the user story"
          },
          "acceptanceCriteria": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of acceptance criteria"
          },
          "complexity": {
            "type": "string",
            "description": "Complexity estimate for the story"
          },
          "subTasks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CodingAgentSubTask"
            },
            "description": "List of subtasks for this story"
          }
        }
      },
      "CodingAgentMilestone": {
        "type": "object",
        "required": [
          "milestoneNumber",
          "description",
          "stories"
        ],
        "properties": {
          "milestoneNumber": {
            "type": "integer",
            "description": "Milestone number"
          },
          "description": {
            "type": "string",
            "description": "Description of the milestone"
          },
          "stories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CodingAgentStory"
            },
            "description": "List of user stories in this milestone"
          }
        }
      },
      "CodingAgentSpecJson": {
        "type": "object",
        "required": [
          "executiveSummary",
          "coreFunctionalities",
          "techStack",
          "milestones"
        ],
        "description": "Simplified structured JSON for AI coding tools (excludes hours, personas, roles)",
        "properties": {
          "title": {
            "type": "string",
            "description": "Title of the specification"
          },
          "executiveSummary": {
            "type": "string",
            "description": "Executive summary of the project"
          },
          "coreFunctionalities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecCoreFunctionality"
            },
            "description": "List of core functionalities"
          },
          "techStack": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecTechStackItem"
            },
            "description": "Technology stack items"
          },
          "techStackGrouped": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Technology stack grouped by category"
          },
          "milestones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CodingAgentMilestone"
            },
            "description": "List of milestones"
          }
        }
      },
      "HumanSpecSubTask": {
        "type": "object",
        "required": [
          "description",
          "hours",
          "complexity"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Subtask identifier"
          },
          "description": {
            "type": "string",
            "description": "Description of the subtask"
          },
          "hours": {
            "type": "number",
            "description": "Estimated hours for this subtask"
          },
          "complexity": {
            "type": "string",
            "description": "Complexity estimate"
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecRole"
            },
            "description": "Roles assigned to this subtask"
          }
        }
      },
      "HumanSpecStory": {
        "type": "object",
        "required": [
          "title",
          "hours",
          "subTasks"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Story identifier (e.g., US-001)"
          },
          "title": {
            "type": "string",
            "description": "Title of the user story"
          },
          "description": {
            "type": "string",
            "description": "Description of the user story"
          },
          "acceptanceCriteria": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of acceptance criteria"
          },
          "hours": {
            "type": "number",
            "description": "Estimated hours for this story"
          },
          "complexity": {
            "type": "string",
            "description": "Complexity estimate for the story"
          },
          "subTasks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HumanSpecSubTask"
            },
            "description": "List of subtasks for this story"
          }
        }
      },
      "HumanSpecMilestone": {
        "type": "object",
        "required": [
          "milestoneNumber",
          "description",
          "hours",
          "stories"
        ],
        "properties": {
          "milestoneNumber": {
            "type": "integer",
            "description": "Milestone number"
          },
          "description": {
            "type": "string",
            "description": "Description of the milestone"
          },
          "hours": {
            "type": "number",
            "description": "Estimated hours for this milestone"
          },
          "stories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HumanSpecStory"
            },
            "description": "List of user stories in this milestone"
          }
        }
      },
      "HumanSpecJson": {
        "type": "object",
        "required": [
          "executiveSummary",
          "coreFunctionalities",
          "personas",
          "techStack",
          "milestones",
          "totalHours",
          "roles"
        ],
        "description": "Full structured JSON with hours, personas, and roles for human review",
        "properties": {
          "title": {
            "type": "string",
            "description": "Title of the specification"
          },
          "executiveSummary": {
            "type": "string",
            "description": "Executive summary of the project"
          },
          "coreFunctionalities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecCoreFunctionality"
            },
            "description": "List of core functionalities"
          },
          "personas": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecPersona"
            },
            "description": "User personas"
          },
          "techStack": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecTechStackItem"
            },
            "description": "Technology stack items"
          },
          "techStackGrouped": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Technology stack grouped by category"
          },
          "milestones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HumanSpecMilestone"
            },
            "description": "List of milestones with hours"
          },
          "totalHours": {
            "type": "number",
            "description": "Total estimated hours for the project"
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecRole"
            },
            "description": "Roles required for the project"
          }
        }
      },
      "CreditsBalanceResponse": {
        "type": "object",
        "required": [
          "success",
          "creditsRemaining"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the request was successful"
          },
          "creditsRemaining": {
            "type": "integer",
            "description": "The number of remaining credits available for the user"
          }
        }
      },
      "SpecGraphNode": {
        "type": "object",
        "required": [
          "id",
          "label"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the node"
          },
          "label": {
            "type": "string",
            "description": "Display label for the node"
          },
          "type": {
            "type": "string",
            "description": "Node category; values depend on the graph."
          },
          "description": {
            "type": "string",
            "description": "Description of the node"
          },
          "level": {
            "type": [
              "number",
              "string",
              "null"
            ],
            "description": "Numeric flow depth or an architecture level such as C1 or C2, when available."
          },
          "hours": {
            "type": "number",
            "description": "Estimated hours for this node"
          }
        }
      },
      "SpecGraphEdge": {
        "type": "object",
        "required": [
          "source",
          "target"
        ],
        "properties": {
          "source": {
            "type": "string",
            "description": "Source node ID"
          },
          "target": {
            "type": "string",
            "description": "Target node ID"
          },
          "description": {
            "type": "string",
            "description": "Description of the relationship"
          },
          "edgeType": {
            "type": "string",
            "description": "Type of edge relationship"
          }
        }
      },
      "SpecGraph": {
        "type": "object",
        "required": [
          "nodes",
          "edges"
        ],
        "properties": {
          "nodes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecGraphNode"
            },
            "description": "Array of graph nodes"
          },
          "edges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpecGraphEdge"
            },
            "description": "Array of graph edges"
          }
        }
      },
      "SpecEnrichedTechStackItem": {
        "type": "object",
        "required": [
          "name",
          "useFor",
          "reason",
          "description"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the technology (e.g., React, PostgreSQL)"
          },
          "useFor": {
            "type": "string",
            "description": "Category label (e.g., Frontend, Backend, Database)"
          },
          "reason": {
            "type": "string",
            "description": "Why this technology was chosen for this specific project"
          },
          "description": {
            "type": "string",
            "description": "Technical description of what the technology does"
          },
          "link": {
            "type": "string",
            "format": "uri",
            "description": "Official website or documentation URL"
          },
          "helpfulLinks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL to helpful resource"
                },
                "description": {
                  "type": "string",
                  "description": "Description of the resource"
                }
              }
            },
            "description": "Array of helpful documentation and tutorial links"
          },
          "alternatives": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "description": "Name of the alternative technology"
                },
                "link": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL of the alternative technology"
                },
                "description": {
                  "type": "string",
                  "description": "Description of the alternative"
                }
              }
            },
            "description": "Array of alternative technologies that could be used instead"
          }
        }
      },
      "Task": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "Full starting HTTP(S) URL. Domains must resolve to at least one IPv4 or IPv6 address.",
            "format": "uri"
          },
          "instruction": {
            "type": "string",
            "description": "Goal and constraints for the task."
          },
          "input": {
            "type": "object",
            "properties": {},
            "additionalProperties": {
              "type": "string"
            },
            "description": "Named string inputs available to the runner."
          },
          "output": {
            "type": "object",
            "properties": {},
            "additionalProperties": true,
            "description": "JSON Schema for extracted data. If omitted, the runner may infer a schema.",
            "minProperties": 1
          },
          "successCondition": {
            "type": "string",
            "description": "Natural-language completion check."
          },
          "mode": {
            "type": "string",
            "description": "auto chooses extraction when an output schema is provided; agent handles interaction.",
            "enum": [
              "auto",
              "extract",
              "agent"
            ],
            "default": "auto"
          },
          "maxSteps": {
            "type": "integer",
            "description": "Planning iteration budget. MCP accepts 1–50; use this range across clients. REST forwards the value without equivalent range validation.",
            "minimum": 1,
            "maximum": 50
          },
          "maxDurationSeconds": {
            "type": "integer",
            "description": "Wall-clock budget in seconds. MCP accepts 5–600; use this range across clients. Defaults vary by execution path.",
            "minimum": 5,
            "maximum": 600
          },
          "maxIterations": {
            "type": "integer",
            "description": "Legacy alias of maxSteps. If both are supplied, maxIterations takes precedence.",
            "deprecated": true
          },
          "timeoutMs": {
            "type": "integer",
            "description": "Legacy millisecond budget. If both are supplied, timeoutMs takes precedence over maxDurationSeconds.",
            "deprecated": true
          }
        },
        "description": "A full HTTP(S) URL and either nonblank instructions or a non-empty output schema are required. The entire batch is validated before billing or queueing.",
        "anyOf": [
          {
            "required": [
              "instruction"
            ],
            "properties": {
              "instruction": {
                "type": "string",
                "pattern": "\\S"
              }
            }
          },
          {
            "required": [
              "output"
            ]
          }
        ]
      },
      "BatchRequest": {
        "type": "object",
        "required": [
          "tasks"
        ],
        "properties": {
          "tasks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Task"
            },
            "minItems": 1,
            "description": "One or more tasks. Default server limit is 1,000, configurable by deployment; BATCH_TOO_LARGE reports the active limit."
          },
          "concurrency": {
            "type": "integer",
            "description": "Requested parallelism; defaults to 5 and is clamped to 1–20. Account and service capacity may reduce effective parallelism.",
            "minimum": 1,
            "maximum": 20,
            "default": 5
          },
          "async": {
            "type": "boolean",
            "default": false,
            "description": "Return the batch ID immediately, then poll or attach to its stream."
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "Return SSE; takes precedence over async."
          },
          "idempotencyKey": {
            "type": "string",
            "description": "Optional retry lookup key. Idempotency-Key header takes precedence. User-scoped lookup lasts 24 hours; concurrent first requests are not atomically deduplicated."
          }
        }
      },
      "TaskResult": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "instruction": {
            "type": "string"
          },
          "input": {
            "type": "object",
            "properties": {},
            "additionalProperties": true
          },
          "output": {
            "type": "object",
            "properties": {},
            "additionalProperties": true
          },
          "status": {
            "type": "string",
            "description": "PENDING and RUNNING are status placeholders; all other listed values are terminal task outcomes.",
            "enum": [
              "PENDING",
              "RUNNING",
              "SUCCESS",
              "ERROR",
              "TIMEOUT",
              "BLOCKED",
              "CAPTCHA_FAILED",
              "LOOP",
              "NO_TARGET"
            ]
          },
          "data": {
            "description": "Extracted result; shape follows the requested or inferred schema. May be null or omitted."
          },
          "creditsUsed": {
            "type": "number",
            "description": "Settled task charge: SUCCESS has a 0.1-credit floor; non-SUCCESS tasks have zero charge. Submission may reserve credits before settlement."
          },
          "durationMs": {
            "type": "integer",
            "description": "Wall-clock task duration in milliseconds."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "attempts": {
            "type": "integer"
          },
          "queuePosition": {
            "anyOf": [
              {
                "type": "integer",
                "description": "Queue estimate; 0 when running."
              },
              {
                "type": "null"
              }
            ]
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RunnerEvent"
            },
            "description": "Available timeline when includeEvents=true."
          }
        },
        "additionalProperties": true
      },
      "RunnerEvent": {
        "type": "object",
        "required": [
          "type",
          "timestamp"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Extensible event type, for example navigation, screenshot, plan, action, validation, waiting, done, or error."
          },
          "timestamp": {
            "type": "number",
            "description": "Unix timestamp in milliseconds."
          },
          "iteration": {
            "type": "integer"
          },
          "data": {
            "description": "Event-specific payload. Screenshot data is not guaranteed to be a URL."
          }
        },
        "additionalProperties": true
      },
      "BatchResult": {
        "type": "object",
        "required": [
          "id",
          "status",
          "results"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "taskNames": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "total": {
            "type": "integer"
          },
          "completed": {
            "type": "integer",
            "description": "Counts result slots, including pending/running placeholders or nulls. Do not use this as the completion signal."
          },
          "results": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/TaskResult"
                },
                {
                  "type": "null"
                }
              ]
            },
            "description": "Ordered by task index. Slots can be null or partial until a result arrives."
          },
          "totalCreditsUsed": {
            "type": "number"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "completed",
              "failed"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "liveEvents": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/RunnerEvent"
              }
            },
            "description": "Per-task events when includeEvents=true and live events are available."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "additionalProperties": true
      },
      "BrowserAgentStatus": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string"
          },
          "running": {
            "type": "integer"
          },
          "claimed": {
            "type": "integer"
          },
          "pending": {
            "type": "integer"
          },
          "total": {
            "type": "integer",
            "description": "Current inflight count reported by the queue snapshot."
          },
          "cap": {
            "type": "integer",
            "description": "Current account inflight limit, resolved by tier. Treat this as a snapshot, not a reservation."
          }
        },
        "additionalProperties": true
      },
      "SpecSummary": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "_id": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "created": {
            "type": "string",
            "format": "date-time"
          },
          "endpoint": {
            "type": "string",
            "enum": [
              "fast_spec",
              "deep_spec"
            ],
            "description": "Which endpoint was used"
          },
          "input": {
            "type": "string",
            "description": "Original input text provided"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "success": {
            "type": "boolean",
            "description": "Whether the request succeeded"
          },
          "uploadedFileShortUrl": {
            "anyOf": [
              {
                "type": "string",
                "description": "Short URL for uploaded file (if file was uploaded)"
              },
              {
                "type": "null"
              }
            ]
          },
          "uploadedFileName": {
            "anyOf": [
              {
                "type": "string",
                "description": "Name of uploaded file (if file was uploaded)"
              },
              {
                "type": "null"
              }
            ]
          },
          "executionTime": {
            "anyOf": [
              {
                "type": "integer",
                "description": "Processing time in milliseconds (only when completed or failed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "currentContext": {
            "anyOf": [
              {
                "type": "string",
                "description": "Existing context supplied with generation."
              },
              {
                "type": "null"
              }
            ]
          },
          "specSource": {
            "anyOf": [
              {
                "type": "string",
                "description": "Origin of the request, such as api or mcp."
              },
              {
                "type": "null"
              }
            ]
          },
          "errorMessage": {
            "anyOf": [
              {
                "type": "string",
                "description": "Error description (only when failed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "progress": {
            "anyOf": [
              {
                "type": "number",
                "description": "Completion percentage (0-100) while processing"
              },
              {
                "type": "null"
              }
            ]
          },
          "predevUrl": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "description": "pre.dev project URL (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "docURLs": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "zippedDocsUrls": {
            "anyOf": [
              {
                "type": "array",
                "description": "Array of scraped documentation archives (only when completed). Empty array if no docURLs provided or scraping fails",
                "items": {
                  "$ref": "#/components/schemas/ZippedDocsUrl"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "codingAgentSpecUrl": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "description": "URL where the coding agent spec format is hosted (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "humanSpecUrl": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "description": "URL where the human-readable spec is hosted (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          },
          "architectureInfographicUrl": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "description": "URL to a visual architecture infographic/diagram for the specification (only when completed)"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "Summary only. Use GET /spec-status/{specId} for Markdown, JSON, graphs, totalHumanHours, creditsUsed, and progressMessage."
      },
      "BrowserGateError": {
        "type": "object",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "SUBSCRIPTION_REQUIRED",
              "INSUFFICIENT_CREDITS",
              "RATE_LIMITED",
              "QUEUE_FULL",
              "BATCH_TOO_LARGE"
            ]
          },
          "actionUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "BatchSummary": {
        "type": "object",
        "required": [
          "id",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "taskNames": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "total": {
            "type": "integer"
          },
          "completed": {
            "type": "integer",
            "description": "Count of stored task results in this history response."
          },
          "results": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/TaskResult"
                },
                {
                  "type": "null"
                }
              ]
            },
            "description": "Compact preview, not a complete result set. Use GET /browser-agent/{id} for details."
          },
          "totalCreditsUsed": {
            "type": "number"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "completed",
              "failed"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "additionalProperties": true
      },
      "ListBatchesResponse": {
        "type": "object",
        "required": [
          "batches",
          "total",
          "hasMore"
        ],
        "properties": {
          "batches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchSummary"
            }
          },
          "total": {
            "type": "integer"
          },
          "hasMore": {
            "type": "boolean"
          }
        }
      },
      "BrowserCapacity": {
        "type": "object",
        "properties": {
          "totalActive": {
            "type": "integer"
          },
          "maxSandboxes": {
            "type": "integer"
          },
          "perUserCap": {
            "type": "integer"
          },
          "pending": {
            "type": "integer"
          },
          "running": {
            "type": "integer"
          },
          "claimed": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "oldestQueuedAgeMs": {
            "type": "integer"
          },
          "utilization": {
            "type": "number",
            "description": "Reported utilization percentage."
          }
        },
        "description": "Advisory service diagnostics. Fields may change; perUserCap is a legacy global value, not your account limit. Use GET /browser-agent-status for your cap.",
        "additionalProperties": true
      },
      "LiveBrowserResponse": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "Credential-bearing WebSocket URL. Keep private and use only for the requested batch.",
            "format": "uri"
          }
        }
      },
      "ProposalFile": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string"
          },
          "fileUrl": {
            "type": "string",
            "format": "uri"
          },
          "fileType": {
            "type": "string"
          },
          "fileSize": {
            "type": "integer",
            "description": "Bytes."
          },
          "uploadedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": true
      },
      "Proposal": {
        "type": "object",
        "required": [
          "_id",
          "proposalName"
        ],
        "properties": {
          "_id": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "proposalName": {
            "type": "string"
          },
          "proposalContent": {
            "type": "string"
          },
          "proposalFile": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ProposalFile"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Stored proposal. Additional metadata can be present.",
        "additionalProperties": true
      },
      "UploadProposalRequest": {
        "type": "object",
        "required": [
          "proposalName"
        ],
        "properties": {
          "proposalName": {
            "type": "string",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "description": "Proposal content.",
            "minLength": 1
          },
          "file": {
            "type": "string",
            "description": "PDF, DOC, DOCX, TXT, JPEG, or PNG, at most 20 MiB. Use multipart/form-data and the matching MIME type.",
            "format": "binary"
          }
        },
        "anyOf": [
          {
            "required": [
              "text"
            ]
          },
          {
            "required": [
              "file"
            ]
          }
        ]
      },
      "UploadProposalResponse": {
        "type": "object",
        "required": [
          "success",
          "proposalId"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "proposalId": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          }
        }
      },
      "VetProposalRequest": {
        "type": "object",
        "required": [
          "specId"
        ],
        "properties": {
          "specId": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "proposalId": {
            "type": "string",
            "description": "Existing proposal ID. When supplied, file, text, and proposalName are ignored.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "proposalName": {
            "type": "string",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "minLength": 1
          },
          "file": {
            "type": "string",
            "description": "New proposal file, at most 20 MiB, with a supported MIME type.",
            "format": "binary"
          }
        },
        "anyOf": [
          {
            "required": [
              "proposalId"
            ]
          },
          {
            "required": [
              "proposalName",
              "text"
            ]
          },
          {
            "required": [
              "proposalName",
              "file"
            ]
          }
        ]
      },
      "VettedProposal": {
        "type": "object",
        "required": [
          "_id",
          "specId",
          "proposalId",
          "shouldAccept"
        ],
        "properties": {
          "_id": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "specId": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "proposalId": {
            "type": "string",
            "description": "24-character record ID.",
            "pattern": "^[a-fA-F0-9]{24}$"
          },
          "shouldAccept": {
            "type": "boolean"
          },
          "acceptanceConfidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "overallAlignment": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "strengths": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "weaknesses": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "criticalGaps": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "recommendations": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "executiveSummary": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": true
      },
      "VettedProposalSummary": {
        "allOf": [
          {
            "$ref": "#/components/schemas/VettedProposal"
          },
          {
            "type": "object",
            "properties": {
              "proposal": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "proposalName": {
                        "type": "string"
                      },
                      "proposalFile": {
                        "anyOf": [
                          {
                            "$ref": "#/components/schemas/ProposalFile"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    }
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        ]
      },
      "VetProposalResponse": {
        "type": "object",
        "required": [
          "success",
          "vettedProposal",
          "proposal"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "vettedProposal": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/VettedProposal"
              },
              {
                "type": "null"
              }
            ]
          },
          "proposal": {
            "$ref": "#/components/schemas/Proposal"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Specifications"
    },
    {
      "name": "Browser Agents"
    },
    {
      "name": "Proposals"
    },
    {
      "name": "Account"
    }
  ]
}
