{"openapi":"3.1.0","info":{"title":"Agentic Data Scientist","version":"0.3.0"},"paths":{"/api/feedback":{"post":{"summary":"Submit Feedback","description":"Capture a satisfaction score (1-10) plus optional written feedback.\n\nBody: {\"score\": int, \"message\": str, \"context\": dict | null}\nEach submission lands as its own JSON file in S3 under the user's\nfeedback/ prefix.","operationId":"submit_feedback_api_feedback_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/quota":{"get":{"summary":"Get Quota","description":"Current user's monthly spend, limit, and reset date.\n\nFrontend reads this on app load + after a 402 to know how much of the\ncap has been used and when it resets. BYOT projects don't count.","operationId":"get_quota_api_quota_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me":{"get":{"summary":"Get Me","description":"Returns the authenticated user's profile.","operationId":"get_me_api_auth_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/status":{"get":{"summary":"Auth Status","description":"Public endpoint that tells the frontend whether Supabase is enabled.","operationId":"auth_status_api_auth_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/auth/check-promo":{"post":{"summary":"Check Promo","description":"Public pre-sign-up check for the closed-beta promo gate.\n\nReturns whether the submitted code is valid so the frontend can show a\nclean error before calling supabase.auth.signUp(). The real enforcement\nis a BEFORE INSERT trigger on auth.users (see SUPABASE_PROFILES_SETUP.md);\nthis endpoint is purely for the user-facing message.","operationId":"check_promo_api_auth_check_promo_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoCheck"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/config":{"get":{"summary":"Billing Config","description":"Top-up config (min/max/step + preset amounts). Public so the pricing\nUI can render without auth.","operationId":"billing_config_api_billing_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/billing/balance":{"get":{"summary":"Get Billing Balance","description":"Credit balance + payment history for the Account page.\n\nNew model: a one-time $50 promo credit (lifetime) + purchased credits\nthat expire 12 months after purchase. No monthly reset.","operationId":"get_billing_balance_api_billing_balance_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/checkout":{"post":{"summary":"Create Billing Checkout","description":"Start a Stripe Checkout Session. Body: {\"amount_usd\": number}.","operationId":"create_billing_checkout_api_billing_checkout_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/webhook":{"post":{"summary":"Stripe Webhook","description":"Stripe webhook receiver. No auth — signature verifies authenticity.\n\nNOTE: this route reads the raw request body. Do NOT add body-parsing\nmiddleware in front of it.","operationId":"stripe_webhook_api_billing_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/projects":{"get":{"summary":"List Projects","description":"List projects for the current user.\n\nQuery params:\n  incognito=false (default): only persistent projects (the normal\n    history view). Lazy-hydrates from S3 so a fresh container still\n    shows the user's full history.\n  incognito=true: only the in-memory incognito projects belonging to\n    the user. These never touched S3, so no hydration needed.","operationId":"list_projects_api_projects_get","parameters":[{"name":"incognito","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Incognito"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Create Project","description":"Create a new project with optional file uploads.","operationId":"create_project_api_projects_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_project_api_projects_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}":{"get":{"summary":"Get Project","operationId":"get_project_api_projects__project_id__get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"full","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Full"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"summary":"Patch Project","description":"Update mutable fields on a project. Currently supports `query` (rename).","operationId":"patch_project_api_projects__project_id__patch","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Project","operationId":"delete_project_api_projects__project_id__delete","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/cost":{"get":{"summary":"Get Project Cost","description":"Return token usage and USD cost breakdown for a project.","operationId":"get_project_cost_api_projects__project_id__cost_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/papers":{"get":{"summary":"List Paper Generations","description":"List every paper generation for this project (history with costs).","operationId":"list_paper_generations_api_projects__project_id__papers_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/papers/{paper_id}/{generation_index}":{"get":{"summary":"Get Paper Version","description":"Download one paper version (302 → presigned S3 URL, attachment).\n\n``fmt`` is the preferred format ('pdf' default, or 'md'). When the\npreferred format isn't in S3 (e.g. PDF generation failed) we transparently\nfall back to the other so the user still gets a file — from their\nperspective the download behaves the same, a .md just pops out instead.","operationId":"get_paper_version_api_projects__project_id__papers__paper_id___generation_index__get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"generation_index","in":"path","required":true,"schema":{"type":"integer","title":"Generation Index"}},{"name":"fmt","in":"query","required":false,"schema":{"type":"string","default":"pdf","title":"Fmt"}},{"name":"ft","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ft"}},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/papers/{paper_id}/{generation_index}/view":{"get":{"summary":"View Paper Version","description":"Resolve a paper version for in-app viewing.\n\nReturns ``{\"fmt\": \"pdf\"|\"md\", \"url\": <inline presigned URL>}`` for the\npreferred format, falling back to the other when missing. The URL has no\nattachment disposition so the PDF/markdown viewer can load it directly.","operationId":"view_paper_version_api_projects__project_id__papers__paper_id___generation_index__view_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"generation_index","in":"path","required":true,"schema":{"type":"integer","title":"Generation Index"}},{"name":"prefer","in":"query","required":false,"schema":{"type":"string","default":"pdf","title":"Prefer"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/cache-report":{"get":{"summary":"Get Cache Report","description":"Per-agent prompt-cache call counts and warm-miss counts.\n\nA non-zero ``warm_misses`` for any agent means a 2nd+ call within\nthis project showed ``cache_read_input_tokens == 0`` despite the\nprompt being above the cacheable size threshold — the cache_control\nboundary for that agent is misplaced (or caching is silently off).","operationId":"get_cache_report_api_projects__project_id__cache_report_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/stop-correction":{"post":{"summary":"Stop Correction","description":"Cancel a running correction/Q&A task.","operationId":"stop_correction_api_projects__project_id__stop_correction_post","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/stop":{"post":{"summary":"Stop Project","operationId":"stop_project_api_projects__project_id__stop_post","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/turns":{"post":{"summary":"Append Turn","description":"Append a follow-up query to a project (Phase 2 conversation mode).\n\nIf the project is currently running, the query is queued and will start\nautomatically when the current turn finishes (Q3=b). If idle, the agent\nis dispatched immediately.","operationId":"append_turn_api_projects__project_id__turns_post","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowupCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/incognito":{"delete":{"summary":"Delete Incognito Projects","description":"Wipe every incognito project for the calling user.\n\nCalled by the frontend when the user exits incognito mode or signs\nout. Idempotent — returns the count of projects actually deleted.","operationId":"delete_incognito_projects_api_projects_incognito_delete","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/stream":{"get":{"summary":"Stream Events","description":"Server-Sent Events stream for real-time project updates.\n\nHardened against the project being deleted mid-stream (e.g. incognito\nexit). Every iteration checks whether the project still exists; if not,\nwe send a 'done' event and close the stream cleanly instead of hanging.","operationId":"stream_events_api_projects__project_id__stream_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"after","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"After"}},{"name":"ft","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ft"}},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/tree":{"get":{"summary":"Get Project Tree","description":"Return every file in the project's output directory as a flat list.\n\nThis backs the All-data browser: a fallback view of the run's real\ndirectory structure, so a file is reachable even when no gallery\nclassifies it. Local disk and S3 are merged — a run that has been evicted\nfrom local cache still lists from S3, and an in-flight run lists files that\nhave not been uploaded yet.\n\nDot-directories (``.venv``, ``.git``, ``.claude``, …) and their non-dot\nequivalents are always skipped — they are machine noise, never run output.\n\nPaths are relative to the project's ``output/`` root, matching what\n``GET /api/projects/{id}/files/{path}`` expects.","operationId":"get_project_tree_api_projects__project_id__tree_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/file-token":{"post":{"summary":"Mint File Token","description":"Issue a short-lived token for this project's asset URLs.\n\nHeader-authenticated, so the account JWT never reaches a URL. The returned\ntoken authorises only this project and expires in minutes — see\nweb.backend.file_tokens.","operationId":"mint_file_token_api_projects__project_id__file_token_post","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/files/{file_path}":{"get":{"summary":"Get File","description":"Serve a generated file.\n\nSmall files are streamed through this endpoint so the browser never holds a\npresigned S3 URL. Large ones still redirect to S3 — with a short expiry —\nbecause pushing hundreds of megabytes through this single-threaded server\nis what the redirect was introduced to avoid.","operationId":"get_file_api_projects__project_id__files__file_path__get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"file_path","in":"path","required":true,"schema":{"type":"string","title":"File Path"}},{"name":"ft","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ft"}},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/correct":{"post":{"summary":"Correct Project","description":"Apply a quick correction to a specific file or ask a question about the results.\n\nThree auto-detected modes:\n- Text correction (target is .md/.txt) → LLM edits the file in-place\n- Figure correction (target is .png/.svg) → LLM modifies the script + re-runs it\n- Q&A (no target) → LLM answers a question about the paper/results","operationId":"correct_project_api_projects__project_id__correct_post","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CorrectionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/paper.pdf":{"get":{"summary":"Get Paper Pdf","description":"Serve the generated PDF paper. Uses S3 pre-signed URL if available.","operationId":"get_paper_pdf_api_projects__project_id__paper_pdf_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"ft","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ft"}},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/paper/view":{"get":{"summary":"View Paper","description":"Resolve the current paper for in-app viewing.\n\nReturns ``{\"fmt\": \"pdf\"|\"md\", \"url\": <inline presigned URL>}`` for the\npreferred format (falling back to the other when missing), so the frontend\ncan render it in the PDF viewer or markdown viewer without downloading.","operationId":"view_paper_api_projects__project_id__paper_view_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"prefer","in":"query","required":false,"schema":{"type":"string","default":"pdf","title":"Prefer"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/paper/scientific":{"post":{"summary":"Generate Scientific Paper","description":"Generate a publication-quality paper using claude-scientific-writer.\n\nRuns in a background thread. The frontend polls /api/projects/{id} until\npaper_content appears. The resulting LaTeX PDF is served at the existing\n/api/projects/{id}/paper.pdf endpoint.","operationId":"generate_scientific_paper_api_projects__project_id__paper_scientific_post","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScientificPaperRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/confirm-discovery":{"post":{"summary":"Confirm Discovery","description":"User confirms or edits the research question after discovery, then analysis starts.","operationId":"confirm_discovery_api_projects__project_id__confirm_discovery_post","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/data-suggestions/{suggestion_type}":{"post":{"summary":"Generate Data Suggestions","description":"Generate in-silico or experimental data suggestions.","operationId":"generate_data_suggestions_api_projects__project_id__data_suggestions__suggestion_type__post","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"suggestion_type","in":"path","required":true,"schema":{"type":"string","title":"Suggestion Type"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/uploads/init":{"post":{"summary":"Uploads Init","description":"Start a multipart upload. Returns {key, upload_id, part_size}.\n\nBody: {\"filename\": str, \"content_type\": str | null, \"batch_id\": str | null}","operationId":"uploads_init_api_uploads_init_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/uploads/sign-part":{"post":{"summary":"Uploads Sign Part","description":"Return a presigned PUT URL for one part. Body: {key, upload_id, part_number}.","operationId":"uploads_sign_part_api_uploads_sign_part_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/uploads/complete":{"post":{"summary":"Uploads Complete","description":"Finalize a multipart upload. Body: {key, upload_id, parts: [{ETag, PartNumber}]}.","operationId":"uploads_complete_api_uploads_complete_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/uploads/abort":{"post":{"summary":"Uploads Abort","description":"Cancel an in-flight upload. Body: {key, upload_id}.","operationId":"uploads_abort_api_uploads_abort_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"Body_create_project_api_projects_post":{"properties":{"query":{"type":"string","title":"Query"},"mode":{"type":"string","title":"Mode","default":"orchestrated"},"num_papers":{"type":"integer","title":"Num Papers","default":10},"days_back":{"type":"integer","title":"Days Back","default":30},"model_provider":{"type":"string","title":"Model Provider","default":""},"planning_model":{"type":"string","title":"Planning Model","default":""},"coding_model":{"type":"string","title":"Coding Model","default":""},"model_api_base":{"type":"string","title":"Model Api Base","default":""},"model_api_key":{"type":"string","title":"Model Api Key","default":""},"base_project_id":{"type":"string","title":"Base Project Id","default":""},"pharos_workflow":{"type":"string","title":"Pharos Workflow","default":""},"pharos_mcp_url":{"type":"string","title":"Pharos Mcp Url","default":""},"incognito":{"type":"string","title":"Incognito","default":""},"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files","default":[]},"staged_keys":{"type":"string","title":"Staged Keys","default":""}},"type":"object","required":["query"],"title":"Body_create_project_api_projects_post"},"CorrectionRequest":{"properties":{"instruction":{"type":"string","title":"Instruction"},"target_file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target File"}},"type":"object","required":["instruction"],"title":"CorrectionRequest","description":"Body for POST /api/projects/{id}/correct — quick targeted correction."},"FollowupCreate":{"properties":{"query":{"type":"string","title":"Query"},"confirmed_modify":{"type":"boolean","title":"Confirmed Modify","default":false}},"type":"object","required":["query"],"title":"FollowupCreate","description":"Body for POST /api/projects/{id}/turns — append a follow-up query."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"PromoCheck":{"properties":{"promo_code":{"type":"string","title":"Promo Code","default":""}},"type":"object","title":"PromoCheck","description":"Body for POST /api/auth/check-promo — closed-beta sign-up gate."},"ScientificPaperRequest":{"properties":{"query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query"},"effort_level":{"type":"string","title":"Effort Level","default":"medium"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instructions"},"track_token_usage":{"type":"boolean","title":"Track Token Usage","default":true}},"type":"object","title":"ScientificPaperRequest","description":"Request body for scientific paper generation via claude-scientific-writer."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}