{
  "openapi": "3.1.0",
  "info": {
    "title": "Noah Predict External API",
    "version": "0.4.7",
    "summary": "Async headless API for Noah Predict saved chats, prompt templates, queued document reviews, same-run follow-ups, viewable report PDFs, fresh investigations, Market Edge card sheets, packages and data packs.",
    "description": "Noah Predict is a predictive signal intelligence engine. This public OpenAPI description is intended for developers and AI agents evaluating account-scoped API access. Production access requires an account API key created inside Noah Predict."
  },
  "servers": [
    {
      "url": "https://noahpredict.com/api"
    },
    {
      "url": "https://www.noahpredict.com/api"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/external/v1/frames": {
      "get": {
        "operationId": "listFrames",
        "summary": "List supported Noah Predict frames for fresh reports.",
        "description": "Returns the machine IDs, labels, audiences, default horizons and sample questions clients can use when creating fresh investigations.",
        "security": [],
        "responses": {
          "200": {
            "description": "Frame catalogue listed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FrameListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/external/v1/saved-chats": {
      "get": {
        "operationId": "listSavedChats",
        "summary": "List saved chats/reports for the API key account.",
        "description": "Preferred route for Saved chats: preserved work threads that can be refreshed or followed up, then collected through result/package/data-pack/card-sheet routes. Rows include report_family, report_family_label, machine_label and bot_search_terms so agents can find specific saved reports such as Market Edge / Polymarket.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search saved chats/reports by id, name, brief, machine_label, report_family_label or bot_search_terms."
          },
          {
            "name": "report_family",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "examples": [
                "market_edge",
                "due_diligence"
              ]
            },
            "description": "Optional family filter. Use market_edge to find saved Polymarket/Market Edge reports."
          }
        ],
        "responses": {
          "200": {
            "description": "Saved chats listed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipeListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          }
        }
      }
    },
    "/external/v1/saved-chats/{recipe_id}/run": {
      "post": {
        "operationId": "runSavedChat",
        "summary": "Queue a fresh update from a saved chat.",
        "parameters": [
          {
            "name": "recipe_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunSetupRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Run accepted and queued. Poll the returned status URL for results.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "default": 5
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/saved-reports": {
      "get": {
        "operationId": "listSavedReportsCompat",
        "summary": "Compatibility alias for saved chats/reports.",
        "description": "Compatibility route for clients that still say saved reports. It returns the same Saved chat rows as /external/v1/saved-chats, including report_family labels and Market Edge / Polymarket search terms.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search saved chats/reports by id, name, brief, machine_label, report_family_label or bot_search_terms."
          },
          {
            "name": "report_family",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "examples": [
                "market_edge",
                "due_diligence"
              ]
            },
            "description": "Optional family filter. Use market_edge to find saved Polymarket/Market Edge reports."
          }
        ],
        "responses": {
          "200": {
            "description": "Saved chats listed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipeListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          }
        }
      }
    },
    "/external/v1/saved-reports/{recipe_id}/run": {
      "post": {
        "operationId": "runSavedReportCompat",
        "summary": "Compatibility alias: queue a fresh update from a saved chat.",
        "parameters": [
          {
            "name": "recipe_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunSetupRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Run accepted and queued. Poll the returned status URL for results.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "default": 5
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/recipes": {
      "get": {
        "operationId": "listRecipesLegacy",
        "summary": "Legacy alias: list saved chats for the API key account.",
        "description": "Returns account-owned Saved chats. The route name recipes is retained for compatibility; clients should prefer /external/v1/saved-chats.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved chats listed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipeListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          }
        }
      }
    },
    "/external/v1/recipes/{recipe_id}/run": {
      "post": {
        "operationId": "runRecipeLegacy",
        "summary": "Legacy alias: queue a fresh update from a saved chat.",
        "parameters": [
          {
            "name": "recipe_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunSetupRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Run accepted and queued. Poll the returned status URL for results.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "default": 5
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/prompt-templates": {
      "get": {
        "operationId": "listPromptTemplates",
        "summary": "List prompt templates for the API key account.",
        "description": "Prompt templates are saved method memory for fresh repeatable runs. They do not reopen prior work. Rows include machine_label, frame_id, product_group and bot_search_terms so agents can find specific templates.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search prompt templates by id, name, description, example_question, frame_id, product_group, machine_label or bot_search_terms."
          },
          {
            "name": "frame_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "examples": [
                "market_edge",
                "due_diligence"
              ]
            },
            "description": "Optional frame/product-group filter."
          }
        ],
        "responses": {
          "200": {
            "description": "Prompt templates listed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptTemplateListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          }
        }
      }
    },
    "/external/v1/prompt-templates/{template_id}": {
      "get": {
        "operationId": "getPromptTemplate",
        "summary": "Get one prompt template summary.",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Prompt template summary.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/prompt-templates/{template_id}/run": {
      "post": {
        "operationId": "runPromptTemplate",
        "summary": "Create a fresh run from a prompt template.",
        "description": "Runs a fresh investigation using the saved route/setup/lane memory from this prompt template. Send question/message for the new run; if omitted, Noah uses the stored example question when available.",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PromptTemplateRunRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Run accepted and queued. Poll the returned status URL for results.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "default": 5
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "400": {
            "description": "Question required when the template has no stored example question."
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/reports": {
      "post": {
        "operationId": "createFreshReport",
        "summary": "Create a fresh Noah Predict investigation.",
        "description": "Requires a full-dashboard API key and plan entitlement. This always creates a brand-new chat/session. Do not use this route for document URLs or follow-ups; use /external/v1/document-reviews for filings/PDFs and /external/v1/runs/{session_id}/turn for same-session follow-ups.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/RunSetupRequest"
                  },
                  {
                    "type": "object",
                    "required": [
                      "question"
                    ],
                    "properties": {
                      "question": {
                        "type": "string",
                        "description": "Forward-looking question for Noah Predict."
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Fresh investigation accepted and queued. Poll the returned status URL for results.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "default": 5
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request. If document_review_route_required is returned, send the file/URL to /external/v1/document-reviews instead."
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          }
        }
      }
    },
    "/external/v1/document-reviews": {
      "post": {
        "operationId": "createDocumentReview",
        "summary": "Upload or link a PDF/TXT/HTML filing and queue a Document Positioning Review package.",
        "description": "Queued external API entry point for due-diligence/document-review reports. Upload the document as multipart field file/document, or send JSON with document_url, pdf_url, source_url, filing_url or attachments[].url. The response returns 202 Accepted with a session_id and run-scoped links for status, package, data-pack, Markdown report and PDF report artifacts.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DocumentReviewRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentReviewRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Document review accepted and queued. Poll links.status, then use links.package, links.data_pack, links.report_markdown, links.report_pdf or links.view_report_pdf for collection/viewing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "413": {
            "description": "File is above the current document-ingest ceiling."
          }
        }
      }
    },
    "/external/v1/market-edge/slates": {
      "post": {
        "operationId": "createMarketEdgeSlate",
        "summary": "Find and score a compact Market Edge card sheet.",
        "description": "Market Edge is the prediction-market product. This endpoint returns the card sheet as the primary artifact; report/PDF output is secondary.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketEdgeSlateRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Market Edge card-sheet run accepted and queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          }
        }
      }
    },
    "/external/v1/market-edge/positions/score": {
      "post": {
        "operationId": "scoreMarketEdgePositions",
        "summary": "Score supplied Polymarket/Kalshi questions into compact cards.",
        "description": "Accepts up to 40 exact positions/questions. It does not perform broad discovery unless the client uses the slate endpoint.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketEdgePositionsRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Position scoring accepted and queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          }
        }
      }
    },
    "/external/v1/market-edge/slates/{slate_id}/refresh": {
      "post": {
        "operationId": "refreshMarketEdgeSlate",
        "summary": "Refresh the same questions from an existing Market Edge card sheet.",
        "description": "Refreshes prices and Noah pressure for the existing slate. It does not discover new markets.",
        "parameters": [
          {
            "name": "slate_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Refresh accepted and queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/market-edge/slates/{slate_id}": {
      "get": {
        "operationId": "getMarketEdgeSlate",
        "summary": "Retrieve a compact Market Edge card sheet by slate/run ID.",
        "parameters": [
          {
            "name": "slate_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Market Edge card sheet returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketEdgeCardSheetResponse"
                }
              }
            }
          },
          "202": {
            "description": "Card sheet still building."
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/runs": {
      "get": {
        "operationId": "listRuns",
        "summary": "List recent API-created runs for the API key account.",
        "description": "Use this to recover a session ID after a client disconnect, timeout or failed poll loop.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 80,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recent API runs listed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          }
        }
      }
    },
    "/external/v1/runs/{session_id}": {
      "get": {
        "operationId": "getRunStatus",
        "summary": "Get lean run status for an API-created Noah Predict run.",
        "description": "Poll this endpoint until result_available is true, then fetch /result. Add ?debug=1 only when troubleshooting internal run state.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunStatusResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/runs/{session_id}/turn": {
      "post": {
        "operationId": "continueRun",
        "summary": "Queue a follow-up turn on the same API run/session.",
        "description": "Use this when an agent needs to update, sharpen or ask a follow-up on an existing report. Do not call /external/v1/reports to look again; that creates a new chat. Store the original session_id returned by the first run and use it here.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "message"
                ],
                "properties": {
                  "message": {
                    "type": "string",
                    "description": "Follow-up instruction. Example: update this report, then regenerate package artifacts."
                  },
                  "run_setup": {
                    "$ref": "#/components/schemas/RunSetupRequest"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Follow-up queued on the existing session. Poll /runs/{session_id}.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedRunResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Existing run is still in progress; poll status before queuing the follow-up."
          }
        }
      }
    },
    "/external/v1/runs/{session_id}/market-edge/card-sheet": {
      "get": {
        "operationId": "getRunMarketEdgeCardSheet",
        "summary": "Retrieve the compact Market Edge card sheet for a run.",
        "description": "For Market Edge workflows, this is the primary machine-facing artifact. Dashboards should read this instead of scraping a report PDF.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Market Edge card sheet returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketEdgeCardSheetResponse"
                }
              }
            }
          },
          "202": {
            "description": "Card sheet is not ready yet. Poll again after Retry-After seconds."
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/runs/{session_id}/result": {
      "get": {
        "operationId": "getRunResult",
        "summary": "Retrieve the completed assistant answer for a run.",
        "description": "This is the first stable result endpoint for headless clients. It returns the completed Markdown answer even when a structured package or data pack has not yet been prepared.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Completed run result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunResultResponse"
                }
              }
            }
          },
          "202": {
            "description": "Result is not ready yet. Poll again after Retry-After seconds."
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/runs/{session_id}/package": {
      "get": {
        "operationId": "getRunPackage",
        "summary": "Retrieve the latest structured Noah Predict package for a run.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Structured package.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "description": "Package is not ready or run was not found."
          }
        }
      }
    },
    "/external/v1/runs/{session_id}/data-pack": {
      "get": {
        "operationId": "downloadDataPack",
        "summary": "Download a redacted machine-readable JSON data pack.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON data pack attachment.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "description": "Data pack is not ready or run was not found."
          }
        }
      }
    },
    "/external/v1/runs/{session_id}/artifacts/report.md": {
      "get": {
        "operationId": "downloadReportMarkdown",
        "summary": "Download a Markdown report artifact.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Markdown report attachment.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "202": {
            "description": "Package is still being prepared. Poll again after Retry-After seconds."
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/runs/{session_id}/artifacts/report.pdf": {
      "get": {
        "operationId": "viewReportPDF",
        "summary": "View or download the generated report PDF artifact.",
        "description": "No UI button is required. When package_available is true, GET this URL with Authorization. Add disposition=inline to open/view the PDF in a browser-capable client; omit it for attachment download.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "disposition",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "inline",
                "attachment"
              ]
            },
            "description": "Use inline to view the PDF instead of downloading it as an attachment."
          }
        ],
        "responses": {
          "200": {
            "description": "Generated PDF report.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "202": {
            "description": "Package is still being prepared. Poll again after Retry-After seconds."
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/runs/{session_id}/artifacts/evidence.csv": {
      "get": {
        "operationId": "downloadEvidenceCSV",
        "summary": "Download a redacted evidence-footprint CSV.",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "CSV evidence-footprint attachment.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "202": {
            "description": "Package is still being prepared. Poll again after Retry-After seconds."
          },
          "401": {
            "$ref": "#/components/responses/AuthError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/external/v1/openapi.json": {
      "get": {
        "operationId": "getExternalOpenAPI",
        "summary": "Return the API-local OpenAPI description.",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "x-artifacts": {
    "description": "Run-scoped report artifacts use the same account ownership and package-read checks as package/data-pack retrieval.",
    "available": {
      "pdf": "GET /external/v1/runs/{session_id}/artifacts/report.pdf",
      "view_pdf": "GET /external/v1/runs/{session_id}/artifacts/report.pdf?disposition=inline",
      "markdown": "GET /external/v1/runs/{session_id}/artifacts/report.md",
      "evidence_csv": "GET /external/v1/runs/{session_id}/artifacts/evidence.csv"
    },
    "instruction": "For document-review workflows, poll /external/v1/runs/{session_id} until package_available and pdf_available are true. Then open view_pdf or download pdf. Do not use the UI Make PDF button."
  },
  "x-session-contract": {
    "canonical_handle": "session_id",
    "instruction": "Store the session_id returned by every create/run endpoint. Use it for polling, package/artifact download, and POST /external/v1/runs/{session_id}/turn follow-ups. Do not search dashboard chat history and do not call /external/v1/reports to look again.",
    "fresh_report_warning": "POST /external/v1/reports always creates a brand-new chat. If a document URL is present, use /external/v1/document-reviews instead."
  },
  "x-saved-chats": {
    "canonical_name": "Saved chats",
    "preferred_route": "GET /external/v1/saved-chats",
    "compatibility_route": "GET /external/v1/saved-reports",
    "selection_fields": [
      "id",
      "name",
      "brief",
      "machine_label",
      "report_family",
      "report_family_label",
      "bot_search_terms"
    ],
    "filters": {
      "q": "Search text across saved-chat labels and terms.",
      "report_family": "Use market_edge for saved Polymarket / Market Edge chats."
    },
    "market_edge_label": "Market Edge / Polymarket",
    "existing_saved_chat_action": "POST links.run on the selected row.",
    "new_extended_polymarket_action": "POST /external/v1/market-edge/slates"
  },
  "x-saved-reports": {
    "alias_of": "x-saved-chats",
    "canonical_name": "Saved chats",
    "compatibility_route": "GET /external/v1/saved-reports",
    "instruction": "Use this only for clients that say saved reports; the product section is Saved chats."
  },
  "x-market-edge": {
    "product": "Market Edge",
    "primary_artifact": "card sheet",
    "meaning": "Compares market-implied probability with Noah public-signal pressure probability. It is a repricing-pressure product, not a generic final-resolution oracle.",
    "primary_action": "refresh_card_sheet",
    "secondary_action": "open_report_pdf"
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Noah Predict account API key. Create inside the account area. Store only in server-side secret management."
      }
    },
    "schemas": {
      "RunSetupRequest": {
        "type": "object",
        "properties": {
          "framework_id": {
            "type": "string",
            "default": "auto"
          },
          "decision_purpose": {
            "type": "string",
            "default": "general",
            "description": "Audience/decision layer. Common values include general, underwriting, trading, investment_committee, bettor, compliance and executive."
          },
          "horizon": {
            "type": "string",
            "enum": [
              "7 days",
              "30 days",
              "90 days",
              "180 days"
            ],
            "default": "90 days"
          },
          "geography": {
            "type": "string"
          },
          "source_mode": {
            "type": "string",
            "default": "balanced"
          },
          "freshness": {
            "type": "string",
            "default": "recent"
          },
          "output_depth": {
            "type": "string",
            "enum": [
              "compact",
              "quick",
              "standard",
              "deep"
            ],
            "default": "standard"
          },
          "second_pass_preference": {
            "type": "string",
            "default": "auto"
          },
          "review_pace": {
            "type": "string",
            "enum": [
              "express_review",
              "ask_permission"
            ],
            "default": "express_review",
            "description": "External API runs default to express_review so Noah can continue through safe route steps and prepare a package without browser clicks."
          }
        }
      },
      "AcceptedRunResponse": {
        "type": "object",
        "required": [
          "ok",
          "accepted",
          "status",
          "session_id",
          "links"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "accepted": {
            "type": "boolean",
            "const": true
          },
          "status": {
            "type": "string",
            "enum": [
              "queued"
            ]
          },
          "session_id": {
            "type": "string"
          },
          "run_id": {
            "type": "string"
          },
          "retry_after_seconds": {
            "type": "integer",
            "default": 5
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string"
              },
              "continue": {
                "type": "string",
                "description": "POST here to queue a follow-up on this same session instead of creating a new chat."
              },
              "result": {
                "type": "string"
              },
              "runs": {
                "type": "string"
              },
              "package": {
                "type": "string"
              },
              "data_pack": {
                "type": "string"
              },
              "report_markdown": {
                "type": "string"
              },
              "report_pdf": {
                "type": "string"
              },
              "view_report_pdf": {
                "type": "string",
                "description": "Open/view form of the generated PDF; no UI Make PDF action is required."
              },
              "evidence_csv": {
                "type": "string"
              },
              "card_sheet": {
                "type": "string"
              },
              "market_edge_card_sheet": {
                "type": "string"
              }
            }
          },
          "recipe_id": {
            "type": "string"
          },
          "saved_chat_id": {
            "type": "string"
          },
          "object_type": {
            "type": "string"
          },
          "source_label": {
            "type": "string"
          },
          "legacy_source": {
            "type": "string"
          }
        }
      },
      "RunStatus": {
        "type": "string",
        "enum": [
          "queued",
          "running",
          "working",
          "completed",
          "package_running",
          "package_ready",
          "failed"
        ]
      },
      "MarketEdgeSlateRequest": {
        "type": "object",
        "required": [
          "arena"
        ],
        "properties": {
          "venue": {
            "type": "string",
            "default": "polymarket"
          },
          "venues": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "arena": {
            "type": "string",
            "description": "Broad market arena, for example US economic policy."
          },
          "max_results": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30,
            "default": 30
          },
          "investigation_mode": {
            "type": "string",
            "default": "compact_cards"
          },
          "exclude_questions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exclude_market_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exclude_event_slugs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exclude_keywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "filters": {
            "type": "object"
          }
        }
      },
      "MarketEdgePositionsRequest": {
        "type": "object",
        "required": [
          "positions"
        ],
        "properties": {
          "venue": {
            "type": "string",
            "default": "polymarket"
          },
          "investigation_mode": {
            "type": "string",
            "default": "compact_cards"
          },
          "max_positions": {
            "type": "integer",
            "minimum": 1,
            "maximum": 40,
            "default": 40
          },
          "positions": {
            "type": "array",
            "maxItems": 40,
            "items": {
              "type": "object",
              "properties": {
                "client_position_id": {
                  "type": "string"
                },
                "question": {
                  "type": "string"
                },
                "market_url": {
                  "type": "string"
                },
                "market_id": {
                  "type": "string"
                },
                "market_implied_probability_pct": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "question_id": {
                  "type": "string"
                },
                "question_url": {
                  "type": "string"
                },
                "event_id": {
                  "type": "string"
                },
                "event_url": {
                  "type": "string"
                },
                "event_slug": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "MarketEdgeCardRow": {
        "type": "object",
        "required": [
          "question",
          "market_implied_probability_pct",
          "edge_pp",
          "direction",
          "conviction_grade",
          "reason",
          "invalidator"
        ],
        "properties": {
          "venue": {
            "type": "string"
          },
          "market_id": {
            "type": "string"
          },
          "event_id": {
            "type": "string"
          },
          "event_slug": {
            "type": "string"
          },
          "market_url": {
            "type": "string"
          },
          "question": {
            "type": "string"
          },
          "outcome_side": {
            "type": "string",
            "default": "Yes"
          },
          "market_implied_probability_pct": {
            "type": [
              "number",
              "null"
            ]
          },
          "house_probability_pct": {
            "type": [
              "number",
              "null"
            ]
          },
          "noah_pressure_probability_pct": {
            "type": [
              "number",
              "null"
            ]
          },
          "edge_pp": {
            "type": [
              "number",
              "null"
            ]
          },
          "direction": {
            "type": "string"
          },
          "display_direction": {
            "type": "string"
          },
          "conviction_grade": {
            "type": "string"
          },
          "question_quality_grade": {
            "type": "string"
          },
          "tradeability_verdict": {
            "type": "string",
            "enum": [
              "",
              "cleaner_tradeable",
              "convex_pressure_tradeable",
              "tradable_with_caution",
              "watch_only",
              "reject"
            ]
          },
          "pressure_tradeability": {
            "type": "string"
          },
          "liquidity_usd": {
            "type": [
              "number",
              "null"
            ]
          },
          "volume_usd": {
            "type": [
              "number",
              "null"
            ]
          },
          "days_to_resolution": {
            "type": [
              "number",
              "null"
            ]
          },
          "contract_shape": {
            "type": "string"
          },
          "exact_bucket": {
            "type": "boolean"
          },
          "geometry_sensitive": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          },
          "invalidator": {
            "type": "string"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "refreshed_at": {
            "type": "string"
          },
          "client_position_id": {
            "type": "string"
          },
          "question_id": {
            "type": "string"
          },
          "question_slug": {
            "type": "string"
          },
          "question_url": {
            "type": "string"
          },
          "event_url": {
            "type": "string"
          },
          "polymarket_market_id": {
            "type": "string"
          },
          "polymarket_question_id": {
            "type": "string"
          },
          "polymarket_event_id": {
            "type": "string"
          },
          "polymarket_url": {
            "type": "string"
          },
          "client_match_key": {
            "type": "string"
          },
          "client_reference": {
            "type": "object",
            "description": "Stable downstream matching block preserving real venue IDs and URLs when present. IDs are blank rather than fabricated when a connector did not supply them."
          }
        }
      },
      "MarketEdgeCardSheet": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "compact_cards"
            ]
          },
          "requested_max": {
            "type": "integer"
          },
          "returned_count": {
            "type": "integer"
          },
          "limit_reason": {
            "type": "string",
            "enum": [
              "suitable_slate_exhausted",
              "time_budget_reached",
              "connector_limit",
              "ambiguity",
              "client_limit"
            ]
          },
          "discover_new_questions": {
            "type": "boolean"
          },
          "venue": {
            "type": "string"
          },
          "arena": {
            "type": "string"
          },
          "generated_at": {
            "type": "string"
          },
          "primary_action": {
            "type": "string",
            "enum": [
              "refresh_card_sheet"
            ]
          },
          "secondary_action": {
            "type": "string",
            "enum": [
              "open_report_pdf"
            ]
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketEdgeCardRow"
            }
          }
        }
      },
      "MarketEdgeCardSheetResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "session_id": {
            "type": "string"
          },
          "slate_id": {
            "type": "string"
          },
          "product": {
            "type": "string",
            "const": "Market Edge"
          },
          "artifact": {
            "type": "string",
            "const": "market_edge_card_sheet"
          },
          "market_edge_card_sheet": {
            "$ref": "#/components/schemas/MarketEdgeCardSheet"
          },
          "market_edge_table": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketEdgeCardRow"
            }
          },
          "links": {
            "type": "object"
          }
        }
      },
      "RecipeListResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "count": {
            "type": "integer"
          },
          "matched_count": {
            "type": "integer"
          },
          "total_available": {
            "type": "integer"
          },
          "filters": {
            "type": "object"
          },
          "family_counts": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "market_edge_saved_report_count": {
            "type": "integer"
          },
          "due_diligence_saved_report_count": {
            "type": "integer"
          },
          "recipes": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "saved_chats": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "saved_reports": {
            "type": "array",
            "description": "Alias of saved_chats for clients that use report language. Rows include report_family, report_family_label, machine_label, links.run and product-specific new-version links.",
            "items": {
              "type": "object"
            }
          },
          "naming_contract": {
            "type": "object"
          }
        }
      },
      "FrameListResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "count": {
            "type": "integer"
          },
          "decision_purposes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "frames": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "label",
                "description"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "audience": {
                  "type": "string"
                },
                "default_horizon": {
                  "type": "string"
                },
                "supported_decision_purposes": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "sample_question": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "RunListResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "count": {
            "type": "integer"
          },
          "runs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "session_id": {
                  "type": "string"
                },
                "run_id": {
                  "type": "string"
                },
                "status": {
                  "$ref": "#/components/schemas/RunStatus"
                },
                "created_at": {
                  "type": "string"
                },
                "updated_at": {
                  "type": "string"
                },
                "links": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "RunResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "session_id": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "next": {
            "type": "object"
          }
        }
      },
      "RunStatusResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "session_id": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/RunStatus"
          },
          "result_available": {
            "type": "boolean"
          },
          "result": {
            "type": "object"
          },
          "package_available": {
            "type": "boolean"
          },
          "pdf_available": {
            "type": "boolean",
            "description": "True when report_pdf/view_report_pdf can be fetched. Same readiness as package_available for current API artifacts."
          },
          "artifact_available": {
            "type": "object",
            "properties": {
              "report_pdf": {
                "type": "boolean"
              },
              "report_markdown": {
                "type": "boolean"
              },
              "evidence_csv": {
                "type": "boolean"
              }
            }
          },
          "route_readiness": {
            "type": "object"
          },
          "links": {
            "type": "object"
          }
        }
      },
      "RunResultResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "session_id": {
            "type": "string"
          },
          "run_id": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/RunStatus"
          },
          "result_available": {
            "type": "boolean"
          },
          "result": {
            "type": "object",
            "properties": {
              "available": {
                "type": "boolean"
              },
              "type": {
                "type": "string",
                "example": "assistant_reply_markdown"
              },
              "content_type": {
                "type": "string",
                "example": "text/markdown"
              },
              "markdown": {
                "type": "string"
              },
              "text": {
                "type": "string"
              },
              "as_of": {
                "type": "string"
              },
              "frame_id_resolved": {
                "type": "string"
              },
              "package_available": {
                "type": "boolean"
              }
            }
          },
          "links": {
            "type": "object"
          }
        }
      },
      "PackageResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "session_id": {
            "type": "string"
          },
          "package_id": {
            "type": "string"
          },
          "package": {
            "type": "object"
          },
          "links": {
            "type": "object"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "DocumentReviewRequest": {
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "PDF, TXT or HTML document. The alternate multipart field name document is also accepted."
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTPS URL for a PDF, TXT, HTML/XHTML filing page or SEC archive filing."
          },
          "pdf_url": {
            "type": "string",
            "format": "uri",
            "description": "Alias accepted for document_url."
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "description": "Alias accepted for document_url."
          },
          "filing_url": {
            "type": "string",
            "format": "uri",
            "description": "Alias accepted for document_url, useful for SEC/issuer filings."
          },
          "attachments": {
            "type": "array",
            "description": "Optional attachment list; the first object/string URL is used for document ingest.",
            "items": {
              "oneOf": [
                {
                  "type": "string",
                  "format": "uri"
                },
                {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "document_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "pdf_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "source_url": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              ]
            }
          },
          "question": {
            "type": "string",
            "description": "Optional instruction. Defaults to a full Document Positioning Review."
          },
          "decision_purpose": {
            "type": "string",
            "default": "due_diligence"
          },
          "horizon": {
            "type": "string",
            "default": "90 days"
          },
          "output_depth": {
            "type": "string",
            "enum": [
              "standard",
              "deep"
            ],
            "default": "deep"
          },
          "challenge": {
            "type": "boolean",
            "default": true,
            "description": "When true, runs bounded public-signal challenge for selected extracted claims."
          },
          "max_claims": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "default": 8
          },
          "feed_lane_emphasis": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "DocumentReviewResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "session_id": {
            "type": "string"
          },
          "run_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "package_ready"
            ]
          },
          "document_id": {
            "type": "string"
          },
          "document_context": {
            "type": "object"
          },
          "package_id": {
            "type": "string"
          },
          "package": {
            "type": "object",
            "description": "Structured package. Document logic lives under package.document_review."
          },
          "external_signal_challenge": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string"
              },
              "continue": {
                "type": "string"
              },
              "result": {
                "type": "string"
              },
              "package": {
                "type": "string"
              },
              "data_pack": {
                "type": "string"
              },
              "report_markdown": {
                "type": "string"
              },
              "report_pdf": {
                "type": "string"
              },
              "view_report_pdf": {
                "type": "string"
              },
              "evidence_csv": {
                "type": "string"
              },
              "browser_report": {
                "type": "string"
              }
            }
          },
          "next": {
            "type": "object"
          },
          "notice": {
            "type": "string"
          }
        }
      },
      "PromptTemplateRunRequest": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "description": "Fresh question to run through the prompt template."
          },
          "message": {
            "type": "string",
            "description": "Alias of question."
          },
          "prompt": {
            "type": "string",
            "description": "Alias of question."
          }
        }
      },
      "PromptTemplateListResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "count": {
            "type": "integer"
          },
          "matched_count": {
            "type": "integer"
          },
          "total_available": {
            "type": "integer"
          },
          "filters": {
            "type": "object"
          },
          "product_counts": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "prompt_templates": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "templates": {
            "type": "array",
            "description": "Alias of prompt_templates.",
            "items": {
              "type": "object"
            }
          },
          "naming_contract": {
            "type": "object"
          }
        }
      }
    },
    "responses": {
      "AuthError": {
        "description": "Missing, invalid, revoked or insufficiently scoped API key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found or not owned by the account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Bad request.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  },
  "x-document-review": {
    "product": "Document Positioning Review / Predictive Due Diligence",
    "entry_point": "POST /external/v1/document-reviews",
    "accepted_document_inputs": [
      "multipart file",
      "multipart document",
      "JSON document_url",
      "JSON pdf_url",
      "JSON source_url",
      "JSON filing_url",
      "JSON attachments[].url"
    ],
    "primary_machine_output": "GET /external/v1/runs/{session_id}/package or /data-pack",
    "report_artifacts": {
      "markdown": "GET /external/v1/runs/{session_id}/artifacts/report.md",
      "pdf": "GET /external/v1/runs/{session_id}/artifacts/report.pdf",
      "view_pdf": "GET /external/v1/runs/{session_id}/artifacts/report.pdf?disposition=inline"
    },
    "instruction": "Do not send document URLs to /external/v1/reports. Use /external/v1/document-reviews so Noah ingests the document and builds package.document_review. Poll /runs/{session_id} until package_available and pdf_available are true, then open view_pdf or fetch pdf. No UI Make PDF button is required. Do not scrape the browser report. Use the returned links and Authorization header."
  },
  "x-prompt-templates": {
    "canonical_name": "Prompt templates",
    "preferred_route": "GET /external/v1/prompt-templates",
    "selection_fields": [
      "id",
      "name",
      "description",
      "example_question",
      "machine_label",
      "frame_id",
      "product_group",
      "bot_search_terms"
    ],
    "filters": {
      "q": "Search text across prompt-template labels and terms.",
      "frame_id": "Filter by saved method/frame/product group."
    },
    "run_action": "POST /external/v1/prompt-templates/{template_id}/run with question/message to create a fresh run.",
    "relationship_to_saved_chats": "Prompt templates reuse method memory for new work. Saved chats reopen or refresh prior work."
  }
}
