{
  "openapi": "3.1.0",
  "info": {
    "title": "Aetherya API",
    "version": "0.1.0",
    "description": "Hand-written specification covering Aetherya's agent-facing HTTP surface: decision studies (autopilot), usage and estimation, cognitive audits, personas and Audience Chat. It is maintained alongside the API rather than generated from it, so treat an endpoint that behaves differently from this document as a bug in the document and tell us.\n\nAuthentication is a bearer API key (prefix `aeth_live_`), created by a signed-in person at https://app.aetherya.ai/dashboard/settings?tab=api-keys. Send `Authorization: Bearer aeth_live_...`. Personal keys allow 60 requests a minute; organization keys follow the organization's plan.\n\nRequests act inside one workspace. Without an `X-Aetherya-Workspace-Id` header the key's default workspace is used; sending the header targets another workspace the key's owner belongs to.\n\nRecommended flow for an agent: POST /api/research-lab/autopilot with a plain-English objective, poll it, confirm the quoted price with POST .../confirm, then read the brief.",
    "contact": {
      "url": "https://aetherya.ai"
    }
  },
  "servers": [
    {
      "url": "https://api.aetherya.ai",
      "description": "Production"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An Aetherya API key (`aeth_live_...`) created in Settings → API keys. Delegated agent tokens are not enabled yet; see https://aetherya.ai/auth.md."
      }
    },
    "parameters": {
      "WorkspaceId": {
        "name": "X-Aetherya-Workspace-Id",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Optional for auth.md delegated tokens (their human-approved workspace is bound into the token); legacy API-key calls may include this header to select a workspace."
      }
    },
    "schemas": {
      "Persona": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "age": {
            "type": "integer"
          },
          "occupation": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "interests": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": true
      },
      "AuditJobState": {
        "type": "string",
        "enum": [
          "queued",
          "running",
          "completed",
          "failed",
          "cancelled",
          "not_found",
          "error"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "UsageLimitResponse": {
        "type": "object",
        "required": [
          "reason"
        ],
        "properties": {
          "reason": {
            "type": "string",
            "enum": [
              "burst",
              "weekly",
              "monthly",
              "concurrency",
              "credits",
              "subscription_required"
            ]
          },
          "resetAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "canUpgrade": {
            "type": "boolean"
          },
          "canBuyCredits": {
            "type": "boolean"
          },
          "suggestions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "UsageWindow": {
        "type": "object",
        "required": [
          "percentUsed",
          "resetsAt"
        ],
        "properties": {
          "percentUsed": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "resetsAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  },
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/api/public/pricing": {
      "get": {
        "operationId": "getPublicPricing",
        "summary": "Get canonical pricing tiers",
        "description": "Returns the canonical EUR pricing catalog for all Aetherya plans. Public endpoint — no authentication required. Consumed by agents, JSON-LD, and llms-full.txt.",
        "security": [],
        "responses": {
          "200": {
            "description": "Pricing catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currency": {
                      "type": "string",
                      "example": "EUR"
                    },
                    "lastUpdated": {
                      "type": "string",
                      "example": "2026-07-04"
                    },
                    "note": {
                      "type": "string"
                    },
                    "tiers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "price": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "currency": {
                            "type": "string"
                          },
                          "billingCycle": {
                            "type": "string",
                            "enum": [
                              "free",
                              "monthly",
                              "annual",
                              "custom"
                            ]
                          },
                          "priceDisplay": {
                            "type": "string"
                          },
                          "capacityDisplay": {
                            "type": "string"
                          },
                          "featureBullets": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "checkoutUrlPath": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "servers": [
          {
            "url": "https://aetherya.ai",
            "description": "Marketing site — this path is NOT served by the API host."
          }
        ]
      },
      "servers": [
        {
          "url": "https://aetherya.ai",
          "description": "Public site"
        }
      ]
    },
    "/api/public/api-equivalent-values": {
      "get": {
        "operationId": "getPublicApiEquivalentValues",
        "summary": "Get approved API-equivalent usage values",
        "description": "Returns mechanically calculated plan values only when the current credit rate card is finance-approved and public. Otherwise returns an unpublished response with no values.",
        "security": [],
        "responses": {
          "200": {
            "description": "Approved values or the fail-closed unpublished state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "published",
                    "values"
                  ],
                  "properties": {
                    "published": {
                      "type": "boolean"
                    },
                    "rateCardVersion": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "currency": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "values": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "planKey",
                          "claimKind",
                          "valueMinorUnits"
                        ],
                        "properties": {
                          "planKey": {
                            "type": "string"
                          },
                          "claimKind": {
                            "type": "string",
                            "enum": [
                              "platform_usage_comparison",
                              "included_api_credit_value"
                            ]
                          },
                          "valueMinorUnits": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/usage/status": {
      "get": {
        "operationId": "getUsageStatus",
        "summary": "Get percentage-based usage status",
        "description": "Returns weekly and monthly percentages, reset times, concurrency state, and the exact purchased Aetherya Credit balance. Raw included unit allowances are never returned.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Current usage status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "planKey",
                    "weekly",
                    "monthly",
                    "concurrency",
                    "credits",
                    "warnings"
                  ],
                  "properties": {
                    "planKey": {
                      "type": "string"
                    },
                    "policyVersion": {
                      "type": "integer"
                    },
                    "weekly": {
                      "$ref": "#/components/schemas/UsageWindow"
                    },
                    "monthly": {
                      "$ref": "#/components/schemas/UsageWindow"
                    },
                    "concurrency": {
                      "type": "object",
                      "properties": {
                        "inUse": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        }
                      }
                    },
                    "credits": {
                      "type": "object",
                      "properties": {
                        "balance": {
                          "type": "integer"
                        },
                        "spendable": {
                          "type": "boolean"
                        },
                        "purchaseEligible": {
                          "type": "boolean"
                        },
                        "autoReloadEligible": {
                          "type": "boolean"
                        }
                      }
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication required."
          }
        }
      }
    },
    "/api/usage/estimate": {
      "post": {
        "operationId": "estimateUsage",
        "summary": "Estimate a workload as a percentage range",
        "description": "Informational estimate only. Execution performs an authoritative server-side policy check.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "service"
                ],
                "properties": {
                  "service": {
                    "type": "string"
                  },
                  "audienceSize": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "variants": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "browserMinutes": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "files": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "analysisDepth": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 5
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Percentage estimate and policy guidance.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "computeClass",
                    "estimatedPercentMin",
                    "estimatedPercentMax",
                    "allowed",
                    "canBuyCredits",
                    "suggestions"
                  ],
                  "properties": {
                    "computeClass": {
                      "type": "string",
                      "enum": [
                        "light",
                        "standard",
                        "high",
                        "extreme"
                      ]
                    },
                    "estimatedPercentMin": {
                      "type": "number"
                    },
                    "estimatedPercentMax": {
                      "type": "number"
                    },
                    "allowed": {
                      "type": "boolean"
                    },
                    "limitingWindow": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "canBuyCredits": {
                      "type": "boolean"
                    },
                    "suggestions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/audits/run": {
      "post": {
        "operationId": "runAudit",
        "summary": "Start a behavioral-simulation audit of a URL",
        "description": "Starts an async audit job. The job runs a synthetic audience against the target URL and produces predicted UX friction, hesitation, drop-off, and messaging-clarity findings. Poll `/api/audits/jobs/{jobId}` for status.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "target",
                  "type"
                ],
                "properties": {
                  "target": {
                    "type": "string",
                    "format": "uri",
                    "description": "The URL to audit."
                  },
                  "type": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "example": [
                      "ux_ui"
                    ],
                    "description": "Audit type(s). `[\"ux_ui\"]` for a page audit, `[\"ux_journey\"]` for a multi-step flow."
                  },
                  "cognitiveMode": {
                    "type": "boolean",
                    "description": "Enable cognitive/behavioral persona simulation. Required to get persona-level findings.",
                    "default": false
                  },
                  "numAgents": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Number of synthetic personas to simulate."
                  },
                  "auditDepth": {
                    "type": "integer",
                    "description": "How many pages to crawl."
                  },
                  "additionalInstructions": {
                    "type": "string",
                    "description": "Plain-language focus or audience guidance for the simulation."
                  },
                  "personas": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Optional list of persona ids to pin the simulation to."
                  },
                  "modelTier": {
                    "type": "string",
                    "description": "Optional simulation quality tier."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audit job started successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "jobId"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "jobId": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Usage policy limit reached. The response identifies burst, weekly, monthly, concurrency, credits, or subscription_required and may include reset, upgrade, purchase, and workload-reduction guidance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/audits/jobs/{jobId}": {
      "get": {
        "operationId": "getAuditJob",
        "summary": "Poll the status of an audit job",
        "description": "Returns the current status of an async audit job. When `status` is `completed`, `reportId` is set and the full report can be fetched from `/api/audits/{reportId}`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "jobId",
                    "status"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "jobId": {
                      "type": "string"
                    },
                    "status": {
                      "$ref": "#/components/schemas/AuditJobState"
                    },
                    "reportId": {
                      "type": "string",
                      "description": "Set when status is 'completed'."
                    },
                    "error": {
                      "type": "string",
                      "description": "Set when status is 'failed'."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/audits/{reportId}": {
      "get": {
        "operationId": "getAuditReport",
        "summary": "Fetch a completed audit report",
        "description": "Returns the full audit report for a completed job. The `summary` and `fullReport` fields carry the raw simulation output and are normalized by the MCP client before being returned to agents.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "name": "reportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audit report.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "report"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "report": {
                      "type": "object",
                      "required": [
                        "id"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        },
                        "score": {
                          "type": "number"
                        },
                        "summary": {},
                        "fullReport": {},
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Report not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/personas": {
      "get": {
        "operationId": "listPersonas",
        "summary": "List synthetic audiences (personas)",
        "description": "Returns the list of synthetic personas available to the authenticated user. These are simulated audience members, not real people.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Persona list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Persona"
                      }
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/personas/create": {
      "post": {
        "operationId": "createPersonas",
        "summary": "Generate synthetic audience personas",
        "description": "**DEPRECATED.** Superseded by the async create path; slated for /api/v1/audiences.\n\nGenerates one or more synthetic personas. When `customTraits` or `websiteUrl` is supplied, the simulation engine generates personas matching the description. All personas are synthetic — engine-generated simulated people, not real users. This call may take up to ~110 seconds for engine-generated batches.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "individual",
                      "batch"
                    ],
                    "description": "Use 'individual' for one persona, 'batch' for multiple."
                  },
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 25,
                    "description": "Number of personas to generate."
                  },
                  "category": {
                    "type": "string",
                    "description": "Segment label (e.g. 'e-commerce', 'fintech')."
                  },
                  "targetAudience": {
                    "type": "string",
                    "description": "Plain-language audience description."
                  },
                  "customTraits": {
                    "type": "string",
                    "description": "Detailed audience description. Triggers engine generation (slower path)."
                  },
                  "websiteUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional site URL. Aetherya infers the audience from its content."
                  },
                  "market": {
                    "type": "string",
                    "description": "Target market / locale (e.g. 'US', 'DE', 'UK')."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created personas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/Persona"
                        },
                        {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Persona"
                          }
                        }
                      ]
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "deprecated": true
      }
    },
    "/api/audience-chat/sessions": {
      "post": {
        "operationId": "createChatSession",
        "summary": "Create an audience chat session",
        "description": "Creates a conversation session with a synthetic persona. Used as the first step of the `aetherya_ask_audience` MCP tool — follow with a POST to `/api/audience-chat/message`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "persona",
                      "group"
                    ],
                    "description": "Target a single persona or a group."
                  },
                  "targetPersonaId": {
                    "type": "string",
                    "description": "The persona id to chat with (required when mode is 'persona')."
                  },
                  "targetGroupId": {
                    "type": "string",
                    "description": "The group id to chat with (required when mode is 'group')."
                  },
                  "title": {
                    "type": "string"
                  },
                  "chatContext": {
                    "type": "string",
                    "description": "Background/situation for the persona to consider."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "required": [
                        "id"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "additionalProperties": true
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/audience-chat/message": {
      "post": {
        "operationId": "sendChatMessage",
        "summary": "Send a message to a synthetic audience chat session",
        "description": "Sends a message to an existing audience chat session and returns the synthetic persona's predicted response. This is the second step of the `aetherya_ask_audience` MCP tool.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sessionId",
                  "message"
                ],
                "properties": {
                  "sessionId": {
                    "type": "string",
                    "description": "The session id returned by POST /api/audience-chat/sessions."
                  },
                  "message": {
                    "type": "string",
                    "description": "The question or message to send to the synthetic audience."
                  },
                  "chatContext": {
                    "type": "string",
                    "description": "Optional additional context for this message."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Persona response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "reply"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "mode": {
                      "type": "string"
                    },
                    "reply": {
                      "type": "string",
                      "description": "The synthetic persona's predicted response."
                    },
                    "innerThoughts": {
                      "type": "string",
                      "description": "Optional inner-monologue reasoning from the persona (may not always be present)."
                    },
                    "sessionId": {
                      "type": "string"
                    },
                    "messageId": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/research-lab/autopilot": {
      "post": {
        "operationId": "startAutopilot",
        "summary": "Design, price and run a study from a plain-English objective",
        "description": "Aetherya designs the study, picks or builds the audience and prices it. Nothing is spent until the run is confirmed.",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "request"
                ],
                "properties": {
                  "request": {
                    "type": "string",
                    "description": "The decision or question, in plain English. Include the variants to compare."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The autopilot run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "awaiting_clarification",
                        "awaiting_confirm",
                        "completed",
                        "failed",
                        "cancelled"
                      ]
                    },
                    "step": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "properties": {
                        "sessions": {
                          "type": "number",
                          "description": "The figure to pass back as acceptedSessions."
                        }
                      }
                    },
                    "brief": {
                      "type": "object",
                      "description": "Decision brief once completed: answer, confidence, reasons, risks, doNext, caveat."
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/research-lab/autopilot/{id}": {
      "get": {
        "operationId": "getAutopilot",
        "summary": "Poll an autopilot run",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The autopilot run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "awaiting_clarification",
                        "awaiting_confirm",
                        "completed",
                        "failed",
                        "cancelled"
                      ]
                    },
                    "step": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "properties": {
                        "sessions": {
                          "type": "number",
                          "description": "The figure to pass back as acceptedSessions."
                        }
                      }
                    },
                    "brief": {
                      "type": "object",
                      "description": "Decision brief once completed: answer, confidence, reasons, risks, doNext, caveat."
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/research-lab/autopilot/{id}/confirm": {
      "post": {
        "operationId": "confirmAutopilot",
        "summary": "Accept the quoted price and launch",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "acceptedSessions"
                ],
                "properties": {
                  "acceptedSessions": {
                    "type": "number",
                    "description": "Must equal estimate.sessions; any other figure returns 409 QUOTE_MISMATCH."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The autopilot run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "awaiting_clarification",
                        "awaiting_confirm",
                        "completed",
                        "failed",
                        "cancelled"
                      ]
                    },
                    "step": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "properties": {
                        "sessions": {
                          "type": "number",
                          "description": "The figure to pass back as acceptedSessions."
                        }
                      }
                    },
                    "brief": {
                      "type": "object",
                      "description": "Decision brief once completed: answer, confidence, reasons, risks, doNext, caveat."
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "QUOTE_MISMATCH: the price changed or the figure is wrong. Re-read the run."
          },
          "429": {
            "description": "INSUFFICIENT_SESSIONS: the plan allowance does not cover this run, or RATE_LIMIT_EXCEEDED."
          }
        }
      }
    },
    "/api/research-lab/autopilot/{id}/answer": {
      "post": {
        "operationId": "answerAutopilot",
        "summary": "Answer a clarifying question",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "answer": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The autopilot run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "awaiting_clarification",
                        "awaiting_confirm",
                        "completed",
                        "failed",
                        "cancelled"
                      ]
                    },
                    "step": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "properties": {
                        "sessions": {
                          "type": "number",
                          "description": "The figure to pass back as acceptedSessions."
                        }
                      }
                    },
                    "brief": {
                      "type": "object",
                      "description": "Decision brief once completed: answer, confidence, reasons, risks, doNext, caveat."
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/research-lab/autopilot/{id}/cancel": {
      "post": {
        "operationId": "cancelAutopilot",
        "summary": "Cancel a run",
        "parameters": [
          {
            "$ref": "#/components/parameters/WorkspaceId"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The autopilot run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "awaiting_clarification",
                        "awaiting_confirm",
                        "completed",
                        "failed",
                        "cancelled"
                      ]
                    },
                    "step": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "properties": {
                        "sessions": {
                          "type": "number",
                          "description": "The figure to pass back as acceptedSessions."
                        }
                      }
                    },
                    "brief": {
                      "type": "object",
                      "description": "Decision brief once completed: answer, confidence, reasons, risks, doNext, caveat."
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
