{"openapi":"3.1.0","info":{"title":"Plant Disease APIN Server","description":"APIN — Adaptive Pathological Intelligence Network","version":"1.0"},"paths":{"/apin/info":{"get":{"summary":"Apin Info","operationId":"apin_info_apin_info_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/predict":{"post":{"summary":"Predict Legacy","description":"Model 2 only (faster, legacy).","operationId":"predict_legacy_predict_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_predict_legacy_predict_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/predict/apin":{"post":{"summary":"Predict Apin","description":"Full APIN ensemble inference.","operationId":"predict_apin_predict_apin_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_predict_apin_predict_apin_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feedback":{"post":{"summary":"Feedback","description":"Record farmer correction. Schema:\nprediction_id    (str, optional)  — id from prior /predict response\nis_correct       (bool, required)\ncorrect_class    (str, required if is_correct=False)\npredicted_class  (str, optional)  — for already-correct rejection\ngeographic_hint  (str, optional)  — for clonal-amplification weighting","operationId":"feedback_feedback_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Payload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feedback/retrain":{"post":{"summary":"Feedback Retrain","description":"Manually trigger a retrain if readiness is met and rate-limit allows.\nReturns 202 if dispatched, 400 if not ready, 429 if rate-limited.","operationId":"feedback_retrain_feedback_retrain_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/feedback/retrain/history":{"get":{"summary":"Feedback Retrain History","operationId":"feedback_retrain_history_feedback_retrain_history_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/feedback/stats":{"get":{"summary":"Feedback Stats","description":"Aggregate stats with recency-weighted counts per class.\n\nready_for_retrain: True when total wrong corrections ≥ 10 AND at\nleast 3 independent classes have ≥ 3 wrong corrections each. This\nis the trigger architecture Section 10.2/10.3 specifies before\nretraining the stacking MLP on new data.","operationId":"feedback_stats_feedback_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"summary":"V2 Index","operationId":"v2_index__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/landing":{"get":{"summary":"V2 Landing","operationId":"v2_landing_landing_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/favicon.svg":{"get":{"summary":"V2 Favicon Svg","operationId":"v2_favicon_svg_favicon_svg_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/favicon.ico":{"get":{"summary":"V2 Favicon Ico","operationId":"v2_favicon_ico_favicon_ico_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/logo.png":{"get":{"summary":"V2 Logo Png","operationId":"v2_logo_png_logo_png_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/apin_sw.js":{"get":{"summary":"V2 Apin Sw","operationId":"v2_apin_sw_apin_sw_js_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/robots.txt":{"get":{"summary":"V2 Robots","operationId":"v2_robots_robots_txt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/sitemap.xml":{"get":{"summary":"V2 Sitemap","operationId":"v2_sitemap_sitemap_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/check":{"get":{"tags":["auth"],"summary":"Check Uniqueness","description":"Live uniqueness probe. Returns {available, reason?, suggestions?}.","operationId":"check_uniqueness_auth_check_get","parameters":[{"name":"field","in":"query","required":true,"schema":{"type":"string","pattern":"^(username|email|display_name)$","title":"Field"}},{"name":"value","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"title":"Value"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/next-accession":{"get":{"tags":["auth"],"summary":"Next Accession Endpoint","description":"Return the next-to-be-assigned user id.","operationId":"next_accession_endpoint_auth_next_accession_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/signup":{"post":{"tags":["auth"],"summary":"Signup","operationId":"signup_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupPayload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/login":{"post":{"tags":["auth"],"summary":"Login","operationId":"login_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginPayload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/admin/request-code":{"post":{"tags":["auth"],"summary":"Admin Request Code","description":"Step 1 of admin MFA. If this is a trusted device → auto-elevate. Else\nmint + email a 6-digit code (rate-limited).","operationId":"admin_request_code_auth_admin_request_code_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/admin/verify":{"post":{"tags":["auth"],"summary":"Admin Verify","description":"Step 2 of admin MFA. Verify the code; on success elevate the session and\n(if remember) trust this device for 7 days.","operationId":"admin_verify_auth_admin_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminVerifyPayload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","operationId":"logout_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/guest":{"post":{"tags":["auth"],"summary":"Guest","description":"Start (or resume) an anonymous guest session.\n\nA guest gets GUEST_INFERENCE_LIMIT free inference checks and no\ndashboard/account access. If the caller is already a signed-in user,\nthis is a no-op that just reports their authenticated state. If they\nalready hold a non-expired guest cookie, that session is reused so\nrefreshing the page doesn't reset the quota.","operationId":"guest_auth_guest_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/state":{"get":{"tags":["auth"],"summary":"State","description":"Single source of truth for the frontend's auth state. Always 200.\n\nReturns one of:\n  {\"mode\": \"user\",      \"user\": {...}}\n  {\"mode\": \"guest\",     \"guest\": {\"remaining\": N, \"limit\": M}}\n  {\"mode\": \"anonymous\"}\nThe inference page calls this once on load to decide whether to show\nthe account chip, the guest counter, or nothing.","operationId":"state_auth_state_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/me":{"get":{"tags":["auth"],"summary":"Me","operationId":"me_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/session":{"get":{"tags":["auth"],"summary":"Session Info","description":"Return the current session's expiry + created_at + a derived\n`idle_warning_at` so the client can schedule its warning modal without\na second clock-syncing round trip.","operationId":"session_info_auth_session_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/extend":{"post":{"tags":["auth"],"summary":"Extend","description":"Slide the session expiry forward by SESSION_LIFETIME (or the user's\nconfigured `session_absolute_ttl_seconds` in account_settings, if set).\n\nCap: cannot exceed the absolute TTL above the session's `created_at`.\nOnce a session has lived its full absolute lifetime, extension is\nrefused with 409 — the client should sign out and back in.","operationId":"extend_auth_extend_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/history":{"get":{"tags":["auth"],"summary":"History","description":"Return paginated prediction history for the current user.","operationId":"history_auth_history_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/history/{prediction_id}":{"get":{"tags":["auth"],"summary":"History Detail","description":"Full response_json for one prediction, scoped to current user.","operationId":"history_detail_auth_history__prediction_id__get","parameters":[{"name":"prediction_id","in":"path","required":true,"schema":{"type":"integer","title":"Prediction Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard":{"get":{"summary":"V2 Dashboard","operationId":"v2_dashboard_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/dashboard/history":{"get":{"summary":"V2 Dashboard History","operationId":"v2_dashboard_history_dashboard_history_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/dashboard/data":{"get":{"summary":"V2 Dashboard Data","operationId":"v2_dashboard_data_dashboard_data_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/history/data":{"get":{"summary":"V2 History Data","operationId":"v2_history_data_dashboard_history_data_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/history/export.csv":{"get":{"summary":"V2 History Export Csv","operationId":"v2_history_export_csv_dashboard_history_export_csv_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/history/export.json":{"get":{"summary":"V2 History Export Json","operationId":"v2_history_export_json_dashboard_history_export_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/prediction/{pred_id}":{"get":{"summary":"V2 Prediction Detail","operationId":"v2_prediction_detail_dashboard_prediction__pred_id__get","parameters":[{"name":"pred_id","in":"path","required":true,"schema":{"type":"integer","title":"Pred Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/disease/{class_name}/predictions":{"get":{"summary":"V2 Disease Predictions","operationId":"v2_disease_predictions_dashboard_disease__class_name__predictions_get","parameters":[{"name":"class_name","in":"path","required":true,"schema":{"type":"string","title":"Class Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/taxonomy":{"get":{"summary":"V2 Taxonomy","operationId":"v2_taxonomy_dashboard_taxonomy_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/notes":{"get":{"summary":"V2 Notes List","operationId":"v2_notes_list_dashboard_notes_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"V2 Notes Create","operationId":"v2_notes_create_dashboard_notes_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/notes/{note_id}":{"patch":{"summary":"V2 Notes Update","operationId":"v2_notes_update_dashboard_notes__note_id__patch","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","title":"Note Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"V2 Notes Delete","operationId":"v2_notes_delete_dashboard_notes__note_id__delete","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","title":"Note Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/reports":{"get":{"summary":"V2 Reports Page","operationId":"v2_reports_page_dashboard_reports_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/dashboard/loupe":{"get":{"summary":"V2 Loupe Page","operationId":"v2_loupe_page_dashboard_loupe_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/dashboard/gallery":{"get":{"summary":"V2 Gallery Page","operationId":"v2_gallery_page_dashboard_gallery_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/dashboard/settings":{"get":{"summary":"V2 Settings Page","operationId":"v2_settings_page_dashboard_settings_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/dashboard/treatments":{"get":{"summary":"V2 Treatments List","operationId":"v2_treatments_list_dashboard_treatments_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"V2 Treatments Create","operationId":"v2_treatments_create_dashboard_treatments_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/treatments/{tid}":{"patch":{"summary":"V2 Treatments Update","operationId":"v2_treatments_update_dashboard_treatments__tid__patch","parameters":[{"name":"tid","in":"path","required":true,"schema":{"type":"integer","title":"Tid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"V2 Treatments Delete","operationId":"v2_treatments_delete_dashboard_treatments__tid__delete","parameters":[{"name":"tid","in":"path","required":true,"schema":{"type":"integer","title":"Tid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/treatments/export.csv":{"get":{"summary":"V2 Treatments Export Csv","operationId":"v2_treatments_export_csv_dashboard_treatments_export_csv_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/shares":{"get":{"summary":"V2 Shares List","operationId":"v2_shares_list_dashboard_shares_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"V2 Shares Create","operationId":"v2_shares_create_dashboard_shares_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/shares/{sid}":{"delete":{"summary":"V2 Shares Revoke","operationId":"v2_shares_revoke_dashboard_shares__sid__delete","parameters":[{"name":"sid","in":"path","required":true,"schema":{"type":"integer","title":"Sid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/share/{token}":{"get":{"summary":"V2 Share View","operationId":"v2_share_view_share__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/share/{token}/data":{"get":{"summary":"V2 Share Data","operationId":"v2_share_data_share__token__data_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/share/{token}/image":{"get":{"summary":"V2 Share Image","operationId":"v2_share_image_share__token__image_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/share/{token}/heatmap":{"get":{"summary":"V2 Share Heatmap","operationId":"v2_share_heatmap_share__token__heatmap_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/predictions/{pid}/image":{"get":{"summary":"V2 Pred Image","operationId":"v2_pred_image_dashboard_predictions__pid__image_get","parameters":[{"name":"pid","in":"path","required":true,"schema":{"type":"integer","title":"Pid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/predictions/{pid}/heatmap":{"get":{"summary":"V2 Pred Heatmap","operationId":"v2_pred_heatmap_dashboard_predictions__pid__heatmap_get","parameters":[{"name":"pid","in":"path","required":true,"schema":{"type":"integer","title":"Pid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/reports/list":{"get":{"summary":"V2 Reports List","operationId":"v2_reports_list_dashboard_reports_list_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/reports/generate":{"post":{"summary":"V2 Reports Generate","operationId":"v2_reports_generate_dashboard_reports_generate_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/dashboard/reports/{rid}/pdf":{"get":{"summary":"V2 Report Pdf","operationId":"v2_report_pdf_dashboard_reports__rid__pdf_get","parameters":[{"name":"rid","in":"path","required":true,"schema":{"type":"integer","title":"Rid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/reports/{rid}/delete":{"post":{"summary":"V2 Report Delete","operationId":"v2_report_delete_dashboard_reports__rid__delete_post","parameters":[{"name":"rid","in":"path","required":true,"schema":{"type":"integer","title":"Rid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/reports/{rid}/restore":{"post":{"summary":"V2 Report Restore","operationId":"v2_report_restore_dashboard_reports__rid__restore_post","parameters":[{"name":"rid","in":"path","required":true,"schema":{"type":"integer","title":"Rid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/predict/full":{"post":{"summary":"V2 Predict Full","description":"V2 override: preserves okra/brassica/chilli behavior byte-for-byte,\nroutes tomato to TomatoPipeline for ensemble inference.\n\nDay-4 addition: when the request carries a valid session cookie, the\nprediction is written to the `predictions` table after the response\nis returned (via FastAPI BackgroundTasks). Anonymous requests are NOT\nrecorded (privacy-preserving default).","operationId":"v2_predict_full_predict_full_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v2_predict_full_predict_full_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/warmup/status":{"get":{"summary":"V2 Warmup Status","operationId":"v2_warmup_status_warmup_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/status":{"get":{"summary":"V2 Status Page","operationId":"v2_status_page_status_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/status/data":{"get":{"summary":"V2 Status Data","operationId":"v2_status_data_status_data_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"V2 Health","operationId":"v2_health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/probe/external":{"get":{"summary":"V2 External Probe","operationId":"v2_external_probe_api_probe_external_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/version":{"get":{"summary":"V1 Version","operationId":"v1_version_api_version_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/diseases":{"get":{"summary":"V1 Diseases","operationId":"v1_diseases_api_diseases_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/diseases/{disease_class}":{"get":{"summary":"V1 Disease Detail","operationId":"v1_disease_detail_api_diseases__disease_class__get","parameters":[{"name":"disease_class","in":"path","required":true,"schema":{"type":"string","title":"Disease Class"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/model/card":{"get":{"summary":"V1 Model Card","operationId":"v1_model_card_api_model_card_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/benchmarks":{"get":{"summary":"V1 Benchmarks","operationId":"v1_benchmarks_api_benchmarks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/warmup":{"post":{"summary":"V1 Warmup","description":"Trigger lazy-loading of every APIN signal. Idempotent and\nexecutor-backed: the heavy load runs in a worker thread so the\nevent loop continues to serve `/health`, `/status`, etc. while\nmodels warm up.\n\nA short cooldown rate-limits concurrent callers: if the previous\ncall was less than _warmup_state['cooldown_s'] seconds ago and\nanother call is already in flight, the new caller is fast-pathed\nwith `coalesced: True` instead of triggering a second load.\nAuthoritative readiness still comes from GET /warmup/status.","operationId":"v1_warmup_api_warmup_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/predict/quick":{"post":{"summary":"V1 Predict Quick","operationId":"v1_predict_quick_api_predict_quick_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v1_predict_quick_api_predict_quick_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/predict/batch":{"post":{"summary":"V1 Predict Batch","operationId":"v1_predict_batch_api_predict_batch_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v1_predict_batch_api_predict_batch_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys":{"get":{"summary":"V1 Keys List","operationId":"v1_keys_list_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"V1 Keys Create","operationId":"v1_keys_create_api_keys_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/keys/{key_id}":{"delete":{"summary":"V1 Keys Revoke","operationId":"v1_keys_revoke_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/info":{"get":{"summary":"V1 Apin Info","operationId":"v1_apin_info_api_info_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/feedback/stats":{"get":{"summary":"V1 Feedback Stats","operationId":"v1_feedback_stats_api_feedback_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/retrain/history":{"get":{"summary":"V1 Retrain History","operationId":"v1_retrain_history_api_retrain_history_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/feedback":{"post":{"summary":"V1 Feedback","description":"Submit a correction or confirmation against a past prediction.\n\nBearer auth is OPTIONAL on this endpoint: anonymous feedback is\naccepted (mirrors the legacy /feedback behaviour so the public\nfarmer feedback button keeps working), but feedback with a valid\nBearer token is tagged with the user_id and shows up in their\nretraining-influence dashboard.","operationId":"v1_feedback_api_feedback_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/predict/full":{"post":{"summary":"V1 Predict Full","operationId":"v1_predict_full_api_predict_full_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v1_predict_full_api_predict_full_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/docs":{"get":{"summary":"Docs Page","operationId":"docs_page_docs_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/scan":{"post":{"summary":"V1 Scan","description":"Run inference on one drone frame and persist the result.\n\nReturns the scan record + a single RFC 7946 GeoJSON Feature\nready to drop into a Mapbox / QGIS / Leaflet layer.","operationId":"v1_scan_api_scan_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v1_scan_api_scan_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/scan/batch":{"post":{"summary":"V1 Scan Batch","operationId":"v1_scan_batch_api_scan_batch_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v1_scan_batch_api_scan_batch_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/scans":{"get":{"summary":"V1 Scans List","operationId":"v1_scans_list_api_scans_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Page Size"}},{"name":"flight_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flight Id"}},{"name":"diagnosis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Diagnosis"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO-8601 lower bound on captured_at","title":"Since"},"description":"ISO-8601 lower bound on captured_at"},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO-8601 upper bound on captured_at","title":"Until"},"description":"ISO-8601 upper bound on captured_at"},{"name":"as_geojson","in":"query","required":false,"schema":{"type":"integer","description":"If 1, include a FeatureCollection","default":0,"title":"As Geojson"},"description":"If 1, include a FeatureCollection"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/scans/{scan_uid}":{"get":{"summary":"V1 Scan Get","operationId":"v1_scan_get_api_scans__scan_uid__get","parameters":[{"name":"scan_uid","in":"path","required":true,"schema":{"type":"string","title":"Scan Uid"}},{"name":"include","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated extras: 'result', 'image'","title":"Include"},"description":"Comma-separated extras: 'result', 'image'"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"V1 Scan Delete","operationId":"v1_scan_delete_api_scans__scan_uid__delete","parameters":[{"name":"scan_uid","in":"path","required":true,"schema":{"type":"string","title":"Scan Uid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/recent":{"get":{"summary":"Api Recent","description":"Return the N most recent HTTP requests this process has\nhandled. Skips static assets. Carries path templates only;\nnever request bodies, auth tokens, or user identifiers.","operationId":"api_recent_api_recent_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Number of recent requests to return (1-200, default 50).","default":50,"title":"Limit"},"description":"Number of recent requests to return (1-200, default 50)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/pipeline":{"get":{"summary":"Pipeline Page","operationId":"pipeline_page_pipeline_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/pipeline_data/{slug}":{"get":{"summary":"Pipeline Data","operationId":"pipeline_data_api_pipeline_data__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stats/summary":{"get":{"summary":"V2 Stats Summary","description":"Aggregate snapshot for the Pipeline Atlas KPI tiles.\n\nReturns:\n  inferences_served : {total, user, guest, scan}\n  top_disease       : {class, count, share, window_days} or null\n  live_activity     : {last_60s_count, last_5min_count,\n                       last_hour_count, median_latency_ms,\n                       error_rate_pct, as_of}\n  test_quality      : (placeholder; populated by Phase 4D extractor)\n\nThe endpoint is intentionally cheap — it issues four COUNT(*) /\nGROUP BY queries against indexed columns. Safe to poll every 5-10s.","operationId":"v2_stats_summary_api_stats_summary_get","parameters":[{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Window Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stats/live-stream":{"get":{"summary":"V2 Stats Live Stream","description":"Server-Sent Events feed for the Live Now tile.\n\nEmits a `snapshot` event with the same shape as\n/api/stats/summary's `live_now` field:\n  { active_count, by_route[], compute{}, as_of }\n\nEvents fire:\n  · immediately on connect (initial state — client doesn't wait)\n  · whenever a telemetry beacon causes a session change (instant)\n  · whenever the 2 s sweeper detects a state change for reasons\n    other than a beacon (stale eviction · GPU memory change ·\n    etc.)\n\nSSE comment-ping every 15 s prevents proxy idle-timeout. The\nEventSource API on the client side auto-reconnects on drop.\n\nProduction deployment note: this works on HF Spaces because we\nemit X-Accel-Buffering: no, which disables Nginx response\nbuffering on the upstream path. Without that header, individual\nevents are batched into 5+ second flushes.","operationId":"v2_stats_live_stream_api_stats_live_stream_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/telemetry/ingest":{"post":{"summary":"V2 Telemetry Ingest","description":"Accept a batch of client-side telemetry events.\n\nExpected payload shape (every key optional, missing → empty):\n{\n  \"session\": {\n    \"id\": \"<browser_session_id>\",\n    \"session_start_at\": \"<iso>\",\n    \"device_type\": \"...\",\n    \"ip_country\": \"...\",\n    ...\n  },\n  \"page_views\":            [{...}, ...],\n  \"clicks\":                [{...}, ...],\n  \"impressions\":           [{...}, ...],\n  \"events\":                [{...}, ...],\n  \"api_calls\":             [{...}, ...],\n  \"inference_telemetry\":   [{...}, ...],\n  \"errors\":                [{...}, ...],\n  \"goals\":                 [{...}, ...],\n  \"experiments_exposures\": [{...}, ...]\n}\n\nReturns per-table insert counts. Malformed rows in a batch are\nsilently dropped — the rest are still inserted, mirroring how\nreal-world telemetry pipelines treat partial failures.","operationId":"v2_telemetry_ingest_api_telemetry_ingest_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/static/telemetry.js":{"get":{"summary":"V2 Telemetry Js","operationId":"v2_telemetry_js_static_telemetry_js_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/keys":{"get":{"tags":["account/keys"],"summary":"List Keys","description":"GET /api/account/keys — paginated list of the caller's keys.","operationId":"list_keys_api_account_keys_get","parameters":[{"name":"env","in":"query","required":false,"schema":{"type":"string","pattern":"^(live|test|all)$","default":"all","title":"Env"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","pattern":"^(active|rotating|disabled|expired|compromised|all)$","default":"all","title":"Status"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Search"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["account/keys"],"summary":"Create Key","description":"POST /api/account/keys — mint a new key with one-time-view payload.","operationId":"create_key_api_account_keys_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/keys/_meta/my-ip":{"get":{"tags":["account/keys"],"summary":"My Ip","description":"GET /api/account/keys/_meta/my-ip — the caller's client IP.\n\nAudit #7: backs the Settings \"+ add my current IP\" helper. Keeps the user's\nIP on our own origin instead of calling a third-party echo service\n(api.ipify.org), which leaked the IP and returned the public egress address\n(wrong for local/proxied callers). Uses the actual TCP peer\n(`request.client.host`) — the non-spoofable source — which is the correct\nvalue to allowlist for same-origin callers. Two path segments after /keys,\nso it never collides with the `/{public_id}` route. Session-gated.","operationId":"my_ip_api_account_keys__meta_my_ip_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/keys/{public_id}":{"get":{"tags":["account/keys"],"summary":"Get Key","description":"GET /api/account/keys/{public_id} — fetch one key.","operationId":"get_key_api_account_keys__public_id__get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["account/keys"],"summary":"Patch Key","description":"PATCH /api/account/keys/{public_id} — edit a subset of fields.","operationId":"patch_key_api_account_keys__public_id__patch","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["account/keys"],"summary":"Delete Key","description":"DELETE /api/account/keys/{public_id} — hard-delete (must be disabled first).","operationId":"delete_key_api_account_keys__public_id__delete","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/rotate":{"post":{"tags":["account/keys"],"summary":"Rotate Key","description":"POST /api/account/keys/{public_id}/rotate — rotate to a new plaintext.\n\nFX-P5-1 (PDA-P5-R1 F01 + PVA-P5-R1 NOTE A): explicitly returns 201\nmatching the mint endpoint. Both produce a one-time-view of a fresh\nplaintext_token; both warrant the same \"created new credential\nrepresentation\" status. Spec §7.1 PDA-R3-F42 pins mint to 201; spec\nis silent on rotate (VER-P5-R1 confirms 200 was also conforming);\nwe pick 201 for client/server consistency and to avoid the\n`r.status === 201` mismatch in the wizard JS.","operationId":"rotate_key_api_account_keys__public_id__rotate_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/usage":{"get":{"tags":["account/keys"],"summary":"Get Key Usage","description":"Phase 8 Wave D: per-minute usage rollup for the detail page.\nReturns oldest-first so the client can render a left-to-right sparkline\nwith no resorting.","operationId":"get_key_usage_api_account_keys__public_id__usage_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"minutes","in":"query","required":false,"schema":{"type":"integer","maximum":1440,"minimum":1,"default":60,"title":"Minutes"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/overview":{"get":{"tags":["account/keys"],"summary":"Get Key Overview","description":"9.N.9 · One-shot overview payload for the bento Overview tab.","operationId":"get_key_overview_api_account_keys__public_id__overview_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Window"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/traffic":{"get":{"tags":["account/keys"],"summary":"Get Key Traffic","description":"9.N.T · One-shot Traffic-tab payload (hero / stats / calendar / clock /\nbytes). tz_off = viewer UTC offset in minutes so buckets render in local\ntime.","operationId":"get_key_traffic_api_account_keys__public_id__traffic_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"granularity","in":"query","required":false,"schema":{"type":"string","default":"hour","title":"Granularity"}},{"name":"tz_off","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Tz Off"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/endpoints":{"get":{"tags":["account/keys"],"summary":"Get Key Endpoints","description":"9.N.T19 · One-shot Endpoints-tab payload: per-endpoint table, method×\nstatus matrix, treemap data, and call-sequence affinity.","operationId":"get_key_endpoints_api_account_keys__public_id__endpoints_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Window"}},{"name":"tz_off","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Tz Off"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/endpoint-profile":{"get":{"tags":["account/keys"],"summary":"Get Key Endpoint Profile","description":"9.N.T27b · Deep per-endpoint profile: callers, constellation,\nminute-level life-story events, fine timeseries, instruments.","operationId":"get_key_endpoint_profile_api_account_keys__public_id__endpoint_profile_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","title":"Path"}},{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Window"}},{"name":"tz_off","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Tz Off"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/routes":{"get":{"tags":["account/keys"],"summary":"Get Key Routes","description":"9.N.T28a · Session-reconstructed journeys: common multi-hop routes\n(with real exemplar replay timing), edge graph, and hub.","operationId":"get_key_routes_api_account_keys__public_id__routes_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"window","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Window"}},{"name":"tz_off","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Tz Off"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/requests":{"get":{"tags":["account/keys"],"summary":"Get Key Requests","description":"Phase 8 Wave D: per-request log for the detail page. Newest first.\n9.N.T: optional since/until time filter so Traffic drill-downs land on a\nspecific bucket/day. 9.N.T(round 3): optional local_hour / local_weekday\n(+tz_off, viewer minutes) so clock 'hour of day' and weekday×hour drills\nreturn the matching requests across the whole window, server-side.","operationId":"get_key_requests_api_account_keys__public_id__requests_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Cursor"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Since"}},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Until"}},{"name":"local_hour","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":23,"minimum":0},{"type":"null"}],"title":"Local Hour"}},{"name":"local_weekday","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":6,"minimum":0},{"type":"null"}],"title":"Local Weekday"}},{"name":"tz_off","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Tz Off"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/audit":{"get":{"tags":["account/keys"],"summary":"Get Key Audit","description":"Phase 8 Wave D: per-key hash-chained audit-log timeline.","operationId":"get_key_audit_api_account_keys__public_id__audit_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/disable":{"post":{"tags":["account/keys"],"summary":"Disable Key","description":"POST /api/account/keys/{public_id}/disable — Phase 8 WI-P8-KEY-DISABLE-VERB.\n\nIdempotent. Moves the key from 'active' to 'disabled'. Disabled keys\ncannot authenticate. Use POST .../enable to reverse. Sudo + CSRF.\n\nWhy a dedicated verb and not PATCH {status:...}: spec §7.1 wants the\nstate machine for keys (active → rotating → disabled → deleted) to\nbe controlled by explicit RPC verbs, not by sneaking a `status`\nfield through the generic PATCH. Makes audit log clean and lets us\nadd per-transition side-effects later (alert emission, webhook firing).","operationId":"disable_key_api_account_keys__public_id__disable_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/keys/{public_id}/enable":{"post":{"tags":["account/keys"],"summary":"Enable Key","description":"POST /api/account/keys/{public_id}/enable — reverse of disable.\nOnly valid for keys currently in 'disabled' status. Sudo + CSRF.","operationId":"enable_key_api_account_keys__public_id__enable_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/key-groups":{"get":{"tags":["account/key-groups"],"summary":"List Groups","operationId":"list_groups_api_account_key_groups_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["account/key-groups"],"summary":"Create Group","operationId":"create_group_api_account_key_groups_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/key-groups/{group_id}":{"get":{"tags":["account/key-groups"],"summary":"Get Group","operationId":"get_group_api_account_key_groups__group_id__get","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["account/key-groups"],"summary":"Patch Group","operationId":"patch_group_api_account_key_groups__group_id__patch","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["account/key-groups"],"summary":"Delete Group","operationId":"delete_group_api_account_key_groups__group_id__delete","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/key-groups/{group_id}/members":{"post":{"tags":["account/key-groups"],"summary":"Add Member","operationId":"add_member_api_account_key_groups__group_id__members_post","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/key-groups/{group_id}/members/{public_id}":{"patch":{"tags":["account/key-groups"],"summary":"Set Member Role","operationId":"set_member_role_api_account_key_groups__group_id__members__public_id__patch","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["account/key-groups"],"summary":"Remove Member","operationId":"remove_member_api_account_key_groups__group_id__members__public_id__delete","parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"integer","title":"Group Id"}},{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/fonts/{filename}":{"get":{"summary":"V2 Serve Font","operationId":"v2_serve_font_fonts__filename__get","parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/sudo":{"get":{"tags":["account/sudo"],"summary":"Sudo State","description":"GET /api/account/sudo — probe sudo state.\n\nSpec §7.6 (lines 2892-2895). CSRF required per PDA-F25 (defends\nagainst cross-origin probe via <img>/<link>).","operationId":"sudo_state_api_account_sudo_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["account/sudo"],"summary":"Sudo Start","description":"POST /api/account/sudo — verify password, mint sudo cookie.\n\nSpec §7.6 (lines 2875-2884).","operationId":"sudo_start_api_account_sudo_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/sudo/revoke":{"post":{"tags":["account/sudo"],"summary":"Sudo Revoke","description":"POST /api/account/sudo/revoke — invalidate active sudo.\n\nSpec §7.6 (lines 2886-2890).","operationId":"sudo_revoke_api_account_sudo_revoke_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/settings":{"get":{"tags":["account/settings"],"summary":"Get Settings","description":"GET /api/account/settings — return the caller's account_settings.","operationId":"get_settings_api_account_settings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"patch":{"tags":["account/settings"],"summary":"Patch Settings","description":"PATCH /api/account/settings — update editable fields. Requires sudo.\n\nPhase 8 Wave C (WI-P8-SUDO-AMPLIFY): if this PATCH RAISES sudo_max_uses\n(the cap on how many mutating requests a sudo session can issue), we\nauto-revoke the current sudo session. Reason: if an attacker compromises\na sudo session, they could amplify its blast radius by PATCHing the cap\nupward, then continuing to mutate. Forcing re-auth on raise neutralises\nthat. Lowering the cap is safe and does not trigger revocation.","operationId":"patch_settings_api_account_settings_patch","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/webhooks":{"get":{"tags":["account/webhooks"],"summary":"List Webhooks Route","description":"List the caller's webhooks.","operationId":"list_webhooks_route_api_account_webhooks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["account/webhooks"],"summary":"Create Webhook Route","description":"Mint a new webhook. The plaintext signing secret is returned ONCE in\nthe response. Save it immediately — APIN cannot show it again.","operationId":"create_webhook_route_api_account_webhooks_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/webhooks/{webhook_id}":{"get":{"tags":["account/webhooks"],"summary":"Get Webhook Route","operationId":"get_webhook_route_api_account_webhooks__webhook_id__get","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["account/webhooks"],"summary":"Patch Webhook Route","description":"Update a subset of editable webhook fields. Sudo + CSRF required.","operationId":"patch_webhook_route_api_account_webhooks__webhook_id__patch","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["account/webhooks"],"summary":"Delete Webhook Route","description":"Hard-delete a webhook. Cascades to delivery rows. Sudo + CSRF.","operationId":"delete_webhook_route_api_account_webhooks__webhook_id__delete","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/webhooks/{webhook_id}/rotate-secret":{"post":{"tags":["account/webhooks"],"summary":"Rotate Webhook Secret Route","description":"Mint a new signing secret. Old secret stays valid for `grace_seconds`\nso receivers can swap in the new secret without dropping in-flight\nevents. Returns the plaintext NEW secret ONCE. Sudo + CSRF.","operationId":"rotate_webhook_secret_route_api_account_webhooks__webhook_id__rotate_secret_post","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/webhooks/{webhook_id}/test":{"post":{"tags":["account/webhooks"],"summary":"Test Webhook Route","description":"Synchronous test-ping. Fires ONE POST and waits up to 10s for the\nreceiver. Returns the attempt outcome (status code, error text, ms).\nSudo + CSRF. State-changing per PDA-R2-F46.","operationId":"test_webhook_route_api_account_webhooks__webhook_id__test_post","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/webhooks/{webhook_id}/deliveries":{"get":{"tags":["account/webhooks"],"summary":"List Deliveries Route","operationId":"list_deliveries_route_api_account_webhooks__webhook_id__deliveries_get","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/alerts":{"get":{"tags":["account/alerts"],"summary":"List Alerts Route","description":"List alerts with filters. Cursor pagination by (updated_at DESC, id DESC).","operationId":"list_alerts_route_api_account_alerts_get","parameters":[{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(info|warn|critical)$"},{"type":"null"}],"title":"Severity"}},{"name":"code","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Code"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Key Id"}},{"name":"only_unread","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Only Unread"}},{"name":"include_dismissed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Dismissed"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/alerts/prefs/registry":{"get":{"tags":["account/alerts"],"summary":"Alert Prefs Registry","description":"Return the catalogue of every alert code, grouped by category, with\nmetadata (severity, default_on, title template). Used by the Settings\nUI to render the toggle list. Doesn't include user values.","operationId":"alert_prefs_registry_api_account_alerts_prefs_registry_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/alerts/prefs":{"get":{"tags":["account/alerts"],"summary":"Alert Prefs Get","description":"Return the user's current alert preference overrides as the JSON\nstructure stored in account_settings.notify_prefs_json.","operationId":"alert_prefs_get_api_account_alerts_prefs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"patch":{"tags":["account/alerts"],"summary":"Alert Prefs Patch","description":"Upsert alert preferences. Body shape:\n    {\"categories\": {\"key_lifecycle\": false, ...},\n     \"codes\":      {\"key.created\": true, ...}}\nUnknown categories/codes are silently dropped (defensive). The merge\nis REPLACE — clients should send the full desired prefs object.","operationId":"alert_prefs_patch_api_account_alerts_prefs_patch","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/alerts/unread-count":{"get":{"tags":["account/alerts"],"summary":"Unread Count Route","description":"For the nav bell badge + the toast detector poll.\n\nPhase 8.H · `?since=<id>` — when the client tells us the highest alert\nid it has already seen, we additionally return:\n  - `new_unread`         (count of unread alerts with id > since)\n  - `new_alerts`         (up to 10 of the newest unread rows, oldest-first\n                          so the toast layer can slide them in in order)\n  - `latest_id`          (the highest id in the user's inbox, including\n                          read+dismissed — so the client can advance its\n                          `since` cursor monotonically and never re-toast)\nWithout `since`, only the global `unread` count is returned (cheap).","operationId":"unread_count_route_api_account_alerts_unread_count_get","parameters":[{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Since"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/alerts/{alert_id}":{"get":{"tags":["account/alerts"],"summary":"Get Alert Route","operationId":"get_alert_route_api_account_alerts__alert_id__get","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["account/alerts"],"summary":"Dismiss Route","description":"Soft-delete: sets dismissed_at. Reversible via /restore.","operationId":"dismiss_route_api_account_alerts__alert_id__delete","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/alerts/{alert_id}/read":{"patch":{"tags":["account/alerts"],"summary":"Mark Read Route","description":"Idempotent. Marking an already-read alert is a no-op.","operationId":"mark_read_route_api_account_alerts__alert_id__read_patch","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/alerts/{alert_id}/restore":{"post":{"tags":["account/alerts"],"summary":"Restore Route","description":"Reverses a prior dismiss.","operationId":"restore_route_api_account_alerts__alert_id__restore_post","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/alerts/{alert_id}/snooze":{"post":{"tags":["account/alerts"],"summary":"Snooze Route","description":"Phase 8 Wave E (WI-P8-ALERTS-SNOOZE): mark an alert as snoozed\nuntil `body.until` (ISO-8601). Until that timestamp the alert is\nexcluded from the unread-count badge and from the default list view.\n\nBody: { until: \"2026-05-27T10:00:00Z\" }  OR  { hours: 24 }","operationId":"snooze_route_api_account_alerts__alert_id__snooze_post","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/summary":{"get":{"tags":["account/usage"],"summary":"Usage Summary","description":"Account-wide KPIs over the requested window, with delta-vs-previous.\n\nReturns:\n  {\n    \"range\": \"24h\", \"window_seconds\": 86400,\n    \"kpis\": {\n      \"requests\":       {\"current\": 1234, \"previous\": 1100, \"delta_pct\": 12.2},\n      \"errors\":         {\"current\": 12,   \"previous\": 8,    \"delta_pct\": 50.0},\n      \"rate_limited\":   {\"current\": 3,    \"previous\": 0,    \"delta_pct\": None},\n      \"quota_blocked\":  {\"current\": 0,    \"previous\": 0,    \"delta_pct\": 0.0},\n      \"bytes_in\":       {\"current\": ..., \"previous\": ..., \"delta_pct\": ...},\n      \"bytes_out\":      {\"current\": ..., \"previous\": ..., \"delta_pct\": ...},\n      \"latency_p50_ms\": {\"current\": 110, \"previous\": 105, \"delta_pct\": 4.8},\n      \"latency_p95_ms\": {\"current\": 320, \"previous\": 290, \"delta_pct\": 10.3},\n      \"latency_p99_ms\": {\"current\": 510, \"previous\": 470, \"delta_pct\": 8.5},\n      \"active_keys\":    {\"current\": 4,   \"previous\": 3,    \"delta_pct\": 33.3},\n      \"error_rate\":     {\"current\": 0.97, \"previous\": 0.72, \"delta_pct\": 34.7},\n    },\n    \"computed_at\": \"2026-...Z\"\n  }\n\nThe previous window has the same length as the current and immediately\nprecedes it (i.e. last 24h vs the 24h before that, not vs yesterday).","operationId":"usage_summary_api_account_usage_summary_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"endpoint","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/timeseries":{"get":{"tags":["account/usage"],"summary":"Usage Timeseries","description":"Bucketed time-series for charting.\n\n`mode` ∈ {total, by_status, by_endpoint, latency, errors, bytes}.\n\nReturns:\n  {\n    \"range\": \"24h\", \"granularity_seconds\": 300,\n    \"mode\": \"by_status\",\n    \"buckets\": [\n      {\"t\": \"2026-05-26 13:00:00\", \"values\": {\"2xx\": 120, \"4xx\": 3, \"5xx\": 1, \"429\": 0}},\n      ...\n    ],\n    \"series_meta\": [\n      {\"key\": \"2xx\", \"label\": \"2xx\", \"color_token\": \"ok\"},\n      {\"key\": \"4xx\", \"label\": \"4xx\", \"color_token\": \"warn\"},\n      ...\n    ]\n  }","operationId":"usage_timeseries_api_account_usage_timeseries_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"granularity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Granularity"}},{"name":"mode","in":"query","required":false,"schema":{"type":"string","default":"total","title":"Mode"}},{"name":"compare","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compare"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"endpoint","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/top":{"get":{"tags":["account/usage"],"summary":"Usage Top","description":"Top-N ranking across `dim`. Returns rows sorted DESC by count.\n\ndim ∈ {keys, endpoints, ips, statuses, error_codes, methods}.\n\nReturns:\n  {\n    \"range\": \"24h\", \"dim\": \"endpoints\", \"limit\": 10,\n    \"items\": [\n      {\"label\": \"/api/predict/full\", \"count\": 980, \"pct\": 79.4,\n       \"extra\": {\"p50_ms\": 120, \"avg_latency_ms\": 135}},\n      ...\n    ],\n    \"total_for_pct\": 1234\n  }","operationId":"usage_top_api_account_usage_top_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"dim","in":"query","required":false,"schema":{"type":"string","default":"keys","title":"Dim"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"endpoint","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/requests":{"get":{"tags":["account/usage"],"summary":"Usage Requests","description":"Paginated raw request log across ALL of the user's keys.\n\n`status` accepts a class shorthand (2xx/3xx/4xx/5xx/429) OR a literal\ncode (e.g. \"404\"). `endpoint` is a path substring match. `method` is\nexact (GET/POST/etc.). `key_id` narrows to one key.\n\n`format=csv` returns text/csv instead of JSON — used by the Export\nbutton on the Usage page (per U5 \"all data and logs, fully detailed\").","operationId":"usage_requests_api_account_usage_requests_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"title":"Cursor"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"method","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"endpoint","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/minute-detail":{"get":{"tags":["account/usage"],"summary":"Usage Minute Detail","description":"Drill-down for one (key_id, minute) cell.\n\nReturns the aggregate row for that minute (from api_key_usage_minute)\nplus the raw requests that landed in it (up to `limit`), filtered the\nsame way as the timeseries. Used by the click-time-series drawer.\n\nminute_ts format: \"YYYY-MM-DD HH:MM:00\" UTC.","operationId":"usage_minute_detail_api_account_usage_minute_detail_get","parameters":[{"name":"minute_ts","in":"query","required":true,"schema":{"type":"string","title":"Minute Ts"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"endpoint","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/latency-drill":{"get":{"tags":["account/usage"],"summary":"Usage Latency Drill","description":"9.I — drill into a clicked latency-histogram bar.","operationId":"usage_latency_drill_api_account_usage_latency_drill_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"min_ms","in":"query","required":true,"schema":{"type":"integer","minimum":0,"title":"Min Ms"}},{"name":"max_ms","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"title":"Max Ms"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/request/{request_id}":{"get":{"tags":["account/usage"],"summary":"Usage Request Detail","description":"9.I — Full request detail card.\n\nReturns one row from `api_key_request_log` (joined with `api_keys` for\nname + env), enriched with client-origin inference (parses UA →\ndetects sandbox / docs / curl / python / node / browser) and a\nredacted-curl reconstruction the user can paste back to reproduce\nthe call.\n\nOwnership check: the row's key_id must belong to the calling user.\nOtherwise return not_found (don't leak existence).","operationId":"usage_request_detail_api_account_usage_request__request_id__get","parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"integer","title":"Request Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/heatmap-calendar":{"get":{"tags":["account/usage"],"summary":"Usage Heatmap Calendar","description":"Returns activity cells for the chosen calendar mode:\n  - week   → 7×24 grid (day_of_week × hour_of_day), last 7 days\n  - month  → 1×N grid (day-of-month, last 30 days)\n  - year   → 1×12 grid (month-of-year, last 365 days)\n  - years  → 1×N grid (year, last 5 years)\nReturns: { mode, cells: [{row, col, count, label?}, ...], rows, cols }","operationId":"usage_heatmap_calendar_api_account_usage_heatmap_calendar_get","parameters":[{"name":"mode","in":"query","required":false,"schema":{"type":"string","default":"week","title":"Mode"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/usage/stream":{"get":{"tags":["account/usage"],"summary":"Usage Stream","description":"Server-Sent Events feed. Streams every request_log row for this\nuser's keys, in real time, as they're recorded by the middleware.\n\nFrame format (per W3C SSE):\n    data: <JSON object>\\n\\n\n\nPlus periodic heartbeats `: heartbeat\\n\\n` (comment lines) every 15s.\n\nNOT wrapped in the standard envelope — this is a streaming endpoint\nwhere each frame is its own JSON object. Clients use EventSource.","operationId":"usage_stream_api_account_usage_stream_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/usage/per-endpoint-detail":{"get":{"tags":["account/usage"],"summary":"Usage Per Endpoint Detail","description":"Returns per-endpoint stats: count, error_rate, p50, p95, p99 plus\na small sparkline-shape (last N buckets of activity).\nUsed by: spark-grid, treemap, boxplot, quadrant.\n\n9.N.6.f · Now accepts status+endpoint filters so a global drill cascades\nto these charts too (treemap/sparkgrid/boxplot/quadrant).","operationId":"usage_per_endpoint_detail_api_account_usage_per_endpoint_detail_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":20,"title":"Limit"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"endpoint","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"}},{"name":"spark_buckets","in":"query","required":false,"schema":{"type":"integer","maximum":60,"minimum":4,"default":20,"title":"Spark Buckets"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/geo":{"get":{"tags":["account/analytics"],"summary":"Analytics Geo","operationId":"analytics_geo_api_account_analytics_geo_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"tier","in":"query","required":false,"schema":{"type":"string","default":"state","title":"Tier"}},{"name":"source","in":"query","required":false,"schema":{"type":"string","default":"requests","title":"Source"}},{"name":"compare","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Compare"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/geo/region":{"get":{"tags":["account/analytics"],"summary":"Analytics Geo Region","operationId":"analytics_geo_region_api_account_analytics_geo_region_get","parameters":[{"name":"cc","in":"query","required":true,"schema":{"type":"string","title":"Cc"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"district","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"District"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"tier","in":"query","required":false,"schema":{"type":"string","default":"state","title":"Tier"}},{"name":"source","in":"query","required":false,"schema":{"type":"string","default":"requests","title":"Source"}},{"name":"compare","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Compare"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/geo/region/requests":{"get":{"tags":["account/analytics"],"summary":"Analytics Geo Region Requests","operationId":"analytics_geo_region_requests_api_account_analytics_geo_region_requests_get","parameters":[{"name":"cc","in":"query","required":true,"schema":{"type":"string","title":"Cc"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"district","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"District"}},{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"tier","in":"query","required":false,"schema":{"type":"string","default":"state","title":"Tier"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/geo/replay":{"get":{"tags":["account/analytics"],"summary":"Analytics Geo Replay","operationId":"analytics_geo_replay_api_account_analytics_geo_replay_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"tier","in":"query","required":false,"schema":{"type":"string","default":"state","title":"Tier"}},{"name":"source","in":"query","required":false,"schema":{"type":"string","default":"requests","title":"Source"}},{"name":"frames","in":"query","required":false,"schema":{"type":"integer","default":120,"title":"Frames"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/field":{"get":{"tags":["account/analytics"],"summary":"Analytics Field","operationId":"analytics_field_api_account_analytics_field_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/field/scans":{"get":{"tags":["account/analytics"],"summary":"Analytics Field Scans","operationId":"analytics_field_scans_api_account_analytics_field_scans_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"crop","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Crop"}},{"name":"disease","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disease"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":400,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/scan/{scan_uid}":{"get":{"tags":["account/analytics"],"summary":"Analytics Scan Detail","operationId":"analytics_scan_detail_api_account_analytics_scan__scan_uid__get","parameters":[{"name":"scan_uid","in":"path","required":true,"schema":{"type":"string","title":"Scan Uid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/scan/{scan_uid}/image":{"get":{"tags":["account/analytics"],"summary":"Analytics Scan Image","operationId":"analytics_scan_image_api_account_analytics_scan__scan_uid__image_get","parameters":[{"name":"scan_uid","in":"path","required":true,"schema":{"type":"string","title":"Scan Uid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/severity":{"get":{"tags":["account/analytics"],"summary":"Analytics Severity","operationId":"analytics_severity_api_account_analytics_severity_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/bloom":{"get":{"tags":["account/analytics"],"summary":"Analytics Bloom","operationId":"analytics_bloom_api_account_analytics_bloom_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"7d","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"buckets","in":"query","required":false,"schema":{"type":"integer","default":28,"title":"Buckets"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/streams":{"get":{"tags":["account/analytics"],"summary":"Analytics Streams","operationId":"analytics_streams_api_account_analytics_streams_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"buckets","in":"query","required":false,"schema":{"type":"integer","default":48,"title":"Buckets"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/clients":{"get":{"tags":["account/analytics"],"summary":"Analytics Clients","operationId":"analytics_clients_api_account_analytics_clients_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"7d","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"buckets","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Buckets"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/confidence":{"get":{"tags":["account/analytics"],"summary":"Analytics Confidence","operationId":"analytics_confidence_api_account_analytics_confidence_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"7d","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"buckets","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Buckets"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/quota":{"get":{"tags":["account/analytics"],"summary":"Analytics Quota","operationId":"analytics_quota_api_account_analytics_quota_get","parameters":[{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/analytics/payloads":{"get":{"tags":["account/analytics"],"summary":"Analytics Payloads","operationId":"analytics_payloads_api_account_analytics_payloads_get","parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"24h","title":"Range"}},{"name":"key_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"}},{"name":"env","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env"}},{"name":"sample","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Sample"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/whoami":{"get":{"tags":["account/admin"],"summary":"Admin Whoami","description":"Report whether the signed-in caller is an administrator.\n\nRequires a valid session (401 otherwise). Returns ONLY the caller's own\nidentity + admin flag — no other user is observable through this route.","operationId":"admin_whoami_api_account_admin_whoami_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/overview":{"get":{"tags":["account/admin"],"summary":"Admin Overview","description":"Org-wide vital signs for the Pulse section. Admin + verified + CSRF.","operationId":"admin_overview_api_account_admin_overview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/list/{kind}":{"get":{"tags":["account/admin"],"summary":"Admin List","description":"Filtered item list for the drill container. kind = requests|keys|scans.","operationId":"admin_list_api_account_admin_list__kind__get","parameters":[{"name":"kind","in":"path","required":true,"schema":{"type":"string","title":"Kind"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/detail/request/{row_id}":{"get":{"tags":["account/admin"],"summary":"Admin Detail Request","operationId":"admin_detail_request_api_account_admin_detail_request__row_id__get","parameters":[{"name":"row_id","in":"path","required":true,"schema":{"type":"integer","title":"Row Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/detail/key/{public_id}":{"get":{"tags":["account/admin"],"summary":"Admin Detail Key","operationId":"admin_detail_key_api_account_admin_detail_key__public_id__get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/detail/scan/{scan_uid}":{"get":{"tags":["account/admin"],"summary":"Admin Detail Scan","operationId":"admin_detail_scan_api_account_admin_detail_scan__scan_uid__get","parameters":[{"name":"scan_uid","in":"path","required":true,"schema":{"type":"string","title":"Scan Uid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/detail/user/{user_id}":{"get":{"tags":["account/admin"],"summary":"Admin Detail User","operationId":"admin_detail_user_api_account_admin_detail_user__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/detail/prediction/{pred_id}":{"get":{"tags":["account/admin"],"summary":"Admin Detail Prediction","operationId":"admin_detail_prediction_api_account_admin_detail_prediction__pred_id__get","parameters":[{"name":"pred_id","in":"path","required":true,"schema":{"type":"string","title":"Pred Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/prediction-image/{pred_id}":{"get":{"tags":["account/admin"],"summary":"Admin Prediction Image","description":"Raw uploaded leaf image bytes for a website inference (admin).","operationId":"admin_prediction_image_api_account_admin_prediction_image__pred_id__get","parameters":[{"name":"pred_id","in":"path","required":true,"schema":{"type":"string","title":"Pred Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/prediction-heatmap/{pred_id}":{"get":{"tags":["account/admin"],"summary":"Admin Prediction Heatmap","description":"Stored Grad-CAM heatmap PNG for a website inference (admin).","operationId":"admin_prediction_heatmap_api_account_admin_prediction_heatmap__pred_id__get","parameters":[{"name":"pred_id","in":"path","required":true,"schema":{"type":"string","title":"Pred Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/scan-region/{scan_uid}":{"get":{"tags":["account/admin"],"summary":"Admin Scan Region","description":"District-highlighted region map (SVG-projected paths) for a scan.","operationId":"admin_scan_region_api_account_admin_scan_region__scan_uid__get","parameters":[{"name":"scan_uid","in":"path","required":true,"schema":{"type":"string","title":"Scan Uid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/scan-image/{scan_uid}":{"get":{"tags":["account/admin"],"summary":"Admin Scan Image","description":"Raw scan image bytes (admin). Not envelope-wrapped — returns the image.","operationId":"admin_scan_image_api_account_admin_scan_image__scan_uid__get","parameters":[{"name":"scan_uid","in":"path","required":true,"schema":{"type":"string","title":"Scan Uid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/metric/{metric}":{"get":{"tags":["account/admin"],"summary":"Admin Metric","description":"Time series + breakdown + headline for one Overview metric. Admin + verified.","operationId":"admin_metric_api_account_admin_metric__metric__get","parameters":[{"name":"metric","in":"path","required":true,"schema":{"type":"string","title":"Metric"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/events":{"get":{"tags":["account/admin"],"summary":"Admin Events","description":"Normalised cross-source event stream for the live feed. Admin + verified.","operationId":"admin_events_api_account_admin_events_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/db/tables":{"get":{"tags":["account/admin"],"summary":"Admin Db Tables","description":"List every table with row + column counts. Admin + verified + CSRF.","operationId":"admin_db_tables_api_account_admin_db_tables_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/db/table":{"get":{"tags":["account/admin"],"summary":"Admin Db Table","description":"Schema + masked, paginated rows for one table. Admin + verified + CSRF.","operationId":"admin_db_table_api_account_admin_db_table_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/traffic":{"get":{"tags":["account/admin"],"summary":"Admin Traffic","operationId":"admin_traffic_api_account_admin_traffic_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/traffic/deck-layout":{"get":{"tags":["account/admin"],"summary":"Admin Deck Layout Get","description":"[STATS DECK F2] Return this admin's saved card order + pins for a dataset.","operationId":"admin_deck_layout_get_api_account_admin_traffic_deck_layout_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["account/admin"],"summary":"Admin Deck Layout Set","description":"[STATS DECK F2] Persist this admin's card order + pins. CSRF via middleware.","operationId":"admin_deck_layout_set_api_account_admin_traffic_deck_layout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/traffic/stream":{"get":{"tags":["account/admin"],"summary":"Admin Traffic Stream","description":"Org-wide live request feed (Server-Sent Events) for the admin Traffic\nsection. Subscribes to the usage bus' BROADCAST channel so it sees every\nrecorded request across all keys/users with no extra DB work.\n\nAuth: require_admin_verified only — the session cookie rides along on the\nEventSource connection. NO CSRF: EventSource can't set request headers, GET\nis read-only and exempt from the central CSRF net (middlewares §846). Each\nframe is its own JSON object (NOT the standard envelope); clients use\nEventSource. Heartbeats every 15s keep proxies from dropping the stream.","operationId":"admin_traffic_stream_api_account_admin_traffic_stream_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/users":{"get":{"tags":["account/admin"],"summary":"Admin Users","operationId":"admin_users_api_account_admin_users_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/users/{user_id}":{"get":{"tags":["account/admin"],"summary":"Admin User Detail","operationId":"admin_user_detail_api_account_admin_users__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/users/{user_id}/role":{"post":{"tags":["account/admin"],"summary":"Admin Set Role","description":"Promote / revoke admin. Sudo + CSRF enforced upstream by middleware;\nrequire_admin_verified here. Blocks any change that would leave zero admins.","operationId":"admin_set_role_api_account_admin_users__user_id__role_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/account/admin/maintenance/backfill-telemetry":{"post":{"tags":["account/admin"],"summary":"Admin Backfill Telemetry","description":"One-time idempotent attribution of historical anonymous telemetry.\nSudo + CSRF enforced upstream by middleware; require_admin_verified here.","operationId":"admin_backfill_telemetry_api_account_admin_maintenance_backfill_telemetry_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/account/admin/users/{user_id}/logout-all":{"post":{"tags":["account/admin"],"summary":"Admin Force Logout","description":"Revoke every active session for the user (force-logout).","operationId":"admin_force_logout_api_account_admin_users__user_id__logout_all_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account/api/settings":{"get":{"summary":"Account Settings Page","operationId":"account_settings_page_account_api_settings_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/api/quickstart":{"get":{"summary":"Account Quickstart Page","operationId":"account_quickstart_page_account_api_quickstart_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/api/sandbox":{"get":{"summary":"Account Sandbox Page","operationId":"account_sandbox_page_account_api_sandbox_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/api/alerts":{"get":{"summary":"Account Alerts Page","operationId":"account_alerts_page_account_api_alerts_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/api/webhooks":{"get":{"summary":"Account Webhooks Page","operationId":"account_webhooks_page_account_api_webhooks_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/api/keys/{public_id}":{"get":{"summary":"Account Key Detail Page","operationId":"account_key_detail_page_account_api_keys__public_id__get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account/api/usage":{"get":{"summary":"Account Usage Page","operationId":"account_usage_page_account_api_usage_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/api/admin":{"get":{"summary":"Account Admin Page","operationId":"account_admin_page_account_api_admin_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/account/api/keys":{"get":{"summary":"Account Keys Page","operationId":"account_keys_page_account_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/static/{filename}":{"get":{"summary":"V2 Static Js","operationId":"v2_static_js_static__filename__get","parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account/api":{"get":{"summary":"Account Root","operationId":"account_root_account_api_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account/api/dashboard":{"get":{"summary":"Account Dashboard Page","operationId":"account_dashboard_page_account_api_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/account/audit/recent":{"get":{"summary":"Account Audit Recent","operationId":"account_audit_recent_api_account_audit_recent_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AdminVerifyPayload":{"properties":{"code":{"type":"string","maxLength":8,"minLength":4,"title":"Code"},"remember":{"type":"boolean","title":"Remember","default":false}},"type":"object","required":["code"],"title":"AdminVerifyPayload"},"Body_predict_apin_predict_apin_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_predict_apin_predict_apin_post"},"Body_predict_legacy_predict_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_predict_legacy_predict_post"},"Body_v1_predict_batch_api_predict_batch_post":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files"}},"type":"object","required":["files"],"title":"Body_v1_predict_batch_api_predict_batch_post"},"Body_v1_predict_full_api_predict_full_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_v1_predict_full_api_predict_full_post"},"Body_v1_predict_quick_api_predict_quick_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_v1_predict_quick_api_predict_quick_post"},"Body_v1_scan_api_scan_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"latitude":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Longitude"},"altitude_m":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Altitude M"},"heading_deg":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Heading Deg"},"accuracy_m":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accuracy M"},"captured_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Captured At"},"flight_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flight Id"},"persist_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persist Image"},"geo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geo"}},"type":"object","required":["file"],"title":"Body_v1_scan_api_scan_post"},"Body_v1_scan_batch_api_scan_batch_post":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files"},"manifest":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manifest"},"flight_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flight Id"},"persist_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persist Image"}},"type":"object","required":["files"],"title":"Body_v1_scan_batch_api_scan_batch_post"},"Body_v2_predict_full_predict_full_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_v2_predict_full_predict_full_post"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LoginPayload":{"properties":{"handle":{"type":"string","maxLength":255,"minLength":1,"title":"Handle"},"password":{"type":"string","title":"Password"}},"type":"object","required":["handle","password"],"title":"LoginPayload"},"SignupPayload":{"properties":{"username":{"type":"string","maxLength":32,"minLength":3,"title":"Username"},"display_name":{"type":"string","maxLength":80,"minLength":2,"title":"Display Name"},"email":{"type":"string","maxLength":255,"minLength":3,"title":"Email"},"password":{"type":"string","title":"Password"},"mobile":{"type":"string","title":"Mobile"}},"type":"object","required":["username","display_name","email","password","mobile"],"title":"SignupPayload"},"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"}}}}