{"openapi":"3.1.0","info":{"title":"soeru API","description":"AIパーソナライズ明細書メッセージ自動生成SaaS","version":"0.1.0"},"paths":{"/api/auth/check-registration":{"post":{"tags":["Auth"],"summary":"Check Registration","description":"Check if new registrations are currently open.\n\nReturns whether signup is available or if users should join the waitlist.","operationId":"check_registration_api_auth_check_registration_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/auth/waitlist":{"post":{"tags":["Auth"],"summary":"Join Waitlist","description":"Add an email to the waitlist.","operationId":"join_waitlist_api_auth_waitlist_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/signup":{"post":{"tags":["Auth"],"summary":"Signup","description":"Create a new user via Supabase Admin API (email auto-confirmed).\n\nThis bypasses Supabase's built-in email verification which is unreliable\non the free tier. Users can log in immediately after signup.\nIncludes registration cap check — redirects to waitlist when limits exceeded.","operationId":"signup_api_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"Get Me","description":"Return current authenticated user info + profile (TOS status).","operationId":"get_me_api_auth_me_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/accept-terms":{"post":{"tags":["Auth"],"summary":"Accept Terms","description":"Record the user's acceptance of terms of service.","operationId":"accept_terms_api_auth_accept_terms_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptTermsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/request-password-reset":{"post":{"tags":["Auth"],"summary":"Request Password Reset","description":"Send a password reset email.\n\nUses Resend if configured, falls back to Supabase built-in email.","operationId":"request_password_reset_api_auth_request_password_reset_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/update-password":{"post":{"tags":["Auth"],"summary":"Update Password","description":"Update the currently-authenticated user's password.\n\nEnforces the same complexity policy as /signup. Required for Amazon\nSP-API § Credentials Management 1.4 compliance: all password changes\n(not just initial registration) must go through the same validation.","operationId":"update_password_api_auth_update_password_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/admin/confirm-all-users":{"post":{"tags":["Auth"],"summary":"Admin Confirm All Users","description":"Confirm all unverified users (admin only).\n\nOnly accessible by admin emails. Finds users with unconfirmed emails\nand confirms them via the admin API.","operationId":"admin_confirm_all_users_api_auth_admin_confirm_all_users_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/admin/app-settings":{"get":{"tags":["Auth"],"summary":"Get App Settings","description":"Get all app settings (admin only).","operationId":"get_app_settings_api_auth_admin_app_settings_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Auth"],"summary":"Update App Setting","description":"Update an app setting (admin only).","operationId":"update_app_setting_api_auth_admin_app_settings_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSettingRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/admin/waitlist":{"get":{"tags":["Auth"],"summary":"Get Waitlist","description":"Get waitlist entries (admin only).","operationId":"get_waitlist_api_auth_admin_waitlist_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/resend-verification":{"post":{"tags":["Auth"],"summary":"Resend Verification","description":"Resend email verification. Uses Supabase resend API.\n\nRate-limited to prevent email-send abuse (Supabase charges for volume\nand attackers can pivot this into an email-bombing DoS on arbitrary\naddresses if left open).","operationId":"resend_verification_api_auth_resend_verification_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/email-hook":{"post":{"tags":["Supabase Hook"],"summary":"Email Hook","description":"Supabase Auth Send Email Hook receiver.\n\nReturns:\n  - `{}`                           → Supabase will suppress its own send\n  - `{\"email_override\": false}`    → Supabase will proceed with its\n                                      default English email (fallback)\n  - 401                            → signature check failed","operationId":"email_hook_api_auth_email_hook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/shops":{"post":{"tags":["Shops"],"summary":"Create Shop","description":"Create a new shop for the current user.","operationId":"create_shop_api_shops_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShopRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Shops"],"summary":"List Shops","description":"List all shops owned by the current user.\n\n2026-05-22 速度①: sync handler (def) にして FastAPI の threadpool で実行させる。\n同期 Supabase 呼び出しがイベントループを塞がず、並列リクエストが直列化しない。","operationId":"list_shops_api_shops_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shops/{shop_id}":{"patch":{"tags":["Shops"],"summary":"Update Shop","description":"Update shop info.","operationId":"update_shop_api_shops__shop_id__patch","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateShopRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Shops"],"summary":"Delete Shop","description":"Delete a shop (cascades to all dependent data).","operationId":"delete_shop_api_shops__shop_id__delete","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orders":{"get":{"tags":["Orders"],"summary":"Get Orders","description":"Fetch orders from the shop's EC platform via the appropriate adapter.\n\nRate limit: 20 requests per minute per user.","operationId":"get_orders_api_orders_get","parameters":[{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date YYYY-MM-DD","title":"Date From"},"description":"Start date YYYY-MM-DD"},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date YYYY-MM-DD","title":"Date To"},"description":"End date YYYY-MM-DD"},{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Single date YYYY-MM-DD (legacy)","title":"Date"},"description":"Single date YYYY-MM-DD (legacy)"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orders/message-status":{"post":{"tags":["Orders"],"summary":"Get Message Status","description":"選択注文のメッセージ状況を軽量に返す (ライブ取得なし, 2026-06-23 B)。\n\nAI が MCP の save_message でメッセージを書き戻したら、出荷キューが自動で表示\n更新するためのポーリング用。message_history だけを引くので速い。\nReturns: {\"messages\": {order_id: {message_status, message_id?, message_text?,\n          message_confirmed_at?, pdf_generated?}}}\n\n2026-07-01: 認証を optional 化。出荷キューは本 endpoint を 6 秒間隔で\nポーリングするため、セッション切れのタブが Authorization ヘッダ無しで叩き\n続けると、required 認証依存だと FastAPI が 422 を無限に量産してログを汚す\n(実害はないが本番ログが埋まる)。未認証/無効トークンは 422 を出さず空\n{\"messages\": {}} を返して黙らせる。データは一切返さないので情報漏れは無い。\n\n2026-07-02 hardening:\n- `request: Request` を明示: get_current_user の A17 stack-walk IP throttle\n  (middleware/auth.py) がフレームから Request を見つけて不正トークン連打を\n  レート制限できるようにする (無いと throttle が silent skip になる)。\n- 空を返すのは「想定内の認証失敗 (400/401/403/429)」のみに限定。DB 障害など\n  それ以外の例外は silent fallback にせず logger.warning + re-raise で表面化\n  させる ([[feedback_silent_fallback_visibility]])。","operationId":"get_message_status_api_orders_message_status_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Shop-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageStatusRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orders/test-connection":{"post":{"tags":["Orders"],"summary":"Test Connection","description":"Test platform API connection with provided credentials.","operationId":"test_connection_api_orders_test_connection_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orders/sync-history":{"post":{"tags":["Orders"],"summary":"Sync Order History","description":"Sync historical orders to build order_history table.\n\nFetches all orders from the past N months and saves them to the\norder_history table for accurate repeat-customer counting.\nUses platform-specific maximum periods when months_back is 0 or omitted.","operationId":"sync_order_history_api_orders_sync_history_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/SyncHistoryRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orders/resync-now":{"post":{"tags":["Orders"],"summary":"Resync Now","description":"全期間 再同期をバックグラウンドで開始する (2026-05-31 項目1b).\n\n/sync-history は同期完了まで HTTP を握り続けるため、楽天 24ヶ月フル再同期の\nように重い処理だと途中でクライアント / プロキシ側が切れて中断する恐れがある。\nこちらは fire_order_history_resync で background task として走らせ、即座に\nreturn する。完了 (または一部失敗) は右上のベルで通知される。\n\n内部で credential 検証 / フル再同期 / 穴の自己修復 / 完了通知まで行うため、\nこのエンドポイントは task を起動するだけ。","operationId":"resync_now_api_orders_resync_now_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orders/sync-limits":{"get":{"tags":["Orders"],"summary":"Get Sync Limits","description":"Return platform-specific sync limits for the current shop.","operationId":"get_sync_limits_api_orders_sync_limits_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orders/history-stats":{"get":{"tags":["Orders"],"summary":"Get History Stats","description":"Get statistics about the order_history table for this shop.","operationId":"get_history_stats_api_orders_history_stats_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orders/import-csv":{"post":{"tags":["Orders"],"summary":"Import Csv Orders","description":"Import orders from a CSV/TSV file (Amazon, 楽天, Yahoo, etc.).","operationId":"import_csv_orders_api_orders_import_csv_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_csv_orders_api_orders_import_csv_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/generate":{"post":{"tags":["Messages"],"summary":"Generate Message","description":"Generate a personalized message for an order.\n\nSame-day restoration: returns cached message if already generated today.\nRate limit: 30 requests per minute per user.\n\nWave 4 (2026-05-05): mode='reflective' で予約 path に分岐.","operationId":"generate_message_api_messages_generate_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/generate/stream":{"post":{"tags":["Messages"],"summary":"Generate Message Stream","description":"単発メッセージ生成の SSE ストリーミング版 (体感高速化).\n\n/generate と同じ依存 (auth + check_usage_limit でプランキャップを enforce) を持ち、\n生成・後処理・課金は完全に同じ経路を通る (use_resonance 判定 → per-shop +\nglobal semaphore → wait_for(45) → basic fallback → _finalize_generation).\n違いは Writer の token を SSE delta で逐次返すことだけ. 最終的に post-process 済みの\nmessage を done イベントで返すので、フロントは delta をプレビュー表示しつつ done で\n最終差し替えする (delta は raw writer の途中経過にすぎない).\n\nSSE events (各行 ``data: <json>\\n\\n``):\n  {\"type\":\"status\",\"stage\":\"generating\"}   生成開始\n  {\"type\":\"delta\",\"text\":\"...\"}            Writer token (プレビュー、途中経過)\n  {\"type\":\"done\",\"result\":{...}}           完了. result は /generate と同形の JSON\n  {\"type\":\"error\",\"detail\":\"...\"}          失敗 (classify_api_error の user_message)\n\n課金/メータリングは _finalize_generation を「生成成功時のみ」呼ぶ — エラー時は\n増分しない (/generate と同じ). reflective mode は非対応で instant 固定\n(mode フィールドは drop). same-day cache 既出力時は即 done で返す.","operationId":"generate_message_stream_api_messages_generate_stream_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/generate-batch-async":{"post":{"tags":["Messages"],"summary":"Generate Batch Async","description":"バルク生成の背景ジョブ化 (2026-06-11, migration 107)。\n\n旧: 4 件ずつの同期チャンクがフロント timeout (60s) / プロキシ (~100s) と競争し、\n10 通で必ずタイムアウト → 自動リカバリが処理中の注文を再生成 (二重課金の温床)。\n新: 即座に job_id を返し、生成は spawn_background_task でサーバー側続行。\nフロントは /generation-jobs/{id} をポーリング。HTTP が長持ちしない =\nタイムアウト概念ごと消える。離脱安全。\n\n- per-shop 実行中ガード: 直近 10 分以内に更新された running ジョブがあれば\n  それを返す (resumed=true) — 二重発火を構造的に防止\n- generation_jobs テーブル未適用環境では 503 → フロントは従来チャンクへ fallback","operationId":"generate_batch_async_api_messages_generate_batch_async_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchGenerateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/generation-jobs/{job_id}":{"get":{"tags":["Messages"],"summary":"Get Generation Job","description":"背景生成ジョブの進捗 (2026-06-11)。shop スコープで取得。","operationId":"get_generation_job_api_messages_generation_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/generate-batch":{"post":{"tags":["Messages"],"summary":"Generate Batch","description":"Generate messages for multiple orders.\n\nSame-day restoration: If a message was already generated today for the\nsame order, the existing message is returned from DB without calling\nClaude API. This prevents accidental double-generation (e.g. browser\nclosed mid-session) from consuming the user's quota or incurring API cost.\n\nRate limit: 10 batch requests per minute per user.","operationId":"generate_batch_api_messages_generate_batch_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchGenerateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/generate-batch/retry-failed":{"post":{"tags":["Messages"],"summary":"Generate Batch Retry Failed","description":"B-3 (2026-04-27): フロントが「失敗した N 件を再生成」ボタンから叩く\nエンドポイント。\n\n動作は ``/generate-batch`` と同等だが、独立した rate-limit bucket を\n持つので「初回バッチ全体」と「リトライ」がお互いの quota を食い合わない。\nユーザーが連打しても 5 件チャンク + per-order retry の安全装置が\n効くので、Supabase / Anthropic に対する追加負荷は限定的。\n\n冪等性: ``/generate-batch`` 同様に同日キャッシュ (`find_today_messages`)\nがあるので、初回バッチで成功した order_id を間違って渡してしまっても\nキャッシュから restored として返り、API/課金は二度走らない。","operationId":"generate_batch_retry_failed_api_messages_generate_batch_retry_failed_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchGenerateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/confirm":{"post":{"tags":["Messages"],"summary":"Confirm Message","description":"店主が明細書メッセージを『確認OK』する。\n\n明細書UX再設計 (2026-06-22): 出荷キューで ②生成済み未確認 → ③確認済み に進める。\n未確認のときのみ confirmed_at をセット (初回確認時刻を保持)。shop スコープ厳守。","operationId":"confirm_message_api_messages_confirm_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/feedback":{"patch":{"tags":["Messages"],"summary":"Set Feedback","description":"Set Good/Bad feedback on a message.\n\n- 'good': saves message as positive voice sample for learning\n- 'bad': marks as bad (avoids similar patterns), optionally with a reason\n- null: removes feedback","operationId":"set_feedback_api_messages_feedback_patch","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/routers__messages__FeedbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/edit":{"patch":{"tags":["Messages"],"summary":"Edit Message","description":"Manually edit a message.\n\nAlso auto-collects the edited text as a Voice DNA sample,\nlearns from the diff between original and edited versions,\nand triggers auto Voice DNA reanalysis when enough new samples accumulate.","operationId":"edit_message_api_messages_edit_patch","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/history":{"get":{"tags":["Messages"],"summary":"Get History","description":"Get message history for the shop (supports both list and paginated response).\n\nQuery params:\n    search: customer name partial match\n    date_from: YYYY-MM-DD start date (JST)\n    date_to: YYYY-MM-DD end date (JST, inclusive)","operationId":"get_history_api_messages_history_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date From"}},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date To"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/brand-learn":{"post":{"tags":["Messages"],"summary":"Brand Learn","description":"Trigger brand profile learning from shop URLs.","operationId":"brand_learn_api_messages_brand_learn_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandLearnRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/style-axes":{"post":{"tags":["Messages"],"summary":"Save Style Axes","description":"Save user-adjusted style axes from onboarding warm start.","operationId":"save_style_axes_api_messages_style_axes_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StyleAxesUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/customer-history/{customer_email}":{"get":{"tags":["Messages"],"summary":"Get Customer Message History","description":"Get past message history for a customer.\n\nReturns recent messages sent to this customer, allowing shop owners\nto see what was previously communicated before generating new messages.\nThis supports the \"shared memory\" concept — shop owners and AI\ncollaborating with full context of the relationship.","operationId":"get_customer_message_history_api_messages_customer_history__customer_email__get","parameters":[{"name":"customer_email","in":"path","required":true,"schema":{"type":"string","title":"Customer Email"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/customer-context/{customer_email}":{"get":{"tags":["Messages"],"summary":"Get Customer Context","description":"お客様カルテ + 過去メッセージを 1 本で返す (明細書作成のサイドパネル用).\n\n2026-05-24: 生成メッセージの良し悪しを「お客様の文脈を見ながら」判断・編集できる\nサイドパネルのためのエンドポイント。get_customer_card (注文回数/最終注文/累計/\n平均間隔/購入履歴) と過去メッセージ(feedback付き)を 1 リクエストで返す。\n\nカルテは「今回の注文も含めた通算」を見せたいので exclude_order_id は使わず\n全注文で集計する (除外すると 2回目なのに『1回』『累計が今回分だけ少ない』等の\n誤表示になる。2026-05-24 sho 指摘で修正)。exclude_order_id 引数は後方互換で残置。","operationId":"get_customer_context_api_messages_customer_context__customer_email__get","parameters":[{"name":"customer_email","in":"path","required":true,"schema":{"type":"string","title":"Customer Email"}},{"name":"exclude_order_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exclude Order Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/pending":{"get":{"tags":["Messages"],"summary":"List Pending Reflective","description":"予約中の reflective ジョブ一覧 (queued / submitted / in_progress).\n\n/dashboard/messages/pending ページから呼ばれる. shop_id 単位で絞り、\n各 row に cancellable (3 分窓内かつ queued) を計算済で返す.","operationId":"list_pending_reflective_api_messages_pending_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/pending/{job_id}/cancel":{"post":{"tags":["Messages"],"summary":"Cancel Pending Reflective","description":"3 分以内に呼ばれた場合のみ status='cancelled' に. 課金ゼロ.\n\n3 分経過後 / 別 shop の job / 既に submit 済 → 409.","operationId":"cancel_pending_reflective_api_messages_pending__job_id__cancel_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"integer","title":"Job Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/reflective-completed":{"get":{"tags":["Messages"],"summary":"List Reflective Completed Pending Pdf","description":"Wave 4 (2026-05-06): じっくり予約で完成 + PDF 未出力のメッセージ一覧.\n\n/dashboard/orders 上部の banner と 1 クリック PDF 出力 flow から使う.\n- reflected_at 以降 24h 以内に絞る (古いものは履歴ページで対応)\n- llm_batch_jobs.caller='reflective_message' AND reflected_at IS NOT NULL\n- 対応する message_history を join して message_text / message_id / pdf_generated を返す\n- pdf_generated=true は除外 (既に PDF 化済 → banner に出さない)\n\n返却形:\n    {\n      \"items\": [\n        {\n          \"job_id\": int,\n          \"message_id\": str,\n          \"order_id\": str,\n          \"customer_name\": str,\n          \"customer_email\": str,\n          \"message_text\": str,\n          \"message_text_preview\": str (200 chars),\n          \"completed_at\": iso,\n        }, ...\n      ],\n      \"count\": int\n    }","operationId":"list_reflective_completed_pending_pdf_api_messages_reflective_completed_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/reflective-completed/{message_id}/dismiss":{"post":{"tags":["Messages"],"summary":"Dismiss Reflective Completed","description":"2026-05-12: じっくり予約完成 banner から「不要」と消す.\n\nPDF 出力せずに banner から個別 dismiss できる. message_history 本体は残るので\n履歴ページからは見える (= 文章を消しているわけではない).\n\nBackward compat: 同 message_id を 2 回以上 dismiss しても idempotent (timestamp 上書き).\n\nArgs:\n    message_id: message_history.id (UUID).\n\nReturns:\n    {\"ok\": true, \"message_id\": str, \"dismissed_at\": iso}\n\nRaises:\n    404: message_history が見つからない\n    403: 他 shop の所有","operationId":"dismiss_reflective_completed_api_messages_reflective_completed__message_id__dismiss_post","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/compare-engines":{"post":{"tags":["Engine Compare (Admin)"],"summary":"Compare Engines","description":"1 注文に対して N engine を並列実行し結果を保存。","operationId":"compare_engines_api_messages_admin_compare_engines_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareEnginesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/select-comparison-winner":{"post":{"tags":["Engine Compare (Admin)"],"summary":"Select Comparison Winner","description":"sho が選んだ engine の出力を message_history に反映。","operationId":"select_comparison_winner_api_messages_admin_select_comparison_winner_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectWinnerRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/engine-comparisons":{"get":{"tags":["Engine Compare (Admin)"],"summary":"List Engine Comparisons","description":"過去の比較ログ一覧 (最新順)。","operationId":"list_engine_comparisons_api_messages_admin_engine_comparisons_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/compare-engines/recent-orders":{"get":{"tags":["Engine Compare (Admin)"],"summary":"List Recent Orders For Compare","description":"エンジン比較 picker 用 — 指定 shop の直近 N 件の注文サマリ。\n\ncustomer_email が `***` (匿名化済) の row も含める — 匿名化された注文でも\n比較対象として有効 (engine が customer_id_hash 経由で履歴を引ける)。","operationId":"list_recent_orders_for_compare_api_messages_admin_compare_engines_recent_orders_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"type":"string","default":"","title":"Shop Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/acceptance-stats":{"get":{"tags":["Acceptance Stats (Admin)"],"summary":"Acceptance Stats","description":"受容率集計を返す。shop_id 省略時は全店、days は集計期間。","operationId":"acceptance_stats_api_messages_admin_acceptance_stats_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Shop Id"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":90,"title":"Days"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Acceptance Stats Api Messages Admin Acceptance Stats Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/pii-recovery/preview":{"post":{"tags":["PII Recovery (Admin)"],"summary":"Preview Orphans","description":"救出対象の orphan 数を shop 別に集計。実 fetch なしの dry view。","operationId":"preview_orphans_api_messages_admin_pii_recovery_preview_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/pii-recovery/execute":{"post":{"tags":["PII Recovery (Admin)"],"summary":"Execute Recovery","description":"Live customer info を再取得し、orphan rows の hash を populate (platform 別に dispatch)。","operationId":"execute_recovery_api_messages_admin_pii_recovery_execute_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/embeddings/preview":{"post":{"tags":["Embeddings (Admin)"],"summary":"Preview Backfill","description":"対象件数 + 概算コスト (実 fetch なし).","operationId":"preview_backfill_api_messages_admin_embeddings_preview_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackfillRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/embeddings/backfill":{"post":{"tags":["Embeddings (Admin)"],"summary":"Execute Backfill","description":"Voyage-3 API で全 entries の embedding を計算して DB に保存.","operationId":"execute_backfill_api_messages_admin_embeddings_backfill_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackfillRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/brand-memory/preview-groups":{"post":{"tags":["Brand Memory (Admin)"],"summary":"Preview Groups","description":"Group 検出を dry_run で. 提案だけ返す.","operationId":"preview_groups_api_messages_admin_brand_memory_preview_groups_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandMemoryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/brand-memory/detect-groups":{"post":{"tags":["Brand Memory (Admin)"],"summary":"Detect Groups Endpoint","description":"Group 検出を実行 (DB 書き込み).","operationId":"detect_groups_endpoint_api_messages_admin_brand_memory_detect_groups_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandMemoryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/brand-memory/preview-cross-links":{"post":{"tags":["Brand Memory (Admin)"],"summary":"Preview Cross Links","description":"Cross-link 抽出を dry_run で. links 提案 + cost 見積もりを返す.\n\nrequire: brand_knowledge / product_catalog に embedding が必要 (Phase 2 backfill 済).","operationId":"preview_cross_links_api_messages_admin_brand_memory_preview_cross_links_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrossLinkRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/brand-memory/extract-cross-links":{"post":{"tags":["Brand Memory (Admin)"],"summary":"Extract Cross Links Endpoint","description":"Cross-link 抽出を実行 (DB 書き込み + 双方向 link 設定).","operationId":"extract_cross_links_endpoint_api_messages_admin_brand_memory_extract_cross_links_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrossLinkRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/brand-memory/rebuild-shop":{"post":{"tags":["Brand Memory (Admin)"],"summary":"Rebuild Shop","description":"Brand Memory 全パイプライン (embedding → cross-link → groups → digests) を\n1 回のリクエストで実行.\n\nPhase 5 brand_memory_worker.rebuild_shop_memory() を呼び出す。\n(voice_outline 生成は V-P4 2026-06-26 で撤去 — 声更新は BYO-AI のみ・cost0。)","operationId":"rebuild_shop_api_messages_admin_brand_memory_rebuild_shop_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FullRebuildRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/observability/total-cost":{"get":{"tags":["Observability (Admin)"],"summary":"Total Cost","description":"今日と昨日の LLM トータル cost (¥) + 前日比.","operationId":"total_cost_api_messages_admin_observability_total_cost_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Total Cost Api Messages Admin Observability Total Cost Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/observability/shop-cost-ranking":{"get":{"tags":["Observability (Admin)"],"summary":"Shop Cost Ranking","description":"当月 cost 上位 shop. 各 shop の plan + ARPU 比率も返す.","operationId":"shop_cost_ranking_api_messages_admin_observability_shop_cost_ranking_get","parameters":[{"name":"top","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Top"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Shop Cost Ranking Api Messages Admin Observability Shop Cost Ranking Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/observability/engine-health":{"get":{"tags":["Observability (Admin)"],"summary":"Engine Health","description":"直近 200 件の cache_hit_rate / 平均 token / fallback 率 / cost 分布.","operationId":"engine_health_api_messages_admin_observability_engine_health_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Engine Health Api Messages Admin Observability Engine Health Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/observability/task-heatmap":{"get":{"tags":["Observability (Admin)"],"summary":"Task Heatmap","description":"過去 24h の (shop, task, hour) 集計. heatmap 描画用 raw 値.","operationId":"task_heatmap_api_messages_admin_observability_task_heatmap_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Task Heatmap Api Messages Admin Observability Task Heatmap Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/observability/llm-call-counters":{"get":{"tags":["Observability (Admin)"],"summary":"Llm Call Counters","description":"現在 hour bucket の per-shop LLM call counter (Redis から読み出し).\n\n閾値超過予兆を sho が朝確認するための raw 値。観測のみ・操作なし。","operationId":"llm_call_counters_api_messages_admin_observability_llm_call_counters_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Llm Call Counters Api Messages Admin Observability Llm Call Counters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/observability/sentry-summary":{"get":{"tags":["Observability (Admin)"],"summary":"Sentry Summary","description":"Sentry 直接連携は MCP / Cowork 側で。ここは「Sentry を見るリンク」を返す.\n\nCowork で sho が Sentry MCP を connect すれば Claude が直接 issue を\n取れるので、この endpoint は誘導文字列のみ返す軽量実装。\nSentry organization slug は env var SENTRY_ORG_SLUG / SENTRY_PROJECT_SLUG。","operationId":"sentry_summary_api_messages_admin_observability_sentry_summary_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Sentry Summary Api Messages Admin Observability Sentry Summary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/cost-management/inventory":{"get":{"tags":["Cost Management (Admin)"],"summary":"List Inventory","description":"全 API 発火点 + 各 plan の現在 cap + 当月サマリを返す.\n\nレスポンス構造:\n  {\n    summary: {当月コスト/revenue/margin},\n    grouped: {manual / per_message / auto / cron},\n    per_message_by_engine: {v3 / v2 / v1 / shared} ← engine 別の grouping\n    quota_groups: [{quota_key + 紐付き経路}],\n  }","operationId":"list_inventory_api_messages_admin_cost_management_inventory_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Inventory Api Messages Admin Cost Management Inventory Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/cost-management/quota-keys":{"get":{"tags":["Cost Management (Admin)"],"summary":"List Quota Keys","description":"quota キー一覧 + 各 quota の現在 cap (Phase 2: DB override 込み).\n\nPATCH /quota/{plan}/{operation} で各 cell を編集可能。","operationId":"list_quota_keys_api_messages_admin_cost_management_quota_keys_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Quota Keys Api Messages Admin Cost Management Quota Keys Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/cost-management/quota/{plan}/{operation}":{"patch":{"tags":["Cost Management (Admin)"],"summary":"Update Quota Override","description":"plan × operation の月間 cap を DB override で上書き.\n\nflow:\n  1. validate (plan / operation / monthly_cap range / 巨大値 confirm)\n  2. 旧値を取得 (audit log の old_cap 用)\n  3. quota_overrides を UPSERT\n  4. quota_override_log に audit 行を INSERT\n  5. invalidate_cap_cache() で自 process の cache をパージ\n     (他 instance は最大 60s 遅延で自然反映)","operationId":"update_quota_override_api_messages_admin_cost_management_quota__plan___operation__patch","parameters":[{"name":"plan","in":"path","required":true,"schema":{"type":"string","title":"Plan"}},{"name":"operation","in":"path","required":true,"schema":{"type":"string","title":"Operation"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapPatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Quota Override Api Messages Admin Cost Management Quota  Plan   Operation  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/cost-management/quota/audit-log":{"get":{"tags":["Cost Management (Admin)"],"summary":"Get Audit Log","description":"quota_override_log の最新 N 件を返す.\n\nUI の「変更履歴」セクション用。set_by uuid → email を 1 round-trip で\n引いて表示用に同梱。","operationId":"get_audit_log_api_messages_admin_cost_management_quota_audit_log_get","parameters":[{"name":"plan","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan"}},{"name":"operation","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Audit Log Api Messages Admin Cost Management Quota Audit Log Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/cost-management/prelaunch-mode":{"get":{"tags":["Cost Management (Admin)"],"summary":"Get Prelaunch Mode","description":"ローンチ前低コストモードの現在状態を返す (admin-only).","operationId":"get_prelaunch_mode_api_messages_admin_cost_management_prelaunch_mode_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Prelaunch Mode Api Messages Admin Cost Management Prelaunch Mode Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Cost Management (Admin)"],"summary":"Set Prelaunch Mode","description":"ローンチ前低コストモードを ON/OFF する (admin-only, 再デプロイ不要).\n\nON: cache keepalive / 異常検知 digest / ブランドクローラ の定期発火を停止し、\n    日々の自動コストをほぼゼロにする. 注文同期など実害のある低コスト job は対象外.\nOFF: 次の tick から各 job が再開する.","operationId":"set_prelaunch_mode_api_messages_admin_cost_management_prelaunch_mode_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrelaunchModeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Prelaunch Mode Api Messages Admin Cost Management Prelaunch Mode Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/cost-observability/summary":{"get":{"tags":["Cost Observability (Admin)"],"summary":"Get Cost Summary","description":"当月 全 shop 合計 cost + alert 件数.","operationId":"get_cost_summary_api_messages_admin_cost_observability_summary_get","parameters":[{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"YYYY-MM, default 今月","title":"Month"},"description":"YYYY-MM, default 今月"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Cost Summary Api Messages Admin Cost Observability Summary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/cost-observability/shops":{"get":{"tags":["Cost Observability (Admin)"],"summary":"List Shops By Cost","description":"当月 cost 上位 shop リスト (revenue / margin% 込み).","operationId":"list_shops_by_cost_api_messages_admin_cost_observability_shops_get","parameters":[{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Month"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":20,"title":"Limit"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"cost_desc / margin_asc","default":"cost_desc","title":"Sort"},"description":"cost_desc / margin_asc"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Shops By Cost Api Messages Admin Cost Observability Shops Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/cost-observability/shops/{shop_id}":{"get":{"tags":["Cost Observability (Admin)"],"summary":"Get Shop Cost Detail","description":"shop 詳細: caller 別 breakdown + 日別推移 (当月).","operationId":"get_shop_cost_detail_api_messages_admin_cost_observability_shops__shop_id__get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Month"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Shop Cost Detail Api Messages Admin Cost Observability Shops  Shop Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/generation-eval/run":{"post":{"tags":["Generation Eval (Admin)"],"summary":"Run Eval","description":"実注文を replay 採点し、generation_eval_runs に保存して report を返す.","operationId":"run_eval_api_messages_admin_generation_eval_run_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunEvalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Run Eval Api Messages Admin Generation Eval Run Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/generation-eval/runs":{"get":{"tags":["Generation Eval (Admin)"],"summary":"List Runs","description":"過去 run 一覧 (最新 50, results は除外して軽量に).","operationId":"list_runs_api_messages_admin_generation_eval_runs_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Runs Api Messages Admin Generation Eval Runs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/messages/admin/generation-eval/runs/{run_id}":{"get":{"tags":["Generation Eval (Admin)"],"summary":"Get Run","description":"1 run の全文 (results 込み).","operationId":"get_run_api_messages_admin_generation_eval_runs__run_id__get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Run Api Messages Admin Generation Eval Runs  Run Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brand-memory/voice-outline":{"get":{"tags":["Brand Memory"],"summary":"Get Voice Outline","description":"声の輪郭 (Phase 4.5 で生成された 5 layer JSON) を返す。\n\nVoice Sync (2026-04-29 fix): voice_sync_source_id が設定されていれば\n主ストアの outline を返し、レスポンスに `is_synced` と `source_shop_name`\nを含める。","operationId":"get_voice_outline_api_brand_memory_voice_outline_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brand-memory/digest-maintenance-status":{"get":{"tags":["Brand Memory"],"summary":"Brand Digest Maintenance Status","description":"ブランドの核 (brand_digest) お手入れの検知をアプリへ返す (cost0・決定論)。\n\nneeds_refresh / material_count / can_maintain を返す。実際の合成は BYO-AI (MCP)。\nVoice-Link target 店は can_maintain=false (同期元で行う)。","operationId":"brand_digest_maintenance_status_api_brand_memory_digest_maintenance_status_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brand-memory/brand-digest":{"get":{"tags":["Brand Memory"],"summary":"Get Brand Digest","description":"ブランド digest (調理済の核テキスト) を返す。\n\nVoice Sync (2026-04-29 fix): voice_sync_source_id が設定されていれば\n主ストアの brand_digest を返す。複数店舗で同 brand を運用する場合に重要。","operationId":"get_brand_digest_api_brand_memory_brand_digest_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brand-memory/product-digests":{"get":{"tags":["Brand Memory"],"summary":"List Product Digests","description":"商品 digest 一覧。Resonance 経路で inject される全商品のリスト。","operationId":"list_product_digests_api_brand_memory_product_digests_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brand-memory/group-digests":{"get":{"tags":["Brand Memory"],"summary":"List Group Digests","description":"グループ digest 一覧。","operationId":"list_group_digests_api_brand_memory_group_digests_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brand-memory/summary":{"get":{"tags":["Brand Memory"],"summary":"Memory Summary","description":"サイドバー / 入口バッジ用の数値サマリ。\n\nVoice Sync (2026-04-29 fix):\n  - voice_outline / brand_digest / authentic_voice_samples_count は sync 元から数える\n    (子ストアでも主ストアの状態が正しく反映される)\n  - product_digest / group_digest は shop 個別資産なので自店から数える\n\nReturns 追加: is_voice_synced, voice_source_shop_name","operationId":"memory_summary_api_brand_memory_summary_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/grow/status":{"get":{"tags":["Grow Cockpit"],"summary":"Grow Status","description":"育てるコックピットの集約検知を返す (cost0・決定論)。\n\n検知ロジックは services.grow_detect.compute_grow_status に切り出し、通知 sweep と共用。\nitems は優先度順 (汚染=最優先)。0件なら items=[] (フロントは「すべて整っています」)。","operationId":"grow_status_api_grow_status_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/grow/redetect-groups":{"post":{"tags":["Grow Cockpit"],"summary":"Redetect Groups","description":"既存グループの重複を整理する (cost0・決定論・LLM不使用)。\n\n再検出ではなく、既存の自動グループ同士を正規化 + あいまい統合し、綴り/スペース揺れの\n重複 (DISH/DISSH/DIESH 等) を実DB上で畳む。代表グループにメンバーを集約し重複を削除。","operationId":"redetect_groups_api_grow_redetect_groups_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/grow/purge-auto-groups":{"post":{"tags":["Grow Cockpit"],"summary":"Purge Auto Groups Endpoint","description":"自動グループ(manual_override=false)を全削除する一回限りのクリーンアップ (admin限定)。\n\nLLM クラスタリングが量産した意味的ノイズを一掃するための保守ツール。手動グループは\n温存。merchant には露出させない (admin allowlist のみ)。x-shop-id で対象 shop を指定。","operationId":"purge_auto_groups_endpoint_api_grow_purge_auto_groups_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/codex":{"get":{"tags":["Voice Study"],"summary":"Get Codex","description":"voice_codex の現在値を返す。Voice Studio 表示用。\n\nVoice Sync 対応 (2026-05-01):\n  - shop が voice_sync_source_id を持つ場合 (= 同期先 shop)、\n    codex / voice_summary / auto_rules すべて同期元から取得する。\n  - これにより「画面上は空だが生成では同期元が使われている」silent failure を防ぐ。\n  - **2026-05-03 sho 指示で auto_rules も sync 対象に変更**:\n    旧設計では子 shop で個別 toggle 可能だったが、親で全 ON 表示なのに\n    子で OFF が反映される矛盾が発生 (UX 上の重大な誤解)。voice_codex 5 軸\n    が既に sync 専用 read-only なので、同じ層に統一する。\n    子側で細かい調整したい店舗主は Voice Link を解除して自立する選択肢が残る。","operationId":"get_codex_api_voice_study_codex_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Voice Study"],"summary":"Update Codex","description":"voice_codex の特定軸を sho が UI で手動編集する。\n\n手動編集された軸は manually_edited_keys に記録され、次回の自動蒸留\n(refresh-all) で AI 出力で上書きされず、sho の意図が恒久的に保持される。","operationId":"update_codex_api_voice_study_codex_patch","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodexUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/auto-rules":{"patch":{"tags":["Voice Study"],"summary":"Update Auto Rule","description":"自動ルール (Context Rule 由来) の ON/OFF を shop ごとに切替。\n\n例: 「3回目のご注文」のように購入回数に触れたい店は\nnumber_recall_forbidden を OFF にできる。default はすべて ON。\n\n2026-05-12 sho 整理判断: 日本語固有ルール (二人称禁止等) は\nculture_modules/ja_jp.py に移動 → /api/voice-study/culture-rules で扱う.\n2026-05-22 P3: gift_inference (贈り主目線禁止) は明細書用途モジュールに\n固定移設したため本トグルから除外。","operationId":"update_auto_rule_api_voice_study_auto_rules_patch","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoRuleToggleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/culture-rules":{"get":{"tags":["Voice Study"],"summary":"Get Culture Rules","description":"文化所作モジュール (Block 1.5) の現在の ON/OFF 状態を取得.\n\nReturns:\n    {\n      \"locale\": \"ja_JP\",\n      \"display_name\": \"日本\",\n      \"rules\": [{\"key\", \"label\", \"description\", \"enabled\"}, ...]\n    }","operationId":"get_culture_rules_api_voice_study_culture_rules_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Voice Study"],"summary":"Update Culture Rule","description":"文化所作モジュール (Block 1.5) のルール ON/OFF を切替.\n\n例: アパレル店舗が「あなた」表現を許したい → j10_second_person を OFF","operationId":"update_culture_rule_api_voice_study_culture_rules_patch","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CultureRuleToggleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/heartbeat":{"get":{"tags":["Voice Study"],"summary":"Get Heartbeat","description":"学習の鼓動 — sample 数 / 編集数 / 最終更新等の統計。\n\nVoice Sync 対応 (2026-05-01):\n  - sample / edit / authentic は **同期元** shop の数字を返す\n    (= 「実際に学習元になっているデータの規模」を見せる)。\n  - voice_codex_meta も同期元の codex から取る。\n  - 同期元 shop 名も含めて返し、UI でバッジ表示できるようにする。","operationId":"get_heartbeat_api_voice_study_heartbeat_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/clear-cassette-warmth":{"post":{"tags":["Voice Study"],"summary":"Clear Cassette Warmth","description":"warmth marker を強制クリア (Phase C-1.5 検証用 / cold start 再現).\n\n通常フローでは呼ばない. shop owner or admin のみ実行可.","operationId":"clear_cassette_warmth_api_voice_study_clear_cassette_warmth_post","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/summary":{"get":{"tags":["Voice Study"],"summary":"Get Voice Summary","description":"新 /dashboard/voice 1 画面用 集約 API (Phase A 2026-05-09).\n\nReturns:\n  personality_score: 0-100 (旧 Voice Maturity, 「ブランドの個性」と表示)\n  personality_stage: \"育ち始め\" | \"深まり中\" | \"成熟\"\n  this_week_evolution: 1-3 行サマリ (今週の進化)\n  next_adventure: { title, description, action_label, action_url }\n  cassette: { exists, version, last_compiled_at, signature_phrases_count }\n  sample_count / authentic_count: Advanced view 用統計","operationId":"get_voice_summary_api_voice_study_summary_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/cassette/full":{"get":{"tags":["Voice Study"],"summary":"Get Cassette Full","description":"active な voice_cassette の中身全体を返す (読み取り専用 UI 用).\n\nReturns:\n  is_starter: bool — starter cassette を使っているか\n  version: int | null\n  compiled_at: ISO str | null\n  cassette: dict — brand_card / voice_card / hard_rules / soft_hints /\n                   exemplar_set / anti_patterns / closing_kit /\n                   bias_check_self / compile_metadata 等の全部\n  source_sample_count: int — 何件のサンプルから作られたか (compile_metadata より)","operationId":"get_cassette_full_api_voice_study_cassette_full_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/maintenance-status":{"get":{"tags":["Voice Study"],"summary":"Get Voice Maintenance Status","description":"声お手入れの検知をアプリへ返す (検知カード用・cost0・決定論)。\n\nneeds_refresh / new_materials / pending_draft / current_cassette を返す。\nVoice-Link target 店は can_maintain=false (source 店で行う)。","operationId":"get_voice_maintenance_status_api_voice_study_maintenance_status_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/cassette/draft":{"get":{"tags":["Voice Study"],"summary":"Get Cassette Draft","description":"未反映の声カセット下書きを返す (プレビュー用)。無ければ has_draft=false。","operationId":"get_cassette_draft_api_voice_study_cassette_draft_get","parameters":[{"name":"shop_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/cassette/apply-draft":{"post":{"tags":["Voice Study"],"summary":"Apply Cassette Draft","description":"下書きを active に昇格する (店主「これで反映」)。learned_principles/editorial_avoids も\nvoice_dna へ書き戻す。決定論・cost0。","operationId":"apply_cassette_draft_api_voice_study_cassette_apply_draft_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_ShopIdBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/voice-study/cassette/rollback":{"post":{"tags":["Voice Study"],"summary":"Rollback Cassette","description":"直前の版へ戻す (店主「前の声に戻す」)。決定論・cost0。","operationId":"rollback_cassette_api_voice_study_cassette_rollback_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_ShopIdBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pdf/generate":{"post":{"tags":["PDF"],"summary":"Generate Pdf","description":"Generate a single message card PDF (legacy).","operationId":"generate_pdf_api_pdf_generate_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfSingleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pdf/generate-batch":{"post":{"tags":["PDF"],"summary":"Generate Batch","description":"Generate a multi-page message card PDF (legacy).","operationId":"generate_batch_api_pdf_generate_batch_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfBatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pdf/generate-slip":{"post":{"tags":["PDF"],"summary":"Generate Slip","description":"Generate packing slip PDFs (明細書).\n\nメッセージカード単体 PDF は 2026-04-22 に廃止。本エンドポイントは\nfull_slip のみを扱う (Literal で担保)。\n\nRate limit: 20 requests per minute per user.","operationId":"generate_slip_api_pdf_generate_slip_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FullSlipRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pdf/preview":{"post":{"tags":["PDF"],"summary":"Preview Pdf","description":"Generate a PDF preview and return as base64.","operationId":"preview_pdf_api_pdf_preview_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfSingleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pdf/regenerate-from-history":{"post":{"tags":["PDF"],"summary":"Regenerate From History","description":"Re-generate a PDF from a saved message in history.\n\nLooks up the message text from message_history and the order details\nfrom order_history.order_data JSONB. No AI API call needed.","operationId":"regenerate_from_history_api_pdf_regenerate_from_history_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegenerateFromHistoryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pdf/templates":{"get":{"tags":["PDF"],"summary":"List Templates","description":"List all available slip design templates.","operationId":"list_templates_api_pdf_templates_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pdf/templates/apply":{"post":{"tags":["PDF"],"summary":"Apply Template","description":"Apply a design template to the shop's slip settings.","operationId":"apply_template_api_pdf_templates_apply_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplyTemplateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/settings":{"get":{"tags":["Settings"],"summary":"Get Settings","description":"Get current shop settings (including shop info).\n\nVoice Link Option α (2026-05-03): 同期 shop の場合、voice 系 frozen\nフィールド + voice_dna は親の値で overlay して返す。これにより UI が\n「実際に生成で使われる値」を表示でき、矛盾 (子で OFF / 親で全 ON 等) が\n起きない。同期情報も `voice_sync.is_synced / source_shop_id /\nsource_shop_name` として公開し、フロントが read-only banner を出せる。","operationId":"get_settings_api_settings_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Settings"],"summary":"Patch Settings","description":"Update shop settings.","operationId":"patch_settings_api_settings_patch","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSettingsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/settings/upload-logo":{"post":{"tags":["Settings"],"summary":"Upload Logo","description":"Upload a logo image (stored as base64 data URL in settings).","operationId":"upload_logo_api_settings_upload_logo_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_logo_api_settings_upload_logo_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/settings/message-sync/shops":{"get":{"tags":["Settings"],"summary":"List Message Syncable Shops","description":"List other shops owned by the same user that have message settings configured.","operationId":"list_message_syncable_shops_api_settings_message_sync_shops_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/settings/message-sync":{"post":{"tags":["Settings"],"summary":"Enable Message Sync","description":"Enable message sync: copy message settings from source shop and link.","operationId":"enable_message_sync_api_settings_message_sync_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSyncRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Settings"],"summary":"Disable Message Sync","description":"Disable message sync: this shop will use its own settings.","operationId":"disable_message_sync_api_settings_message_sync_delete","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/settings/message-sync/status":{"get":{"tags":["Settings"],"summary":"Get Message Sync Status","description":"Get the current message sync status.","operationId":"get_message_sync_status_api_settings_message_sync_status_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing":{"get":{"tags":["Billing"],"summary":"Get Billing","description":"Get current billing info for the user.\n\nPhase NOTIF-4 fix (2026-05-11): brand_id クエリパラメータ対応.\nmulti-brand owner では brand_id を渡すことで該当 brand の subscription\nを返す. 未指定時は legacy 互換 (data[0] = 最初の sub) で返す.\n\nFrontend 側 (billing/page.tsx) は currentShop?.brand_id を渡す必要あり.","operationId":"get_billing_api_billing_get","parameters":[{"name":"brand_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/plans":{"get":{"tags":["Billing"],"summary":"Get Plans","description":"Get available plans with pricing details.\n\nNew model (2026-04): Free (30 messages) + Standard (¥980 base + usage-based).","operationId":"get_plans_api_billing_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/billing/usage-by-shop":{"get":{"tags":["Billing"],"summary":"Get Usage By Shop","description":"Get current billing period message count broken down by shop.\n\nReturns a list of {shop_id, shop_name, platform, message_count} for each\nshop owned by the user, plus the total.","operationId":"get_usage_by_shop_api_billing_usage_by_shop_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/usage-by-mode":{"get":{"tags":["Billing"],"summary":"Get Usage By Mode","description":"Wave 4 (2026-05-06): 当月の instant vs reflective 内訳を返す.\n\n課金ページの「料金内訳」セクションで使用. message_history.engine_metadata.mode\nを集計する. mode 未セットの行 (Wave 4 以前 / 移行漏れ) は instant 扱い.\n\nReturns:\n    {\n      \"instant\": {\"count\": int, \"amount_jpy\": int, \"unit_price\": int},\n      \"reflective\": {\"count\": int, \"amount_jpy\": int, \"unit_price\": int},\n      \"total_count\": int,\n      \"total_amount_jpy\": int,\n      \"period_start\": iso str | null,\n    }","operationId":"get_usage_by_mode_api_billing_usage_by_mode_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/pending-reflective-count":{"get":{"tags":["Billing"],"summary":"Get Pending Reflective Count","description":"Wave 4 (2026-05-06): 該 shop の予約中件数を返す軽量 endpoint.\n\nサイドバーの「予約一覧」エントリに件数 badge を出すために polling される.\nSWR refresh interval は 30s 推奨 (重要度低).","operationId":"get_pending_reflective_count_api_billing_pending_reflective_count_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/create-checkout":{"post":{"tags":["Billing"],"summary":"Create Checkout","description":"Create a Stripe Checkout session for free → standard upgrade.\n\nNew model (2026-04): Only one paid plan (standard).\nSubscription has 2 Stripe items:\n  1. Base price: ¥980/month (recurring fixed)\n  2. Metered price: per-message usage (tiered: ¥18 × 1-300, ¥15 × 301+)","operationId":"create_checkout_api_billing_create_checkout_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/create-portal":{"post":{"tags":["Billing"],"summary":"Create Portal","description":"Create a Stripe Customer Portal session.","operationId":"create_portal_api_billing_create_portal_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/invoices":{"get":{"tags":["Billing"],"summary":"Get Invoices","description":"Get invoice history from Stripe.\n\nReturns past invoices with amounts, dates, status, and PDF download URLs.\nAlso ensures Stripe is configured to email invoices to the customer.","operationId":"get_invoices_api_billing_invoices_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Limit"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/cancel":{"post":{"tags":["Billing"],"summary":"Cancel Subscription","description":"Cancel the user's Stripe subscription.\n\nDefault behavior: cancel at end of current billing period (prorate=False).\nThe user retains access until `current_period_end`, then the webhook\n`customer.subscription.deleted` automatically downgrades to free.\n\nIf immediate=True, cancel right away and prorate.\n\nPhase 3 (2026-04-26 fix): brand_id を必須に近い形で受ける。multi-brand\nowner で brand_id を渡さずに呼ぶと 400 で拒否 (どの sub をキャンセルする\nか曖昧)。1-brand owner は legacy 互換で brand_id 省略可。Stripe 上は対象\nの 1 sub のみ delete し、DB UPDATE も WHERE id = (target row id) で 1 行\n限定 — owner_id 単条件で全 sub を巻き込む旧バグの再発を防ぐ。","operationId":"cancel_subscription_api_billing_cancel_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/reactivate":{"post":{"tags":["Billing"],"summary":"Reactivate Subscription","description":"Reactivate a subscription that was set to cancel at period end.\n\nOnly works if the subscription hasn't actually been deleted yet\n(status is cancel_pending, Stripe still has it as active with\ncancel_at_period_end=True).\n\nPhase 3 (2026-04-26 fix): brand_id 対応。multi-brand owner で brand_id を\n渡さずに呼ぶと 400 で拒否。1-brand owner は brand_id 省略可 (legacy 互換)。\nDB UPDATE は WHERE id = (target row id) で 1 行限定 — owner_id 単条件で\n全 sub の status を上書きする旧バグの再発を防ぐ。","operationId":"reactivate_subscription_api_billing_reactivate_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ReactivateRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/invoice-email-status":{"get":{"tags":["Billing"],"summary":"Get Invoice Email Status","description":"Check if invoice emails are enabled for this customer.","operationId":"get_invoice_email_status_api_billing_invoice_email_status_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/enable-invoice-email":{"post":{"tags":["Billing"],"summary":"Enable Invoice Email","description":"Toggle automatic invoice emails for this customer in Stripe.","operationId":"enable_invoice_email_api_billing_enable_invoice_email_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceEmailRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/brand-plans":{"get":{"tags":["Billing"],"summary":"Get Brand Plans","description":"Return per-brand plan summaries for sidebar / header badge display.\n\nPhase NOTIF-4 (2026-05-11, sho UX 提案): multi-brand owner が\nどの brand が何プランか一目で分かるようにするため. UI コンポーネント\nPlanBadge から呼ばれる軽量エンドポイント.\n\nReturns: {brand_id: {plan, status, cancel_at_period_end}}\n    - brand_id: subscription の brand_id (None の場合は除外)\n    - plan: 'free' | 'standard' | 'dev'\n    - cancel_at_period_end: 解約予約中なら true","operationId":"get_brand_plans_api_billing_brand_plans_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/billing-profile":{"get":{"tags":["Billing"],"summary":"Get Billing Profile","description":"現在の請求情報を返す。未契約 (subscription 無し) も {all null} で返す。","operationId":"get_billing_profile_api_billing_billing_profile_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Billing"],"summary":"Update Billing Profile","description":"請求情報を保存し、Stripe Customer にも即時同期する。","operationId":"update_billing_profile_api_billing_billing_profile_put","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingProfile"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/setup-intent":{"post":{"tags":["Billing"],"summary":"Create Setup Intent","description":"Return a SetupIntent client_secret for Stripe Elements card collection.","operationId":"create_setup_intent_api_billing_setup_intent_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/add-brand":{"post":{"tags":["Billing"],"summary":"Add Brand","description":"新ブランドを追加し、その brand 用の Standard Subscription を Stripe で\n作成する。Free user は既存 brand 用も同時に upgrade される (atomic)。\n\nReturns: {brand_id, created_subscription_ids: [...], message}","operationId":"add_brand_api_billing_add_brand_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBrandRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/delete-account":{"post":{"tags":["Billing"],"summary":"Delete Account","description":"Permanently delete a user's account and all associated data.\n\nOnly available for free plan users. Paid users must cancel first.\nRequires confirmation string \"DELETE\" to prevent accidental deletion.\n\nDeletes in order:\n1. Stripe customer (if exists) — removes payment methods & invoices\n2. Messages, usage_logs, order_history (shop-linked data)\n3. Shop settings, soeru_link data\n4. Shops\n5. Subscription record\n6. User profile\n7. Supabase Auth user","operationId":"delete_account_api_billing_delete_account_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/dashboard":{"get":{"tags":["Analytics"],"summary":"Get Dashboard Data","description":"Get dashboard summary data.\n\nPerformance optimizations:\n- 5-min in-memory cache, invalidated on message generation\n- asyncio.to_thread() for all sync Supabase calls → true parallelism\n- Consolidated per-shop monthly counts into single in_() query\n- Reduced total queries from ~15+ sequential to ~8 parallel","operationId":"get_dashboard_data_api_analytics_dashboard_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics":{"get":{"tags":["Analytics"],"summary":"Get Analytics","description":"Get full analytics data for the analytics page.\n\nPerf note (2026-04-23): the five queries below (monthly counts ×2 +\n30-day paginated aggregations ×3 over message_history) used to run\nserially on the request thread. They are now executed in parallel\nvia ``asyncio.gather`` + ``asyncio.to_thread`` — each inner function\nstill owns its own try/except so a single sub-query failure degrades\nto safe defaults without taking the whole endpoint down. Wall-clock\nimproves roughly ``Σ latencies → max latency`` for this endpoint,\nwhich is the dominant cost for ``/dashboard/insights``.","operationId":"get_analytics_api_analytics_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/growth":{"get":{"tags":["Analytics"],"summary":"Get Growth","description":"Get soeru Growth Index — 5-dimension learning visualization data.","operationId":"get_growth_api_analytics_growth_get","parameters":[{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":52,"minimum":1,"description":"Number of weeks of history","default":12,"title":"Weeks"},"description":"Number of weeks of history"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/customer-stories":{"get":{"tags":["Analytics"],"summary":"Get Customer Stories","description":"Get detailed customer stories for the shop.","operationId":"get_customer_stories_api_analytics_customer_stories_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Max stories to return","default":20,"title":"Limit"},"description":"Max stories to return"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/analyze-arcs":{"post":{"tags":["Analytics"],"summary":"Trigger Arc Analysis","description":"Trigger arc analysis for the shop's customers.\n\nAnalyzes customers with 2+ orders who haven't been analyzed recently.","operationId":"trigger_arc_analysis_api_analytics_analyze_arcs_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/usage":{"get":{"tags":["Analytics"],"summary":"Get Usage Stats","description":"Get usage statistics for the shop.","operationId":"get_usage_stats_api_analytics_usage_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"day, week, month","default":"month","title":"Period"},"description":"day, week, month"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/engagement":{"get":{"tags":["Analytics"],"summary":"Get Engagement","description":"Get engagement summary with period-over-period comparison.\n\nReturns metrics for the last 30 days vs the previous 30 days,\nincluding message volume, repeat rate, feedback, and link scans.","operationId":"get_engagement_api_analytics_engagement_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/engagement/trend":{"get":{"tags":["Analytics"],"summary":"Get Engagement Trend","description":"Get weekly engagement trend data for charting.","operationId":"get_engagement_trend_api_analytics_engagement_trend_get","parameters":[{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":52,"minimum":4,"default":12,"title":"Weeks"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/engagement/refresh":{"post":{"tags":["Analytics"],"summary":"Refresh Engagement Snapshots","description":"Rebuild weekly engagement snapshots (admin action).","operationId":"refresh_engagement_snapshots_api_analytics_engagement_refresh_post","parameters":[{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":52,"minimum":4,"default":12,"title":"Weeks"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/dashboard/link-stats":{"get":{"tags":["Analytics"],"summary":"Get Dashboard Link Stats","description":"Lightweight link stats for dashboard card (total_codes, total_scans, scan_rate + QR feedback).","operationId":"get_dashboard_link_stats_api_analytics_dashboard_link_stats_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/link":{"get":{"tags":["Analytics"],"summary":"Get Link Analytics Summary","description":"Get つなぐQR scan/click funnel summary.","operationId":"get_link_analytics_summary_api_analytics_link_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":7,"default":30,"title":"Days"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/link/trend":{"get":{"tags":["Analytics"],"summary":"Get Link Trend","description":"Get weekly つなぐQR scan/click trend data.","operationId":"get_link_trend_api_analytics_link_trend_get","parameters":[{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":52,"minimum":4,"default":12,"title":"Weeks"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/daily-breakdown":{"get":{"tags":["Analytics"],"summary":"Get Daily Breakdown","description":"Get daily message counts for a given month across all shops.\n\nReturns per-day counts for the requested month, used by the\ndashboard's accordion daily breakdown. Only fetched on demand\n(lazy-loaded) for better performance.","operationId":"get_daily_breakdown_api_analytics_daily_breakdown_get","parameters":[{"name":"year","in":"query","required":true,"schema":{"type":"integer","maximum":2030,"minimum":2024,"title":"Year"}},{"name":"month","in":"query","required":true,"schema":{"type":"integer","maximum":12,"minimum":1,"title":"Month"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/dashboard/feature-summary":{"get":{"tags":["Analytics"],"summary":"Get Feature Summary","description":"FeatureMenu 9 カード分の実数値メトリクスを 1 shot で返却.\n\n各 metric は best-effort (table 不在や query 失敗時は 0 / None で続行).\nFailure は warning ログのみ、レスポンスは 200 で返す (UI 側は欠落 metric\nがあれば fallback 表示する).","operationId":"get_feature_summary_api_analytics_dashboard_feature_summary_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/next-action":{"get":{"tags":["Growth Journey"],"summary":"Get Next Action","description":"次にやるべき 1 アクションを返す。\n\n成熟度ステージ (setup_platform → brand → product → voice → first_practice\n→ mature) を判定し、欠けている層を埋める提案を 1 つだけ返す。全ステージ\n充足後は最適化提案 (溜まった編集を学ばせる、長期休止からの復帰など)。\n\nレスポンス例:\n    {\n      \"action_id\": \"add_brand_url\",\n      \"stage\": \"brand_foundation\",\n      \"title\": \"ブランドのストーリー URL を 1 件追加\",\n      \"why\": \"...\",\n      \"cta_label\": \"URL を追加する\",\n      \"cta_href\": \"/dashboard/settings/brand\",\n      \"index_delta\": 12,\n      \"is_milestone\": true,\n      \"is_blocked_by_v3\": true\n    }","operationId":"get_next_action_api_growth_next_action_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Next Action Api Growth Next Action Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/learning-log":{"get":{"tags":["Growth Journey"],"summary":"Get Learning Log","description":"soeru があなたから学んだルールを返す (#339)。\n\nvoice_codex (現在 state) × 直近 weeks 週の編集 (証拠) を突き合わせて\n「使わなくなった (forbidden)」「選ぶようになった (preferred)」ルールを\n最大 8 件返す。各ルールに前後ペアと「学習後に何件で適用されたか」が付く。\n\nレスポンス例:\n    {\n      \"period\": {\"start\": \"...\", \"end\": \"...\", \"weeks\": 4},\n      \"summary\": {\"edit_count\": 23, \"generation_count\": 156, ...},\n      \"learnings\": [\n        {\n          \"kind\": \"forbidden\",\n          \"rule\": \"あなたの\",\n          \"headline\": \"「あなたの」を控えるようになりました\",\n          \"evidence_count\": 3,\n          \"sample_pairs\": [{before, after, edited_at}, ...],\n          \"application_applied\": 142, \"application_total\": 156\n        }\n      ],\n      \"fallback_signatures\": [...]  // learnings が空の時だけ\n    }","operationId":"get_learning_log_api_growth_learning_log_get","parameters":[{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":26,"minimum":1,"description":"lookback window in weeks","default":4,"title":"Weeks"},"description":"lookback window in weeks"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Learning Log Api Growth Learning Log Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/self-portrait":{"get":{"tags":["Growth Journey"],"summary":"Get Self Portrait","description":"soeru の自己紹介テキスト (一人称、200 字)。\n\nvoice_codex を Sonnet で詩化、24h cache。voice_codex が空の shop には\nLLM を呼ばず空状態 (status=\"empty\") を返す。\n\nレスポンス例:\n    {\n      \"status\": \"ok\",\n      \"text\": \"私はこのお店の声で書きます。\\n丁寧だけど距離が近い...\",\n      \"generated_at\": \"2026-05-01T12:00:00+00:00\",\n      \"voice_codex_updated_at\": \"2026-04-30T18:00:00+00:00\",\n      \"from_cache\": false\n    }","operationId":"get_self_portrait_api_growth_self_portrait_get","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass 24h cache (e.g. after 違和感 click)","default":false,"title":"Force"},"description":"Bypass 24h cache (e.g. after 違和感 click)"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Self Portrait Api Growth Self Portrait Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/self-portrait/feedback":{"post":{"tags":["Growth Journey"],"summary":"Post Self Portrait Feedback","description":"「違和感がある」が押された時。cache を invalidate して次回再生成させる。\n\n将来は受信したフィードバックを voice_codex のメタに追記して LLM 蒸留時に\n考慮させる拡張余地あり (まずは最小実装)。","operationId":"post_self_portrait_feedback_api_growth_self_portrait_feedback_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Self Portrait Feedback Api Growth Self Portrait Feedback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/letters":{"get":{"tags":["Growth Journey"],"summary":"Get Letters","description":"soeru からの手紙の履歴 (最新順)。\n\n1 通目が「今週の手紙」、2 通目以降が過去のアーカイブ。frontend は\n1 通目を大きく表示、2 通目以降を折りたたみで見せる想定。","operationId":"get_letters_api_growth_letters_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"recent letters to return","default":10,"title":"Limit"},"description":"recent letters to return"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Letters Api Growth Letters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/letters/{letter_id}/read":{"post":{"tags":["Growth Journey"],"summary":"Post Letter Read","description":"手紙を既読にする。","operationId":"post_letter_read_api_growth_letters__letter_id__read_post","parameters":[{"name":"letter_id","in":"path","required":true,"schema":{"type":"string","title":"Letter Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Letter Read Api Growth Letters  Letter Id  Read Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/letters/generate-now":{"post":{"tags":["Growth Journey"],"summary":"Post Letter Generate Now","description":"ad-hoc に手紙を 1 通生成 (sho の手動トリガー)。dedup なし。\n\nSonnet 1 回 (約 ¥2)。連打防止は frontend のローディング表示に任せる。","operationId":"post_letter_generate_now_api_growth_letters_generate_now_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Letter Generate Now Api Growth Letters Generate Now Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/proposals":{"get":{"tags":["Growth Journey"],"summary":"Get Proposals","description":"ホーム画面用「soeru からの提案」最大 N 件 (Phase A6)。\n\n5 ジャンル (edit_pattern / product_knowledge / brand_stagnation /\nrhythm / rule_conflict) のルールベース検知器を順に走らせ、priority 順\nで上位 N 件返す。dismiss 済みは除外。LLM 呼び出し無し。\n\n検知器は全て独立 try/except で隔離 (1 ジャンル失敗で他が止まらない)。","operationId":"get_proposals_api_growth_proposals_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5,"minimum":1,"description":"max proposals to return","default":3,"title":"Limit"},"description":"max proposals to return"},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Proposals Api Growth Proposals Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/proposals/{proposal_id}/dismiss":{"post":{"tags":["Growth Journey"],"summary":"Post Dismiss Proposal","description":"proposal を 7 日 cooldown で dismiss する。","operationId":"post_dismiss_proposal_api_growth_proposals__proposal_id__dismiss_post","parameters":[{"name":"proposal_id","in":"path","required":true,"schema":{"type":"string","title":"Proposal Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Dismiss Proposal Api Growth Proposals  Proposal Id  Dismiss Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/growth/timeline":{"get":{"tags":["Growth Journey"],"summary":"Get Timeline","description":"育成の年表 (出会いから今日までの主要マイルストーン)。\n\nLLM 不要。既存テーブル (shops / brand_knowledge / brand_digest /\nvoice_samples / voice_outline / message_history / voice_dna) から\n各 1 クエリで最古日を集めるだけ。\n\nレスポンス:\n    {\n      \"shop_id\": \"...\",\n      \"event_count\": 7,\n      \"events\": [\n        {\"type\": \"v3_engine_active\", \"date\": \"2026-04-30\",\n         \"title\": \"V3 narrative engine が起動しました\",\n         \"body\": \"詩的表現が解禁された日...\",\n         \"icon\": \"✨\"},\n        ...\n      ]\n    }\n\n新しい順 (今日に近いものが先頭) でフロントが上から表示する想定。","operationId":"get_timeline_api_growth_timeline_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Timeline Api Growth Timeline Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/notifications":{"get":{"tags":["Notifications","notifications"],"summary":"List Notifications","description":"inbox 一覧を返す (新しい順).","operationId":"list_notifications_api_notifications_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":30,"title":"Limit"}},{"name":"unread_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Unread Only"}},{"name":"include_dismissed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Dismissed"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Notifications Api Notifications Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/notifications/unread-count":{"get":{"tags":["Notifications","notifications"],"summary":"Get Unread Count","description":"未読件数のみ返す (右上バッジ用、軽量).","operationId":"get_unread_count_api_notifications_unread_count_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"integer"},"title":"Response Get Unread Count Api Notifications Unread Count Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/notifications/{notification_id}/read":{"post":{"tags":["Notifications","notifications"],"summary":"Mark One Read","description":"1 件を既読にする.","operationId":"mark_one_read_api_notifications__notification_id__read_post","parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"string","title":"Notification Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Mark One Read Api Notifications  Notification Id  Read Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/notifications/read-all":{"post":{"tags":["Notifications","notifications"],"summary":"Mark All Read","description":"user の全未読を既読にする. 更新件数を返す.","operationId":"mark_all_read_api_notifications_read_all_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Mark All Read Api Notifications Read All Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/notifications/{notification_id}":{"delete":{"tags":["Notifications","notifications"],"summary":"Dismiss Notification","description":"1 件を dismiss (inbox から消す). DB 上には dismissed_at で残る.","operationId":"dismiss_notification_api_notifications__notification_id__delete","parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"string","title":"Notification Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Dismiss Notification Api Notifications  Notification Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/webhooks/stripe":{"post":{"tags":["Webhooks"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events.","operationId":"stripe_webhook_api_webhooks_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/products":{"get":{"tags":["Products"],"summary":"List Products","description":"List products in the shop's catalog.\n\nq を渡すと item_name / learned_summary / platform_item_id を横断 ilike 検索する\n(全件サーバー検索・ページング対応)。","operationId":"list_products_api_products_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by learning_status","title":"Status"},"description":"Filter by learning_status"},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"商品名/要約/商品IDの横断検索 (ilike)","title":"Q"},"description":"商品名/要約/商品IDの横断検索 (ilike)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/digest-overlaps":{"get":{"tags":["Products"],"summary":"Get Digest Overlaps","description":"Shop 内の素材リスト重複疑いペアを返す.\n\nUI バッジ + 重複疑い notice に使う.","operationId":"get_digest_overlaps_api_products_digest_overlaps_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/maintenance-status":{"get":{"tags":["Products"],"summary":"Product Maintenance Status","description":"商品お手入れカード用の検知を返す (注文駆動4バケツ・cost0)。\n\nunlearned/stale/missing/contaminated + count + page。soeru は LLM を呼ばない。","operationId":"product_maintenance_status_api_products_maintenance_status_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"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/{product_id}":{"get":{"tags":["Products"],"summary":"Get Product","description":"Get full product details including learned knowledge.","operationId":"get_product_api_products__product_id__get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Products"],"summary":"Update Product","description":"Manually update product knowledge.","operationId":"update_product_api_products__product_id__put","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProductRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Products"],"summary":"Delete Product","description":"Delete a product from the catalog.","operationId":"delete_product_api_products__product_id__delete","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/learn":{"post":{"tags":["Products"],"summary":"Learn Products","description":"Trigger AI learning for specified products.","operationId":"learn_products_api_products_learn_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualLearnRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/learn-from-orders":{"post":{"tags":["Products"],"summary":"Learn From Orders","description":"Learn products from existing order history.","operationId":"learn_from_orders_api_products_learn_from_orders_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/manual":{"post":{"tags":["Products"],"summary":"Add Manual Product","description":"Manually add a product to the catalog (before orders arrive).","operationId":"add_manual_product_api_products_manual_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualProductRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/quota/url-learn":{"get":{"tags":["Products"],"summary":"Get Url Learn Quota","description":"商品 URL 学習の当月 quota を返す (UI 表示用)。","operationId":"get_url_learn_quota_api_products_quota_url_learn_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/{product_id}/learn-url":{"post":{"tags":["Products"],"summary":"Learn From Url","description":"商品ページURLを取得し raw_data に格納する (PL-P7: 取り込みのみ・cost0)。\n\n事実抽出は BYO-AI (MCP) が行うため soeru は LLM を呼ばない。よって月間 quota は撤去\n(取得は API/HTTP だけで安価)。取得後は learning_status='pending' になり、商品お手入れ\nカード / compose_message のインライン学習で店主の AI が学ぶ。","operationId":"learn_from_url_api_products__product_id__learn_url_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/URLLearnRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/{product_id}/hint":{"patch":{"tags":["Products"],"summary":"Update Manual Hint","description":"Set or update a manual hint for a product.","operationId":"update_manual_hint_api_products__product_id__hint_patch","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualHintRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/{product_id}/canonical":{"patch":{"tags":["Products"],"summary":"Confirm Canonical Name","description":"Confirm/lock canonical names for this product (Layer 3 manual_2step).","operationId":"confirm_canonical_name_api_products__product_id__canonical_patch","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmCanonicalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/{product_id}/canonicalize":{"post":{"tags":["Products"],"summary":"Backfill Canonical Name","description":"Run Layer 2 canonicalization on an existing product (backfill).","operationId":"backfill_canonical_name_api_products__product_id__canonicalize_post","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/canonicalize-all":{"post":{"tags":["Products"],"summary":"Bulk Canonicalize All","description":"Bulk-canonicalize all learned products that lack canonical_name_*.\n\nReturns counts: processed / succeeded / skipped (manual). Errors per\nproduct are silently logged + counted but don't abort the batch.","operationId":"bulk_canonicalize_all_api_products_canonicalize_all_post","parameters":[{"name":"max_products","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Max Products"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/{product_id}/corrections":{"get":{"tags":["Products"],"summary":"List Product Corrections","description":"Return the product_name_corrections timeline for this product.","operationId":"list_product_corrections_api_products__product_id__corrections_get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/{product_id}/forbidden":{"delete":{"tags":["Products"],"summary":"Unban Forbidden Variant","description":"Remove one entry from forbidden_variants (operator override).","operationId":"unban_forbidden_variant_api_products__product_id__forbidden_delete","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenVariantRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/products/{product_id}/digest":{"get":{"tags":["Products"],"summary":"Get Product Digest","description":"Get the active product_digest for a product (UI 表示用).\n\nReturns:\n  digest_text: メッセージ生成時に writer に渡される本文\n  manual_override: True なら sho が手動で書いた版 (自動再生成されない)\n  compiled_by_model: どの方法で作られたか\n  manual_edited_at: 最後の手動編集時刻\n  compiled_at: 自動生成時刻","operationId":"get_product_digest_api_products__product_id__digest_get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Products"],"summary":"Update Product Digest","description":"Manually override product_digest text.\n\n`manual_override=true` を立てると次回の自動再生成で上書きされなくなる.\nsho が「これが正しい digest だ」と確定する操作.","operationId":"update_product_digest_api_products__product_id__digest_patch","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigestUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/install":{"get":{"tags":["Shopify OAuth"],"summary":"Shopify Install","description":"Entry point for Shopify App Store installs.\n\nThis endpoint does NOT require soeru authentication. It initiates the\nShopify OAuth flow directly so that App Store reviewers (and new merchants)\nget the expected \"install → app works\" experience.\n\nAfter OAuth completes, the callback detects this is an install flow and\nredirects the user to /setup/shopify where they can create or link a\nsoeru account.","operationId":"shopify_install_api_shopify_install_get","parameters":[{"name":"shop","in":"query","required":true,"schema":{"type":"string","description":"Shopify store domain","title":"Shop"},"description":"Shopify store domain"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/auth":{"post":{"tags":["Shopify OAuth"],"summary":"Start Shopify Auth","description":"Generate Shopify authorization URL for the current shop.\n\nThe frontend should redirect the user to auth_url.","operationId":"start_shopify_auth_api_shopify_auth_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShopifyAuthRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShopifyAuthResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/callback":{"get":{"tags":["Shopify OAuth"],"summary":"Shopify Callback","description":"Handle Shopify OAuth callback.\n\nShopify redirects here after user authorizes. We:\n1. Verify HMAC signature\n2. Verify state matches a pending auth request\n3. Exchange authorization code for access token\n4. Store the token in shop_settings\n5. Redirect to frontend settings page","operationId":"shopify_callback_api_shopify_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"shop","in":"query","required":true,"schema":{"type":"string","title":"Shop"}},{"name":"state","in":"query","required":true,"schema":{"type":"string","title":"State"}},{"name":"hmac","in":"query","required":false,"schema":{"type":"string","default":"","title":"Hmac"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/claim-install":{"post":{"tags":["Shopify OAuth"],"summary":"Claim Shopify Install","description":"Claim a pending Shopify install for the authenticated user.\n\nThis is called from the /setup/shopify page after the user logs in or\ncreates an account. It:\n1. Validates the setup token\n2. Creates a soeru shop for the user\n3. Stores the Shopify access token in shop_settings\n4. Deletes the pending install record","operationId":"claim_shopify_install_api_shopify_claim_install_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimShopifyInstallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/pending-install":{"get":{"tags":["Shopify OAuth"],"summary":"Get Pending Install","description":"Retrieve pending install info for the setup page (no auth required).","operationId":"get_pending_install_api_shopify_pending_install_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"Setup token from install redirect","title":"Token"},"description":"Setup token from install redirect"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/status":{"get":{"tags":["Shopify OAuth"],"summary":"Shopify Connection Status","description":"Check if the current shop has a valid Shopify connection.","operationId":"shopify_connection_status_api_shopify_status_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/diagnose":{"get":{"tags":["Shopify OAuth"],"summary":"Shopify Diagnose","description":"Diagnostic endpoint to check Shopify API access and data quality.\n\nReturns: granted scopes, order count, sample customer data with orders_count,\nand whether read_all_orders is actually working.","operationId":"shopify_diagnose_api_shopify_diagnose_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/disconnect":{"post":{"tags":["Shopify OAuth"],"summary":"Disconnect Shopify","description":"Remove Shopify connection for the current shop.","operationId":"disconnect_shopify_api_shopify_disconnect_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/manual-connect":{"post":{"tags":["Shopify OAuth"],"summary":"Manual Shopify Connect","description":"Connect a Shopify store using a manually obtained Admin API access token.\n\nThis is used for custom apps created directly in the Shopify store admin,\nbypassing the OAuth flow. The token is validated via GraphQL shop query.","operationId":"manual_shopify_connect_api_shopify_manual_connect_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualShopifyConnectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/client-credentials-connect":{"post":{"tags":["Shopify OAuth"],"summary":"Client Credentials Connect","description":"Connect a Shopify store using Client Credentials Grant.\n\nThis is for apps created in the Shopify Dev Dashboard (new flow from 2025+).\nInstead of a static access token, we exchange Client ID + Client Secret\nfor a temporary access token via Shopify's OAuth endpoint.","operationId":"client_credentials_connect_api_shopify_client_credentials_connect_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientCredentialsConnectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/yahoo/auth":{"post":{"tags":["Yahoo OAuth"],"summary":"Yahoo Auth Start","description":"認可URLを生成して返す。フロントは返り値の auth_url へ遷移する。\n\n前提: shop_settings に yahoo_app_id (Client ID) が保存済みであること\n(= 店主が自分の Yahoo アプリの Client ID/Secret を先に保存)。","operationId":"yahoo_auth_start_api_yahoo_auth_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthStartRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/yahoo/callback":{"get":{"tags":["Yahoo OAuth"],"summary":"Yahoo Callback","description":"Yahoo からのコールバック。state を検証し code をトークンに交換して保存する。","operationId":"yahoo_callback_api_yahoo_callback_get","parameters":[{"name":"code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"error","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},{"name":"error_description","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Description"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/yahoo/status":{"get":{"tags":["Yahoo OAuth"],"summary":"Yahoo Status","description":"接続状態を返す。フロントの接続 UI で使用。","operationId":"yahoo_status_api_yahoo_status_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/yahoo/disconnect":{"post":{"tags":["Yahoo OAuth"],"summary":"Yahoo Disconnect","description":"保存済みトークンを破棄 (Client ID/Secret は残す → 再接続が容易)。","operationId":"yahoo_disconnect_api_yahoo_disconnect_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shopify/webhooks/customers-data-request":{"post":{"tags":["Shopify Webhooks"],"summary":"Customers Data Request","description":"Handle customers/data_request webhook.\n\nA customer has requested their data. Collect all data stored about\nthe customer and return it. Shopify will forward this to the customer.\n\nData we store:\n- order_history: order records containing customer_name, customer_email\n- message_history: AI-generated messages linked to orders","operationId":"customers_data_request_api_shopify_webhooks_customers_data_request_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/shopify/webhooks/customers-redact":{"post":{"tags":["Shopify Webhooks"],"summary":"Customers Redact","description":"Handle customers/redact webhook.\n\nShopify requests deletion of a specific customer's data.\nAnonymize customer info in order_history.\n\nGDPR critical (2026-05-13 audit lens 3): 必ず shop_domain → shop_id 解決を\n挟んで shop_id でフィルタする. 同じ customer_email が複数 soeru shop に\n紐づいている場合に、他店舗の order が巻き込まれて REDACTED 化される\nクロスショップ事故を防ぐ.","operationId":"customers_redact_api_shopify_webhooks_customers_redact_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/shopify/webhooks/shop-redact":{"post":{"tags":["Shopify Webhooks"],"summary":"Shop Redact","description":"Handle shop/redact webhook.\n\nShopify requests deletion of ALL data for a shop (48 hours after uninstall).\nDelete all soeru data for the shop.","operationId":"shop_redact_api_shopify_webhooks_shop_redact_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/shopify/webhooks/app-uninstalled":{"post":{"tags":["Shopify Webhooks"],"summary":"App Uninstalled","description":"Handle app/uninstalled webhook.\n\nThe store has uninstalled soeru. Clear the access token but keep\ndata (shop/redact will handle full deletion after 48 hours).","operationId":"app_uninstalled_api_shopify_webhooks_app_uninstalled_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/b2b/settings":{"get":{"tags":["B2B Documents"],"summary":"Get B2B Settings","description":"Get current B2B settings for the shop.","operationId":"get_b2b_settings_api_b2b_settings_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["B2B Documents"],"summary":"Update B2B Settings","description":"Update B2B settings.","operationId":"update_b2b_settings_api_b2b_settings_put","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/B2BSettingsUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/b2b/generate":{"post":{"tags":["B2B Documents"],"summary":"Generate B2B Documents","description":"一般注文と卸注文が混在した選択を、1本のPDFにまとめて出力する。\n\nハイブリッド運用 (2026-08-03):\nB2B帳票機能を ON にしているショップでも、出荷キューには一般消費者の注文が\n普通に並ぶ。ここでは注文ごとに卸かどうかを DB から確定させ、卸だけを法人\n書式 (納品書/請求書/…) に回し、一般のお客様には従来の明細書を出す。\n\nRate limit: 20 requests per minute per user.","operationId":"generate_b2b_documents_api_b2b_generate_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/B2BDocumentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/b2b/preview":{"post":{"tags":["B2B Documents"],"summary":"Preview B2B Document","description":"Generate a preview (base64) of a B2B document.\n\nTypically called with a single order and single document_type for preview.","operationId":"preview_b2b_document_api_b2b_preview_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/B2BDocumentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-samples":{"get":{"tags":["Resonance Engine"],"summary":"List Voice Samples","description":"List all active voice samples for the current shop.","operationId":"list_voice_samples_api_resonance_voice_samples_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Resonance Engine"],"summary":"Add Voice Sample","description":"Add a single voice sample.","operationId":"add_voice_sample_api_resonance_voice_samples_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddVoiceSampleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-samples/{sample_id}":{"get":{"tags":["Resonance Engine"],"summary":"Get Voice Sample","description":"Fetch a single voice sample by id (for the detail page).","operationId":"get_voice_sample_api_resonance_voice_samples__sample_id__get","parameters":[{"name":"sample_id","in":"path","required":true,"schema":{"type":"string","title":"Sample Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Resonance Engine"],"summary":"Delete Voice Sample","description":"Soft-delete a voice sample (mark as inactive).","operationId":"delete_voice_sample_api_resonance_voice_samples__sample_id__delete","parameters":[{"name":"sample_id","in":"path","required":true,"schema":{"type":"string","title":"Sample Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-samples/batch":{"post":{"tags":["Resonance Engine"],"summary":"Add Voice Samples Batch","description":"Add multiple voice samples at once.","operationId":"add_voice_samples_batch_api_resonance_voice_samples_batch_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddVoiceSamplesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-samples/{sample_id}/authentic":{"patch":{"tags":["Resonance Engine"],"summary":"Set Voice Sample Authentic","description":"★本当の声フラグを on/off する.\n\nBrand Memory Compiler Phase 4.5: voice_outline 生成は\nis_authentic_voice=true のサンプルだけを素材にする (AI 生成 / 編集\nサンプルが混じると「妥協」を学習してしまうため)。shop 主が能動的に\n書いた文章だけ ★ を付けることで、Opus が読み解く声の輪郭の純度を\n保つ。","operationId":"set_voice_sample_authentic_api_resonance_voice_samples__sample_id__authentic_patch","parameters":[{"name":"sample_id","in":"path","required":true,"schema":{"type":"string","title":"Sample Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchAuthenticVoiceRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/learning-history":{"get":{"tags":["Resonance Engine"],"summary":"Get Learning History","description":"Get feedback learning history for the current shop.\n\nReturns voice samples filtered to feedback-related source_types,\nordered by newest first. Supports pagination and filtering.","operationId":"get_learning_history_api_resonance_learning_history_get","parameters":[{"name":"source_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/learning-history/stats":{"get":{"tags":["Resonance Engine"],"summary":"Get Learning Stats","description":"Get aggregated learning statistics for the current shop.","operationId":"get_learning_stats_api_resonance_learning_history_stats_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-dna":{"get":{"tags":["Resonance Engine"],"summary":"Get Voice Dna","description":"Get the current Voice DNA for the shop (or synced source).","operationId":"get_voice_dna_api_resonance_voice_dna_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-dna/quota":{"get":{"tags":["Resonance Engine"],"summary":"Get Voice Dna Quota","description":"Voice DNA 分析の当月 quota を返す (UI 表示用)。","operationId":"get_voice_dna_quota_api_resonance_voice_dna_quota_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-dna/preview":{"post":{"tags":["Resonance Engine"],"summary":"Preview Voice Dna","description":"Preview: generate a sample message with and without Voice DNA.\n\nUses a fixed sample order so the owner can compare how Voice DNA\naffects the generated message.\nReturns both versions for side-by-side comparison.","operationId":"preview_voice_dna_api_resonance_voice_dna_preview_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-sync/graph":{"get":{"tags":["Resonance Engine"],"summary":"Get Voice Link Graph","description":"Return the Voice Link graph for all shops owned by the current user.\n\nReturns nodes (shops) with metadata and edges (sync relationships).\nUsed by the Voice Link visualization page (`/dashboard/growth/voice-link`).","operationId":"get_voice_link_graph_api_resonance_voice_sync_graph_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-sync/shops":{"get":{"tags":["Resonance Engine"],"summary":"List Syncable Shops","description":"List other shops owned by the same user that have Voice DNA configured.","operationId":"list_syncable_shops_api_resonance_voice_sync_shops_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-sync":{"post":{"tags":["Resonance Engine"],"summary":"Enable Voice Sync","description":"Enable voice sync: this shop will use another shop's Voice DNA.","operationId":"enable_voice_sync_api_resonance_voice_sync_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSyncRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Resonance Engine"],"summary":"Disable Voice Sync","description":"Disable voice sync: this shop will use its own Voice DNA.","operationId":"disable_voice_sync_api_resonance_voice_sync_delete","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/learning-report":{"get":{"tags":["Resonance Engine"],"summary":"Get Learning Report","description":"Get learning effect report showing monthly feedback accumulation.\n\nReturns monthly breakdown of voice samples by type, programmatically\ngenerated highlights based on feedback patterns, and current Voice DNA settings.","operationId":"get_learning_report_api_resonance_learning_report_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-dna/auto-improve":{"post":{"tags":["Resonance Engine"],"summary":"Generate Auto Improve Suggestions","description":"Generate auto-improvement suggestions using Claude.\n\nAnalyzes negative_feedback and bad_correction samples to suggest\nspecific tone, expression, and content improvements in Japanese.","operationId":"generate_auto_improve_suggestions_api_resonance_voice_dna_auto_improve_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-dna/report":{"get":{"tags":["Resonance Engine"],"summary":"Get Voice Dna Growth Report","description":"Get Voice DNA growth report showing evolution over time.\n\nReturns sample accumulation, feedback trends, milestones,\nand current Voice DNA dimensions.","operationId":"get_voice_dna_growth_report_api_resonance_voice_dna_report_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-dna/learned-rules":{"get":{"tags":["Resonance Engine"],"summary":"Get Learned Rules","description":"Get Voice DNA learned rules — structured view of what soeru has learned.\n\nReturns rules derived from Voice DNA analysis and feedback, organized by\ncategory so the shop owner can see, modify, or delete individual rules.\n\nIf the shop is synced from another shop's Voice DNA (voice_sync_source_id),\npulls the Voice DNA from that source shop so rules stay consistent with the\n/voice-dna endpoint used by the Voice DNA settings page.","operationId":"get_learned_rules_api_resonance_voice_dna_learned_rules_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-dna/learned-rules/{rule_id}":{"patch":{"tags":["Resonance Engine"],"summary":"Update Learned Rule","description":"Update or delete a specific learned rule.\n\nThis modifies the Voice DNA or shop settings directly\nto remove or adjust a specific learned behavior.\n\n**Master-write model**: If this shop is synced from another shop\n(voice_sync_source_id set), edits write to the source (master) shop's\nvoice_dna, so the change propagates to every shop in the sync group.","operationId":"update_learned_rule_api_resonance_voice_dna_learned_rules__rule_id__patch","parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","title":"Rule Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLearnedRuleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/resonance/voice-dna/learned-rules/add-avoid":{"post":{"tags":["Resonance Engine"],"summary":"Add Avoid Expression","description":"Manually add an expression to the avoids list.\n\nMaster-write model: if the shop is synced from another, the avoid is\nadded to the master shop so it propagates to the whole Voice Link group.","operationId":"add_avoid_expression_api_resonance_voice_dna_learned_rules_add_avoid_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLearnedRuleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/templates":{"get":{"tags":["soeru Link"],"summary":"List Templates","description":"List available built-in menu templates.","operationId":"list_templates_api_soeru_link_templates_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/menus":{"get":{"tags":["soeru Link"],"summary":"List Menus","description":"List all marketing menus for the current shop.","operationId":"list_menus_api_soeru_link_menus_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["soeru Link"],"summary":"Create Menu","description":"Create a new marketing menu.","operationId":"create_menu_api_soeru_link_menus_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMenuRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/menus/from-template":{"post":{"tags":["soeru Link"],"summary":"Create Menu From Template","description":"Create a menu from a built-in template.","operationId":"create_menu_from_template_api_soeru_link_menus_from_template_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMenuFromTemplateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/menus/{menu_id}":{"patch":{"tags":["soeru Link"],"summary":"Update Menu","description":"Update a marketing menu.","operationId":"update_menu_api_soeru_link_menus__menu_id__patch","parameters":[{"name":"menu_id","in":"path","required":true,"schema":{"type":"string","title":"Menu Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMenuRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["soeru Link"],"summary":"Delete Menu","description":"Delete a marketing menu (and its rules via CASCADE).","operationId":"delete_menu_api_soeru_link_menus__menu_id__delete","parameters":[{"name":"menu_id","in":"path","required":true,"schema":{"type":"string","title":"Menu Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/menus/reorder":{"post":{"tags":["soeru Link"],"summary":"Reorder Menus","description":"Reorder menus by updating order_position.","operationId":"reorder_menus_api_soeru_link_menus_reorder_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderMenusRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/rules":{"get":{"tags":["soeru Link"],"summary":"List Rules","description":"List display rules, optionally filtered by menu_id.","operationId":"list_rules_api_soeru_link_rules_get","parameters":[{"name":"menu_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Menu Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["soeru Link"],"summary":"Create Rule","description":"Create a display rule for a menu.","operationId":"create_rule_api_soeru_link_rules_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRuleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/rules/{rule_id}":{"patch":{"tags":["soeru Link"],"summary":"Update Rule","description":"Update a display rule.","operationId":"update_rule_api_soeru_link_rules__rule_id__patch","parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","title":"Rule Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRuleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["soeru Link"],"summary":"Delete Rule","description":"Delete a display rule.","operationId":"delete_rule_api_soeru_link_rules__rule_id__delete","parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","title":"Rule Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/generate-codes":{"post":{"tags":["soeru Link"],"summary":"Generate Codes","description":"Generate soeru Link codes for a batch of orders.","operationId":"generate_codes_api_soeru_link_generate_codes_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateCodesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/analytics":{"get":{"tags":["soeru Link"],"summary":"Analytics","description":"Get soeru Link analytics for the shop.","operationId":"analytics_api_soeru_link_analytics_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/page":{"get":{"tags":["soeru Link Blocks"],"summary":"Get Editor Page","description":"Get the page with all blocks for the editor. Auto-creates if needed.\nAlways uses the primary shop's page (shared across all shops).","operationId":"get_editor_page_api_soeru_link_page_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["soeru Link Blocks"],"summary":"Update Page","description":"Update page-level settings.","operationId":"update_page_api_soeru_link_page_patch","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePageSettingsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/blocks":{"post":{"tags":["soeru Link Blocks"],"summary":"Create New Block","description":"Create a new block on the page.","operationId":"create_new_block_api_soeru_link_blocks_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBlockRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/blocks/from-template":{"post":{"tags":["soeru Link Blocks"],"summary":"Create Block Template","description":"Create a block from a template.","operationId":"create_block_template_api_soeru_link_blocks_from_template_post","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBlockFromTemplateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/blocks/reorder":{"patch":{"tags":["soeru Link Blocks"],"summary":"Reorder Page Blocks","description":"Reorder blocks on the page.","operationId":"reorder_page_blocks_api_soeru_link_blocks_reorder_patch","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderBlocksRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/blocks/{block_id}":{"patch":{"tags":["soeru Link Blocks"],"summary":"Update Existing Block","description":"Update a block's data, enabled state, or platform visibility.","operationId":"update_existing_block_api_soeru_link_blocks__block_id__patch","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBlockRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["soeru Link Blocks"],"summary":"Delete Existing Block","description":"Delete a block.","operationId":"delete_existing_block_api_soeru_link_blocks__block_id__delete","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/blocks/{block_id}/rules":{"get":{"tags":["soeru Link Blocks"],"summary":"Get Rules","description":"Get display rules for a block.","operationId":"get_rules_api_soeru_link_blocks__block_id__rules_get","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["soeru Link Blocks"],"summary":"Add Rule","description":"Add a display rule to a block.","operationId":"add_rule_api_soeru_link_blocks__block_id__rules_post","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBlockRuleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/blocks/{block_id}/rules/{rule_id}":{"delete":{"tags":["soeru Link Blocks"],"summary":"Remove Rule","description":"Delete a block rule.","operationId":"remove_rule_api_soeru_link_blocks__block_id__rules__rule_id__delete","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","title":"Rule Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/blocks/{block_id}/sync":{"post":{"tags":["soeru Link Blocks"],"summary":"Sync Block","description":"Sync a block to other shops.","operationId":"sync_block_api_soeru_link_blocks__block_id__sync_post","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncBlockRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["soeru Link Blocks"],"summary":"Remove Sync","description":"Remove a block from its sync group.","operationId":"remove_sync_api_soeru_link_blocks__block_id__sync_delete","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/blocks/{block_id}/sync-status":{"get":{"tags":["soeru Link Blocks"],"summary":"Get Block Sync Status","description":"Get sync status for a block.","operationId":"get_block_sync_status_api_soeru_link_blocks__block_id__sync_status_get","parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","title":"Block Id"}},{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/soeru-link/block-templates":{"get":{"tags":["soeru Link Blocks"],"summary":"List Block Templates","description":"List all available block templates, organized by category.","operationId":"list_block_templates_api_soeru_link_block_templates_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional shop ID","title":"X-Shop-Id"},"description":"Optional shop ID"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/link/{code}":{"get":{"tags":["Public"],"summary":"Get Link Page","description":"Get the soeru Link landing page data for a customer.\n\nThis is the main public endpoint — no authentication required.\nCalled when a customer scans the QR code on their packing slip.\n\nRate limit: 30 requests per minute per IP.","operationId":"get_link_page_api_public_link__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/link/{code}/click":{"post":{"tags":["Public"],"summary":"Record Link Click","description":"Record a click event when a customer taps a menu item.\n\nNo authentication required — called from the public landing page.\nRate limit: 60 requests per minute per IP.","operationId":"record_link_click_api_public_link__code__click_post","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClickRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/link/{code}/feedback":{"post":{"tags":["Public"],"summary":"Submit Link Feedback","description":"Record customer feedback (Good/Bad) from the QR landing page.\n\nNo authentication required — called from the public landing page.\nRate limit: 10 requests per minute per IP.","operationId":"submit_link_feedback_api_public_link__code__feedback_post","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/routers__public__FeedbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/support/conversations":{"post":{"tags":["Support"],"summary":"Create Conversation","description":"Create a new support conversation.","operationId":"create_conversation_api_v1_support_conversations_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Support"],"summary":"Get Conversations","description":"Get user's support conversations.","operationId":"get_conversations_api_v1_support_conversations_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/support/chat":{"post":{"tags":["Support"],"summary":"Send Chat Message","description":"Send a message to the support chat and get an AI response.","operationId":"send_chat_message_api_v1_support_chat_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/support/conversations/{conversation_id}":{"get":{"tags":["Support"],"summary":"Get Conversation Messages","description":"Get messages for a specific conversation.","operationId":"get_conversation_messages_api_v1_support_conversations__conversation_id__get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/support/feature-requests":{"post":{"tags":["Support"],"summary":"Create Feature Request","description":"Submit a feature request.","operationId":"create_feature_request_api_v1_support_feature_requests_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Support"],"summary":"Get Feature Requests","description":"Get user's feature requests.","operationId":"get_feature_requests_api_v1_support_feature_requests_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/knowledge":{"get":{"tags":["Brand Knowledge"],"summary":"List Brand Knowledge","description":"List brand knowledge. If status is omitted, returns all non-archived items.","operationId":"list_brand_knowledge_api_v1_shops__shop_id__knowledge_get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/knowledge/manual":{"post":{"tags":["Brand Knowledge"],"summary":"Add Knowledge Manual","description":"Add brand knowledge via manual text input.","operationId":"add_knowledge_manual_api_v1_shops__shop_id__knowledge_manual_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddKnowledgeManual"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/knowledge/url/preview":{"post":{"tags":["Brand Knowledge"],"summary":"Preview Url Summary","description":"Step 1: Fetch URL and return AI summary for user review (does NOT save).","operationId":"preview_url_summary_api_v1_shops__shop_id__knowledge_url_preview_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewURLRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/knowledge/url/confirm":{"post":{"tags":["Brand Knowledge"],"summary":"Confirm Url Knowledge","description":"Step 2: Save the (optionally edited) URL summary.","operationId":"confirm_url_knowledge_api_v1_shops__shop_id__knowledge_url_confirm_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmURLRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/knowledge/url":{"post":{"tags":["Brand Knowledge"],"summary":"Add Knowledge From Url","description":"Direct URL → save (Phase 1a-iii: 非同期化, 即 202 + 完了通知).\n\nUX 改善: URL summarize + brand_knowledge insert は LLM call を含む\nため 5-30 秒待ちになる. ユーザーを待たせず即 202 を返し、background\ntask で処理 + 完了で右上ベル通知 (1a-i で配線済).","operationId":"add_knowledge_from_url_api_v1_shops__shop_id__knowledge_url_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewURLRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/knowledge/{knowledge_id}":{"put":{"tags":["Brand Knowledge"],"summary":"Update Knowledge","operationId":"update_knowledge_api_v1_shops__shop_id__knowledge__knowledge_id__put","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateKnowledge"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Brand Knowledge"],"summary":"Delete Knowledge","operationId":"delete_knowledge_api_v1_shops__shop_id__knowledge__knowledge_id__delete","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/knowledge/batch-approve":{"post":{"tags":["Brand Knowledge"],"summary":"Batch Approve","description":"Approve multiple pending knowledge items at once.","operationId":"batch_approve_api_v1_shops__shop_id__knowledge_batch_approve_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Ids"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/knowledge/batch-reject":{"post":{"tags":["Brand Knowledge"],"summary":"Batch Reject","description":"Reject multiple pending knowledge items.","operationId":"batch_reject_api_v1_shops__shop_id__knowledge_batch_reject_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Ids"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources":{"get":{"tags":["Brand Knowledge"],"summary":"List Sources","description":"List registered URL sources for this shop, plus Voice-Link-shared API\nsources inherited from the linked parent.\n\nThe response includes two kinds of rows:\n\n* **Own sources** — rows where ``shop_id`` matches. No annotation.\n* **Shared sources** — API-typed rows (``shopify-api://`` /\n  ``rakuten-api://``) owned by the Voice-Link parent that this shop\n  inherits from. Annotated with ``shared_from_shop_id`` and\n  ``shared_from_shop_name`` so the UI can render a \"共有中\" badge.\n\nWeb-based rows from the parent are intentionally *not* merged: each\nchild may have its own LP/blog, and we only want API canonical data\n(products, collections, shop metafields) to propagate via Voice Link.","operationId":"list_sources_api_v1_shops__shop_id__sources_get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Brand Knowledge"],"summary":"Add Source","description":"Register a new URL source for periodic crawling.","operationId":"add_source_api_v1_shops__shop_id__sources_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddSourceRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/{source_id}":{"put":{"tags":["Brand Knowledge"],"summary":"Update Source","operationId":"update_source_api_v1_shops__shop_id__sources__source_id__put","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSourceRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Brand Knowledge"],"summary":"Delete Source","operationId":"delete_source_api_v1_shops__shop_id__sources__source_id__delete","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}},{"name":"delete_data","in":"query","required":false,"schema":{"type":"boolean","description":"Also delete learned entries","default":false,"title":"Delete Data"},"description":"Also delete learned entries"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/entries/by-label":{"delete":{"tags":["Brand Knowledge"],"summary":"Delete Entries By Label","description":"Delete orphaned brand_knowledge entries by source_label.\n\nUsed to clean up entries from previously deleted sources, e.g.\nlabel=\"[削除] 公式オンラインストア\".","operationId":"delete_entries_by_label_api_v1_shops__shop_id__entries_by_label_delete","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"label","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"source_label to match","title":"Label"},"description":"source_label to match"},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/entries/bulk":{"post":{"tags":["Brand Knowledge"],"summary":"Bulk Entries Action","description":"Bulk exclude / restore / delete entries filtered by source.\n\n- action=exclude  → set is_active=false\n- action=restore  → set is_active=true\n- action=delete   → permanently delete rows","operationId":"bulk_entries_action_api_v1_shops__shop_id__entries_bulk_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkEntriesAction"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/{source_id}/crawl-now":{"post":{"tags":["Brand Knowledge"],"summary":"Crawl Source Now","description":"Manually trigger a crawl for a specific source.","operationId":"crawl_source_now_api_v1_shops__shop_id__sources__source_id__crawl_now_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/preview-deep":{"post":{"tags":["Brand Knowledge"],"summary":"Preview Deep Snapshot","description":"Plan a deep snapshot crawl and return page list + cost/time estimates.\n\nThis does NOT write anything or call Haiku. It's the backend half of\nthe owner's confirm dialog — the UI shows estimated pages, cost and\nduration before the owner kicks off the real run.","operationId":"preview_deep_snapshot_api_v1_shops__shop_id__sources_preview_deep_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeepPreviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/snapshot":{"post":{"tags":["Brand Knowledge"],"summary":"Register And Run Snapshot","description":"Register a Snapshot source and immediately run the deep crawl.\n\nPhase 3 path: skips Phase 2's summarize-on-save and uses the multi-page\nrunner instead. The runner writes N rows (not just 1) with per-subpage\nprovenance.","operationId":"register_and_run_snapshot_api_v1_shops__shop_id__sources_snapshot_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterSnapshotRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/monitor":{"post":{"tags":["Brand Knowledge"],"summary":"Register Monitor Source","description":"Register a Monitor source (RSS/blog index) for periodic re-checks.\n\nMonitor mode is implemented in Phase D (RSS parser + HTML blog index).\nFor now this endpoint registers the row so the UI can list it, but\nactual incremental crawls are handled by the Phase D scheduler.","operationId":"register_monitor_source_api_v1_shops__shop_id__sources_monitor_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterMonitorRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/{source_id}/status":{"get":{"tags":["Brand Knowledge"],"summary":"Get Source Status","description":"Lightweight poll endpoint for background crawl progress.\n\nVoice-Link-aware: if the source isn't owned by this shop but is\nreachable via Voice Link (tri-path), return the owner's status row\nso relearn polling on a shared source doesn't 404 and leave the UI\nspinner stuck. The requesting user must still own ``shop_id``.","operationId":"get_source_status_api_v1_shops__shop_id__sources__source_id__status_get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/detect":{"post":{"tags":["Brand Knowledge"],"summary":"Detect Source","description":"Auto-detect whether a URL is best handled as Snapshot or Monitor.","operationId":"detect_source_api_v1_shops__shop_id__sources_detect_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/{source_id}/pause":{"post":{"tags":["Brand Knowledge"],"summary":"Pause Source","description":"Pause a source: keep row + history but stop scheduled runs.","operationId":"pause_source_api_v1_shops__shop_id__sources__source_id__pause_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/{source_id}/resume":{"post":{"tags":["Brand Knowledge"],"summary":"Resume Source","description":"Resume a paused source.","operationId":"resume_source_api_v1_shops__shop_id__sources__source_id__resume_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/{source_id}/relearn":{"post":{"tags":["Brand Knowledge"],"summary":"Relearn Source","description":"Re-run a Snapshot source's deep crawl.\n\nFor snapshot sources, this replays the multi-page extraction. Existing\nitems stay (content_hash dedup prevents duplicates) — only genuinely new\ncontent is added.\n\nVoice-Link-aware: if the source is NOT owned by this shop but is\nreachable via Voice Link (tri-path own/parent/children), the crawl is\nrun against the owner's shop_id so the refreshed brand_knowledge rows\nland on the owner and propagate to every Voice-Link sibling through\nthe shared-entries merge in ``list_sources`` / ``/entries`` /\n``/sources/graph``. We still verify the *requesting* user owns\n``shop_id`` — the Voice-Link link is what authorises cross-shop\nrefresh, not a blanket IDOR bypass.","operationId":"relearn_source_api_v1_shops__shop_id__sources__source_id__relearn_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/connectors":{"get":{"tags":["Brand Knowledge"],"summary":"List Source Connectors","description":"Return connection + brand-learning state for each platform adapter.\n\nThe UI uses this to render the compact \"Shopify\" / \"楽天\" cards next\nto \"Web から学習\". Per platform we expose:\n\n* ``credentials_connected`` — whether ``shop_settings`` has the creds\n  needed to call the platform API. If false, the UI nudges the user\n  to the API-settings page.\n* ``source`` — the already-registered platform brand-learning source,\n  if any (null means \"creds present but not activated yet\").\n* ``api_first_enabled`` — global feature flag. When false, the cards\n  surface \"準備中\" instead of the activation CTA.","operationId":"list_source_connectors_api_v1_shops__shop_id__sources_connectors_get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/connectors/{platform}/connect":{"post":{"tags":["Brand Knowledge"],"summary":"Connect Source Connector","description":"Register a platform API brand-learning source + run initial snapshot.\n\nIdempotent: calling this on an already-connected platform returns the\nexisting source row and re-runs the snapshot (same semantics as\n``/sources/{id}/relearn`` but looked up by platform name so the UI\ndoesn't need to track source IDs).","operationId":"connect_source_connector_api_v1_shops__shop_id__sources_connectors__platform__connect_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"platform","in":"path","required":true,"schema":{"type":"string","title":"Platform"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/connectors/{platform}/sync":{"post":{"tags":["Brand Knowledge"],"summary":"Sync Source Connector","description":"Re-sync an already-connected platform source.\n\nThin wrapper over ``run_snapshot`` that looks up the source row by\nplatform name. Useful for the \"今すぐ同期\" button in the connector\nmodal so the UI doesn't need to track source IDs per platform.","operationId":"sync_source_connector_api_v1_shops__shop_id__sources_connectors__platform__sync_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"platform","in":"path","required":true,"schema":{"type":"string","title":"Platform"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/graph":{"get":{"tags":["Brand Knowledge"],"summary":"Get Sources Graph","description":"Return graph data for the Voice Link-style source map.\n\nEach source becomes a node; each brand_knowledge row becomes a leaf\nattached to its parent source (or the 'manual' pseudo-node). The\nfrontend renders this as a radial SVG graph.","operationId":"get_sources_graph_api_v1_shops__shop_id__sources_graph_get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/sources/migrate-legacy":{"post":{"tags":["Brand Knowledge"],"summary":"Migrate Legacy Sources","description":"Backfill source_kind for legacy sources that pre-date the deep crawl redesign.\n\nLegacy sources (source_kind IS NULL) get auto-detected or default to 'snapshot'.\nThis is idempotent — running it multiple times is safe.","operationId":"migrate_legacy_sources_api_v1_shops__shop_id__sources_migrate_legacy_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/profile":{"get":{"tags":["Brand Knowledge"],"summary":"Get Brand Profile Phase2","description":"Return the 5 manual V/M/V/C/Story fields for this shop.\n\nMissing fields are returned as None so the UI can render empty inputs.\nExcluded rows (is_active=false) are also returned as None from this\nendpoint — the owner's editing surface should only reflect live entries.","operationId":"get_brand_profile_phase2_api_v1_shops__shop_id__profile_get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/profile/{field}":{"put":{"tags":["Brand Knowledge"],"summary":"Upsert Brand Profile Field","description":"Upsert a single V/M/V/C/Story field. Empty text deletes the entry.","operationId":"upsert_brand_profile_field_api_v1_shops__shop_id__profile__field__put","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"field","in":"path","required":true,"schema":{"type":"string","title":"Field"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertManualField"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/profile/peer-preview":{"get":{"tags":["Brand Knowledge"],"summary":"Brand Profile Peer Preview","description":"Voice Link 相手のブランドの核 (V/M/V/C/Story) を差分プレビュー用に返す。\n\nVoice Link が張られていない場合は ``peer=None`` を返して UI で CTA を\n隠すだけ (エラーにしない)。張られている場合は相手の profile を同梱し、\nモーダルで項目別 diff を描けるようにする。","operationId":"brand_profile_peer_preview_api_v1_shops__shop_id__profile_peer_preview_get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/profile/import-from-peer":{"post":{"tags":["Brand Knowledge"],"summary":"Brand Profile Import From Peer","description":"Voice Link 相手のブランドの核を選択取り込みする。\n\n- ``fields``: 取り込む MANUAL_FIELDS の配列 (空配列なら no-op)\n- ``overwrite``: true で自 shop の既入力フィールドも上書き、false で空欄のみ埋める","operationId":"brand_profile_import_from_peer_api_v1_shops__shop_id__profile_import_from_peer_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportFromPeerBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/profile/clear-share":{"post":{"tags":["Brand Knowledge"],"summary":"Brand Profile Clear Share","description":"「独立させる」— 指定フィールドの Voice Link 取り込み注釈だけ消す。\n\ntext / summary は保持したまま、shared_from_shop_id/name/synced_at を\nNULL に戻す。以降このフィールドは自 shop のオリジナルとして扱われる。","operationId":"brand_profile_clear_share_api_v1_shops__shop_id__profile_clear_share_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClearShareBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/entries":{"get":{"tags":["Brand Knowledge"],"summary":"List Learned Entries","description":"Return all entries (both manual and crawled) for the learned-entries\ndashboard, with provenance tags ready for UI rendering.\n\nThe response includes:\n  - ``entries``: up to ``limit`` rows, ordered ``fetched_at DESC`` with\n    a layer-priority tiebreak so deep-inference rows (worldview /\n    negative / stance) surface first within each crawl batch.\n  - ``total``: the true server-side filtered count (not truncated by\n    ``limit``). UI uses this for the \"全 N 件\" display.\n  - ``truncated``: boolean indicating whether ``total > len(entries)``.","operationId":"list_learned_entries_api_v1_shops__shop_id__entries_get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"layer","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"fact | essence | worldview | negative | stance","title":"Layer"},"description":"fact | essence | worldview | negative | stance"},{"name":"source_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"manual | website | sns","title":"Source Type"},"description":"manual | website | sns"},{"name":"include_inactive","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Inactive"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"default":500,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/shops/{shop_id}/entries/{entry_id}/active":{"patch":{"tags":["Brand Knowledge"],"summary":"Set Entry Active","description":"Toggle the is_active flag. Inactive entries are kept for audit but\nnever injected into message generation prompts.","operationId":"set_entry_active_api_v1_shops__shop_id__entries__entry_id__active_patch","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetActiveBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bootstrap":{"get":{"tags":["Bootstrap"],"summary":"Get Bootstrap Data","description":"Get all initial data for dashboard in a single request.\n\nReturns:\n    {\n        \"shops\": [...],\n        \"active_shop_id\": \"...\",\n        \"dashboard\": { ... },      # may be null if no shops\n        \"settings\": { ... },        # may be null if no shops\n    }","operationId":"get_bootstrap_data_api_bootstrap_get","parameters":[{"name":"x-shop-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Shop-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pulse/command":{"post":{"tags":["Pulse Guard"],"summary":"Slack Slash Command","description":"Slack Slash Command receiver.\n\nSlack sends `application/x-www-form-urlencoded`. We must respond\nwithin 3 seconds or Slack shows a timeout error — so read-only\nactions run inline and long-running actions return a staged message.","operationId":"slack_slash_command_api_pulse_command_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/brands/{brand_id}/value-hypothesis":{"get":{"tags":["Value Hypothesis"],"summary":"Get Value Hypothesis","description":"Brand の active な value_hypothesis を返す。未 seed の場合は seed: False で空を返す。","operationId":"get_value_hypothesis_api_v1_brands__brand_id__value_hypothesis_get","parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","title":"Brand Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/brands/{brand_id}/value-hypothesis/evolution":{"get":{"tags":["Value Hypothesis"],"summary":"List Hypothesis Evolution","description":"Brand の仮説進化ログ(新しい順)。","operationId":"list_hypothesis_evolution_api_v1_brands__brand_id__value_hypothesis_evolution_get","parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","title":"Brand Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/brands":{"get":{"tags":["Value Hypothesis"],"summary":"List My Brands","description":"Current user が owner の brands 一覧(UI のブランドセレクタ用)。","operationId":"list_my_brands_api_v1_brands_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/announcements":{"get":{"tags":["Announcements"],"summary":"List Public Announcements","description":"List published announcements visible on soeru.biz.\n\nRate limit: 60 req/min/IP. Returns at most `limit` rows (1..50).","operationId":"list_public_announcements_api_public_announcements_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","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"}}}}}}},"/api/public/announcements/{slug}":{"get":{"tags":["Announcements"],"summary":"Get Public Announcement","description":"Return a single published announcement by slug.","operationId":"get_public_announcement_api_public_announcements__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/announcements/active":{"get":{"tags":["Announcements"],"summary":"List Active For Dashboard","description":"Current banner announcements for the logged-in dashboard (max 3).","operationId":"list_active_for_dashboard_api_announcements_active_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/announcements":{"get":{"tags":["Announcements (Admin)"],"summary":"List Admin Announcements","description":"List all announcements (draft/published/archived) for admin CMS.","operationId":"list_admin_announcements_api_admin_announcements_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Announcements (Admin)"],"summary":"Create Announcement","description":"Create a new draft announcement.","operationId":"create_announcement_api_admin_announcements_post","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnnouncementRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/announcements/templates":{"get":{"tags":["Announcements (Admin)"],"summary":"List Admin Templates","description":"Return announcement templates seeded in migration 063.\n\n2026-04-25 fix: ordered by 'severity' which doesn't exist in the table\n(actual column is 'default_severity'). Supabase returned 500. Switch to\nordering by 'key' for stable, deterministic listing. Also normalize the\nfield shape to match the frontend Template interface (slug/title/body_md).","operationId":"list_admin_templates_api_admin_announcements_templates_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/announcements/{announcement_id}":{"get":{"tags":["Announcements (Admin)"],"summary":"Get Admin Announcement","description":"Fetch a single announcement (including drafts/archived) for admin edit.","operationId":"get_admin_announcement_api_admin_announcements__announcement_id__get","parameters":[{"name":"announcement_id","in":"path","required":true,"schema":{"type":"string","title":"Announcement Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Announcements (Admin)"],"summary":"Update Announcement","description":"Update an announcement in place (edits propagate on next cache refresh).","operationId":"update_announcement_api_admin_announcements__announcement_id__patch","parameters":[{"name":"announcement_id","in":"path","required":true,"schema":{"type":"string","title":"Announcement Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAnnouncementRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/announcements/{announcement_id}/publish":{"post":{"tags":["Announcements (Admin)"],"summary":"Publish Announcement","description":"Flip status to 'published'. `published_at` is set by DB trigger.","operationId":"publish_announcement_api_admin_announcements__announcement_id__publish_post","parameters":[{"name":"announcement_id","in":"path","required":true,"schema":{"type":"string","title":"Announcement Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/announcements/{announcement_id}/archive":{"post":{"tags":["Announcements (Admin)"],"summary":"Archive Announcement","description":"Flip status to 'archived' — hides from public/admin banner.","operationId":"archive_announcement_api_admin_announcements__announcement_id__archive_post","parameters":[{"name":"announcement_id","in":"path","required":true,"schema":{"type":"string","title":"Announcement Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brands":{"get":{"tags":["Brands"],"summary":"List Brands","description":"owner の active brands 一覧 + 現在の plan (primary brand 基準) を返す。\n\nフロント /dashboard/settings/brands ページで brand 一覧と plan バッジを\n描画するために使う。","operationId":"list_brands_api_brands_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brands/{brand_id}":{"patch":{"tags":["Brands"],"summary":"Rename Brand","description":"ブランド名を変更。owner 認証 + 同名衝突チェック。","operationId":"rename_brand_api_brands__brand_id__patch","parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","title":"Brand Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brands/{brand_id}/archive":{"post":{"tags":["Brands"],"summary":"Archive Brand","description":"ブランドを archive する。14 日後に cron が物理削除。\n\n制約:\n  - primary brand (owner の最古 active brand) は archive 不可\n  - archive 時、紐付く Stripe Subscription は cancel_at_period_end で\n    予約キャンセル (月末まで使える、自動課金停止)","operationId":"archive_brand_api_brands__brand_id__archive_post","parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","title":"Brand Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brands/{brand_id}/restore":{"post":{"tags":["Brands"],"summary":"Restore Brand","description":"archive 期間中 (14日以内) に復活させる。\n\narchive 時に Stripe sub は cancel_at_period_end=True (= 月末まで使える)\nにしていたので、restore では cancel_at_period_end=False に戻すことで\nサブスクをそのまま継続させる。月を跨いでいなければ課金・利用に影響なし。","operationId":"restore_brand_api_brands__brand_id__restore_post","parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","title":"Brand Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["MCP OAuth"],"summary":"Authorization Server Metadata","operationId":"authorization_server_metadata__well_known_oauth_authorization_server_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/oauth-protected-resource/mcp":{"get":{"tags":["MCP OAuth"],"summary":"Protected Resource Metadata","operationId":"protected_resource_metadata__well_known_oauth_protected_resource_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/register":{"post":{"tags":["MCP OAuth"],"summary":"Register Client","operationId":"register_client_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/authorize":{"get":{"tags":["MCP OAuth"],"summary":"Authorize Get","operationId":"authorize_get_authorize_get","parameters":[{"name":"response_type","in":"query","required":false,"schema":{"type":"string","default":"code","title":"Response Type"}},{"name":"client_id","in":"query","required":false,"schema":{"type":"string","default":"","title":"Client Id"}},{"name":"redirect_uri","in":"query","required":false,"schema":{"type":"string","default":"","title":"Redirect Uri"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"","title":"Scope"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"","title":"State"}},{"name":"code_challenge","in":"query","required":false,"schema":{"type":"string","default":"","title":"Code Challenge"}},{"name":"code_challenge_method","in":"query","required":false,"schema":{"type":"string","default":"S256","title":"Code Challenge Method"}},{"name":"resource","in":"query","required":false,"schema":{"type":"string","default":"","title":"Resource"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["MCP OAuth"],"summary":"Authorize Post","operationId":"authorize_post_authorize_post","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_authorize_post_authorize_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/token":{"post":{"tags":["MCP OAuth"],"summary":"Token Endpoint","operationId":"token_endpoint_token_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_token_endpoint_token_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mcp/connection-status":{"get":{"tags":["MCP Status","MCP Status"],"summary":"Connection Status","description":"このユーザーが自分の AI を MCP 接続済みかを返す。\n\n非失効 (revoked_at IS NULL) のトークンが 1 件でもあれば接続済みとみなす。\naccess トークンは 1h で失効するが refresh は残るため、失効していなければ\n「接続継続中」と判定できる。\nReturns: {\"connected\": bool, \"connected_at\"?: str, \"client_id\"?: str}","operationId":"connection_status_api_mcp_connection_status_get","parameters":[{"name":"authorization","in":"header","required":true,"schema":{"type":"string","description":"Bearer <token>","title":"Authorization"},"description":"Bearer <token>"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Connection Status Api Mcp Connection Status Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Shopify App Launch","description":"Handle Shopify app launch redirect.\n\nWhen a Shopify merchant opens the soeru app from their admin panel,\nShopify sends them here. We redirect to the soeru frontend dashboard.\nIf an OAuth token hasn't been obtained yet, the frontend's API settings\npage will guide them through the connection flow.","operationId":"shopify_app_launch__get","parameters":[{"name":"shop","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop"}},{"name":"hmac","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hmac"}},{"name":"host","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host"}},{"name":"timestamp","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timestamp"}},{"name":"session","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health":{"get":{"summary":"Health Check","description":"Health check endpoint — verifies API, DB, and encryption.","operationId":"health_check_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/health/encryption":{"get":{"summary":"Encryption Health Check","description":"Check decryption health across all shops.","operationId":"encryption_health_check_api_health_encryption_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health/breakers":{"get":{"summary":"Breakers Health","description":"Snapshot of every registered circuit breaker.\n\nIntended for ops dashboards + manual oncall checks. Returns the\nstate (closed / open / half_open), failure counters, and last\nfailure reason so we can tell at a glance whether any upstream\ndependency is currently degraded on this process.\n\nNote: state is per-process. With multiple uvicorn workers you'll\nsee one entry per worker; that's intentional (see breaker.py).","operationId":"breakers_health_api_health_breakers_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/snapshots/{shop_id}":{"get":{"summary":"List Snapshots","description":"List recent snapshots for a shop.","operationId":"list_snapshots_api_admin_snapshots__shop_id__get","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/snapshots/{shop_id}/restore":{"post":{"summary":"Restore Snapshot","description":"Restore shop settings from a snapshot.","operationId":"restore_snapshot_api_admin_snapshots__shop_id__restore_post","parameters":[{"name":"shop_id","in":"path","required":true,"schema":{"type":"string","title":"Shop Id"}},{"name":"snapshot_id","in":"query","required":true,"schema":{"type":"string","title":"Snapshot Id"}},{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/rotate-encryption":{"post":{"summary":"Rotate Encryption Keys","description":"Re-encrypt all shop credentials with the current ENCRYPTION_KEY.\n\nRequires ENCRYPTION_KEY_PREVIOUS to be set so old data can be decrypted.\nEach shop's encrypted fields are decrypted (using old or new key) and\nre-encrypted with the current key.","operationId":"rotate_encryption_keys_api_admin_rotate_encryption_post","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AcceptTermsRequest":{"properties":{"terms_version":{"type":"string","maxLength":32,"title":"Terms Version","default":"1.0"}},"type":"object","title":"AcceptTermsRequest"},"AddBlockRuleRequest":{"properties":{"rule_type":{"type":"string","title":"Rule Type"},"condition":{"additionalProperties":true,"type":"object","title":"Condition"}},"type":"object","required":["rule_type","condition"],"title":"AddBlockRuleRequest"},"AddBrandRequest":{"properties":{"brand_name":{"type":"string","maxLength":100,"minLength":1,"title":"Brand Name"},"payment_method_id":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Payment Method Id"},"billing_cycle":{"type":"string","pattern":"^(monthly|annual)$","title":"Billing Cycle","default":"monthly"}},"type":"object","required":["brand_name"],"title":"AddBrandRequest"},"AddKnowledgeManual":{"properties":{"summary":{"type":"string","maxLength":2000,"minLength":5,"title":"Summary"},"category":{"type":"string","title":"Category","default":"brand"},"original_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Original Text"},"use_level":{"type":"string","title":"Use Level","default":"standard"}},"type":"object","required":["summary"],"title":"AddKnowledgeManual"},"AddSourceRequest":{"properties":{"url":{"type":"string","maxLength":2000,"minLength":10,"title":"Url"},"label":{"type":"string","title":"Label","default":""},"source_type":{"type":"string","title":"Source Type","default":"website"},"crawl_frequency":{"type":"string","title":"Crawl Frequency","default":"weekly"},"default_category":{"type":"string","title":"Default Category","default":"brand"}},"type":"object","required":["url"],"title":"AddSourceRequest","description":"Register a URL source for periodic crawling."},"AddVoiceSampleRequest":{"properties":{"sample_text":{"type":"string","title":"Sample Text"},"source_type":{"type":"string","title":"Source Type","default":"manual"}},"type":"object","required":["sample_text"],"title":"AddVoiceSampleRequest","description":"Add a voice sample for Voice DNA learning."},"AddVoiceSamplesRequest":{"properties":{"samples":{"items":{"$ref":"#/components/schemas/AddVoiceSampleRequest"},"type":"array","title":"Samples"}},"type":"object","required":["samples"],"title":"AddVoiceSamplesRequest","description":"Add multiple voice samples at once."},"ApplyTemplateRequest":{"properties":{"template_id":{"type":"string","title":"Template Id"}},"type":"object","required":["template_id"],"title":"ApplyTemplateRequest"},"AuthStartRequest":{"properties":{"frontend_origin":{"type":"string","title":"Frontend Origin","default":""}},"type":"object","title":"AuthStartRequest"},"AutoRuleToggleRequest":{"properties":{"shop_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"},"key":{"type":"string","title":"Key","description":"切替するルール (推奨 5 件): customer_scene_assumption_forbidden / customer_intent_declaration_forbidden / vocabulary_matches_product_context / closing_must_express_gratitude / number_recall_forbidden"},"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["key","enabled"],"title":"AutoRuleToggleRequest"},"B2BDocumentRequest":{"properties":{"document_types":{"items":{"type":"string","enum":["packing_slip","invoice","receipt","quotation"]},"type":"array","title":"Document Types","description":"グローバルの帳票タイプ（注文別指定がない場合のフォールバック）","default":["packing_slip"]},"orders":{"items":{"additionalProperties":true,"type":"object"},"type":"array","minItems":1,"title":"Orders","description":"注文データ配列。各注文は document_types を含めることが可能"},"include_ai_message":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Include Ai Message"}},"type":"object","required":["orders"],"title":"B2BDocumentRequest","description":"B2B帳票生成リクエスト — 注文別帳票タイプ選択対応.\n\norders: 注文データ配列。各注文は document_types フィールドを含めることが可能。\ndocument_types: グローバルのフォールバック（注文に個別指定がない場合に使用）\ninclude_ai_message: AIメッセージを含めるか（設定のオーバーライド用）"},"B2BSettingsUpdate":{"properties":{"shopify_b2b_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Shopify B2B Enabled"},"shopify_b2b_ai_message":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Shopify B2B Ai Message"},"invoice_registration_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Registration Number"},"invoice_payment_terms":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Payment Terms"},"invoice_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Notes"},"stamp_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stamp Image"},"stamp_width_cm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Stamp Width Cm"},"stamp_position_top_cm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Stamp Position Top Cm"},"stamp_position_right_cm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Stamp Position Right Cm"},"bank_transfer_info":{"anyOf":[{"$ref":"#/components/schemas/BankTransferInfo"},{"type":"null"}]},"b2b_addressee_format":{"anyOf":[{"type":"string","enum":["company_name_御中","company_name_person_様","person_様"]},{"type":"null"}],"title":"B2B Addressee Format"},"quotation_validity_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Quotation Validity Days"}},"type":"object","title":"B2BSettingsUpdate","description":"B2B設定更新リクエスト"},"BackfillRequest":{"properties":{"shop_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Shop Id"}},"type":"object","title":"BackfillRequest"},"BankTransferInfo":{"properties":{"bank_name":{"type":"string","title":"Bank Name","default":""},"branch_name":{"type":"string","title":"Branch Name","default":""},"account_type":{"type":"string","enum":["普通","当座"],"title":"Account Type","default":"普通"},"account_number":{"type":"string","title":"Account Number","default":""},"account_holder":{"type":"string","title":"Account Holder","default":""}},"type":"object","title":"BankTransferInfo","description":"振込先情報"},"BatchGenerateRequest":{"properties":{"orders":{"items":{"$ref":"#/components/schemas/GenerateRequest"},"type":"array","maxItems":200,"minItems":1,"title":"Orders"},"restore_only":{"type":"boolean","title":"Restore Only","default":false}},"type":"object","required":["orders"],"title":"BatchGenerateRequest"},"BillingProfile":{"properties":{"billing_company_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Billing Company Name"},"billing_contact_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Billing Contact Name"},"billing_postal_code":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Billing Postal Code"},"billing_address":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Billing Address"},"billing_phone":{"anyOf":[{"type":"string","maxLength":30},{"type":"null"}],"title":"Billing Phone"}},"type":"object","title":"BillingProfile","description":"請求情報のリクエスト/レスポンス共通モデル。全フィールド任意。"},"Body_authorize_post_authorize_post":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"},"response_type":{"type":"string","title":"Response Type","default":"code"},"client_id":{"type":"string","title":"Client Id"},"redirect_uri":{"type":"string","title":"Redirect Uri"},"scope":{"type":"string","title":"Scope","default":""},"state":{"type":"string","title":"State","default":""},"code_challenge":{"type":"string","title":"Code Challenge"},"code_challenge_method":{"type":"string","title":"Code Challenge Method","default":"S256"},"resource":{"type":"string","title":"Resource","default":""}},"type":"object","required":["email","password","client_id","redirect_uri","code_challenge"],"title":"Body_authorize_post_authorize_post"},"Body_import_csv_orders_api_orders_import_csv_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_import_csv_orders_api_orders_import_csv_post"},"Body_token_endpoint_token_post":{"properties":{"grant_type":{"type":"string","title":"Grant Type"},"client_id":{"type":"string","title":"Client Id","default":""},"code":{"type":"string","title":"Code","default":""},"redirect_uri":{"type":"string","title":"Redirect Uri","default":""},"code_verifier":{"type":"string","title":"Code Verifier","default":""},"refresh_token":{"type":"string","title":"Refresh Token","default":""},"resource":{"type":"string","title":"Resource","default":""},"scope":{"type":"string","title":"Scope","default":""}},"type":"object","required":["grant_type"],"title":"Body_token_endpoint_token_post"},"Body_upload_logo_api_settings_upload_logo_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"logo_type":{"type":"string","title":"Logo Type","default":"marketplace"}},"type":"object","required":["file"],"title":"Body_upload_logo_api_settings_upload_logo_post"},"BrandLearnRequest":{"properties":{"urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Urls"}},"type":"object","title":"BrandLearnRequest"},"BrandMemoryRequest":{"properties":{"shop_id":{"type":"string","maxLength":64,"minLength":1,"title":"Shop Id"}},"type":"object","required":["shop_id"],"title":"BrandMemoryRequest"},"BrandUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Name"}},"type":"object","title":"BrandUpdateRequest"},"BulkEntriesAction":{"properties":{"action":{"type":"string","title":"Action","description":"exclude | restore | delete"},"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Id","description":"Filter by source_id"},"source_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Label","description":"Filter by source_label (for orphaned)"}},"type":"object","required":["action"],"title":"BulkEntriesAction"},"CancelRequest":{"properties":{"immediate":{"type":"boolean","title":"Immediate","default":false},"reason":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Reason"},"brand_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Brand Id"}},"type":"object","title":"CancelRequest","description":"Request body for subscription cancellation."},"CapPatchRequest":{"properties":{"monthly_cap":{"type":"integer","maximum":100000.0,"minimum":0.0,"title":"Monthly Cap"},"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason"},"confirm_large_value":{"type":"boolean","title":"Confirm Large Value","default":false}},"type":"object","required":["monthly_cap"],"title":"CapPatchRequest","description":"PATCH /quota/{plan}/{operation} body."},"CheckoutRequest":{"properties":{"plan":{"type":"string","maxLength":64,"minLength":1,"title":"Plan"}},"type":"object","required":["plan"],"title":"CheckoutRequest"},"ClaimShopifyInstallRequest":{"properties":{"setup_token":{"type":"string","maxLength":128,"minLength":16,"title":"Setup Token"}},"type":"object","required":["setup_token"],"title":"ClaimShopifyInstallRequest","description":"Request to claim a pending Shopify install for the authenticated user."},"ClearShareBody":{"properties":{"field":{"type":"string","title":"Field"}},"type":"object","required":["field"],"title":"ClearShareBody"},"ClickRequest":{"properties":{"menu_id":{"type":"string","title":"Menu Id"}},"type":"object","required":["menu_id"],"title":"ClickRequest","description":"Record a menu click."},"ClientCredentialsConnectRequest":{"properties":{"store_domain":{"type":"string","maxLength":256,"minLength":3,"title":"Store Domain"},"client_id":{"type":"string","maxLength":256,"minLength":8,"title":"Client Id"},"client_secret":{"type":"string","maxLength":256,"minLength":8,"title":"Client Secret"}},"type":"object","required":["store_domain","client_id","client_secret"],"title":"ClientCredentialsConnectRequest","description":"Request to connect using Client ID + Client Secret (Dev Dashboard flow)."},"CodexUpdateRequest":{"properties":{"shop_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"},"key":{"type":"string","title":"Key","description":"編集する軸: forbidden_expressions / preferred_expressions / signature_phrases / structural_conventions / forbidden_concepts"},"value":{"title":"Value"}},"type":"object","required":["key","value"],"title":"CodexUpdateRequest"},"CompareEnginesRequest":{"properties":{"shop_id":{"type":"string","maxLength":64,"minLength":1,"title":"Shop Id"},"order_id":{"type":"string","maxLength":128,"minLength":1,"title":"Order Id"},"engines":{"items":{"type":"string","enum":["v1_legacy","v2_structured","v3_narrative","v4_cassette","v4_singlepass","v6_kobo","v6_material","v4_refined"]},"type":"array","maxItems":4,"minItems":1,"title":"Engines"},"length_preset":{"anyOf":[{"type":"string","enum":["short","standard","long","dynamic","custom"]},{"type":"null"}],"title":"Length Preset","description":"文字数プリセット. None なら shop 設定をそのまま使う"},"min_length":{"anyOf":[{"type":"integer","maximum":600.0,"minimum":40.0},{"type":"null"}],"title":"Min Length","description":"length_preset='custom' の時に必須. 40〜600"},"max_length":{"anyOf":[{"type":"integer","maximum":600.0,"minimum":40.0},{"type":"null"}],"title":"Max Length","description":"length_preset='custom' の時に必須. 40〜600"}},"type":"object","required":["shop_id","order_id","engines"],"title":"CompareEnginesRequest"},"ConfirmCanonicalRequest":{"properties":{"conversational":{"type":"string","maxLength":100,"minLength":1,"title":"Conversational"},"formal":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Formal"},"category":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Category"},"vague":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Vague"}},"type":"object","required":["conversational"],"title":"ConfirmCanonicalRequest","description":"Request to confirm the canonical (4-register) product names.\n\n`conversational` is the primary name SOERU should use when addressing the\ncustomer (e.g., 「スパイスカレーキット」). The other three are optional —\nif omitted, we leave the existing value untouched (so Haiku's prior\ncanonicalization is preserved where the operator didn't override it)."},"ConfirmRequest":{"properties":{"message_id":{"type":"string","title":"Message Id"}},"type":"object","required":["message_id"],"title":"ConfirmRequest"},"ConfirmURLRequest":{"properties":{"url":{"type":"string","maxLength":2000,"minLength":10,"title":"Url"},"summary":{"type":"string","maxLength":2000,"minLength":5,"title":"Summary"},"original_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Original Text"},"category":{"type":"string","title":"Category","default":"brand"},"use_level":{"type":"string","title":"Use Level","default":"standard"}},"type":"object","required":["url","summary"],"title":"ConfirmURLRequest","description":"Step 2: Confirm (optionally edit) and save previewed summary."},"CreateAnnouncementRequest":{"properties":{"slug":{"type":"string","maxLength":120,"minLength":3,"title":"Slug"},"title":{"type":"string","maxLength":200,"minLength":1,"title":"Title"},"body_md":{"type":"string","maxLength":20000,"minLength":1,"title":"Body Md"},"severity":{"type":"string","enum":["info","warning","critical"],"title":"Severity","default":"info"},"audience":{"type":"string","enum":["admin_only","public_only","both"],"title":"Audience","default":"both"},"starts_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Starts At"},"ends_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ends At"},"incident_id":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Incident Id"},"related_links":{"items":{"$ref":"#/components/schemas/RelatedLink"},"type":"array","title":"Related Links"}},"type":"object","required":["slug","title","body_md"],"title":"CreateAnnouncementRequest"},"CreateBlockFromTemplateRequest":{"properties":{"template_key":{"type":"string","title":"Template Key"}},"type":"object","required":["template_key"],"title":"CreateBlockFromTemplateRequest"},"CreateBlockRequest":{"properties":{"block_type":{"type":"string","title":"Block Type"},"block_data":{"additionalProperties":true,"type":"object","title":"Block Data"},"enabled":{"type":"boolean","title":"Enabled","default":true},"visible_platforms":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Visible Platforms"}},"type":"object","required":["block_type","block_data"],"title":"CreateBlockRequest"},"CreateMenuFromTemplateRequest":{"properties":{"template_key":{"type":"string","title":"Template Key"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"action_url":{"type":"string","title":"Action Url","default":""},"action_data":{"additionalProperties":true,"type":"object","title":"Action Data","default":{}}},"type":"object","required":["template_key"],"title":"CreateMenuFromTemplateRequest","description":"Create a menu from a built-in template."},"CreateMenuRequest":{"properties":{"menu_type":{"type":"string","title":"Menu Type","default":"custom"},"name":{"type":"string","title":"Name"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description","default":""},"action_type":{"type":"string","title":"Action Type","default":"external_link"},"action_url":{"type":"string","title":"Action Url","default":""},"action_data":{"additionalProperties":true,"type":"object","title":"Action Data","default":{}},"icon_emoji":{"type":"string","title":"Icon Emoji","default":"🎁"},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["name","title"],"title":"CreateMenuRequest","description":"Create a marketing menu."},"CreateRuleRequest":{"properties":{"menu_id":{"type":"string","title":"Menu Id"},"rule_type":{"type":"string","title":"Rule Type"},"condition":{"additionalProperties":true,"type":"object","title":"Condition","default":{}},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["menu_id","rule_type"],"title":"CreateRuleRequest","description":"Create a display rule."},"CreateShopRequest":{"properties":{"shop_name":{"type":"string","title":"Shop Name"},"shop_platform":{"type":"string","title":"Shop Platform","default":"rakuten"},"brand_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Name"},"target_brand_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Brand Id"}},"type":"object","required":["shop_name"],"title":"CreateShopRequest"},"CrossLinkRequest":{"properties":{"shop_id":{"type":"string","maxLength":64,"minLength":1,"title":"Shop Id"},"only_unprocessed":{"type":"boolean","title":"Only Unprocessed","default":true}},"type":"object","required":["shop_id"],"title":"CrossLinkRequest"},"CultureRuleToggleRequest":{"properties":{"shop_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"},"key":{"type":"string","title":"Key","description":"ルール ID (例: j1_kogo_buree, j10_second_person)"},"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["key","enabled"],"title":"CultureRuleToggleRequest"},"DeepPreviewRequest":{"properties":{"url":{"type":"string","maxLength":2000,"minLength":10,"title":"Url"},"max_pages":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Max Pages","default":30}},"type":"object","required":["url"],"title":"DeepPreviewRequest"},"DeleteAccountRequest":{"properties":{"confirmation":{"type":"string","maxLength":32,"minLength":1,"title":"Confirmation"}},"type":"object","required":["confirmation"],"title":"DeleteAccountRequest","description":"Request body for account deletion."},"DetectRequest":{"properties":{"url":{"type":"string","maxLength":2000,"minLength":10,"title":"Url"}},"type":"object","required":["url"],"title":"DetectRequest"},"DigestUpdateRequest":{"properties":{"digest_text":{"type":"string","maxLength":2000,"minLength":10,"title":"Digest Text"}},"type":"object","required":["digest_text"],"title":"DigestUpdateRequest","description":"Request to manually override product_digest text (2026-05-16)."},"EditMessageRequest":{"properties":{"message_id":{"type":"string","title":"Message Id"},"message":{"type":"string","title":"Message"}},"type":"object","required":["message_id","message"],"title":"EditMessageRequest"},"ExecuteRequest":{"properties":{"shop_id":{"type":"string","maxLength":64,"minLength":1,"title":"Shop Id"},"limit":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Limit","default":500},"dry_run":{"type":"boolean","title":"Dry Run","default":false}},"type":"object","required":["shop_id"],"title":"ExecuteRequest"},"FeatureRequestBody":{"properties":{"title":{"type":"string","title":"Title","default":""},"description":{"type":"string","maxLength":2000,"minLength":1,"title":"Description"},"category":{"type":"string","title":"Category","default":"general"}},"type":"object","required":["description"],"title":"FeatureRequestBody"},"ForbiddenVariantRequest":{"properties":{"variant":{"type":"string","maxLength":200,"minLength":1,"title":"Variant"}},"type":"object","required":["variant"],"title":"ForbiddenVariantRequest","description":"Request to remove (un-ban) a forbidden variant."},"FullRebuildRequest":{"properties":{"shop_id":{"type":"string","maxLength":64,"minLength":1,"title":"Shop Id"},"skip_embedding":{"type":"boolean","title":"Skip Embedding","default":true},"skip_cross_link":{"type":"boolean","title":"Skip Cross Link","default":true},"skip_digests":{"type":"boolean","title":"Skip Digests","default":false},"digest_model":{"type":"string","title":"Digest Model","default":"claude-sonnet-4-6"},"force":{"type":"boolean","title":"Force","default":false}},"type":"object","required":["shop_id"],"title":"FullRebuildRequest"},"FullSlipRequest":{"properties":{"output_mode":{"type":"string","const":"full_slip","title":"Output Mode","default":"full_slip"},"orders":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Orders"}},"type":"object","required":["orders"],"title":"FullSlipRequest","description":"Request for full packing slip PDF (明細書).\n\nメッセージカード単体 PDF は 2026-04-22 に UI から削除したため、\noutput_mode は現在 \"full_slip\" のみ受け付ける (後方互換のため\nLiteral で残している)。"},"GenerateCodesRequest":{"properties":{"orders":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Orders"}},"type":"object","required":["orders"],"title":"GenerateCodesRequest","description":"Generate link codes for orders."},"GenerateRequest":{"properties":{"order_id":{"type":"string","maxLength":255,"minLength":1,"title":"Order Id"},"customer_name":{"type":"string","maxLength":255,"title":"Customer Name","default":""},"customer_email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Customer Email"},"item_names":{"items":{"type":"string"},"type":"array","maxItems":100,"title":"Item Names"},"total_price":{"type":"integer","maximum":999999999.0,"minimum":0.0,"title":"Total Price","default":0},"is_gift":{"type":"boolean","title":"Is Gift","default":false},"delivery_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Context"},"repeat_count":{"anyOf":[{"type":"integer","maximum":9999.0,"minimum":0.0},{"type":"null"}],"title":"Repeat Count"},"is_repeat":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Repeat"},"mode":{"type":"string","pattern":"^(instant|reflective)$","title":"Mode","default":"instant"}},"type":"object","required":["order_id"],"title":"GenerateRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ImportFromPeerBody":{"properties":{"peer_shop_id":{"type":"string","title":"Peer Shop Id"},"fields":{"items":{"type":"string"},"type":"array","title":"Fields"},"overwrite":{"type":"boolean","title":"Overwrite","default":false}},"type":"object","required":["peer_shop_id"],"title":"ImportFromPeerBody"},"InvoiceEmailRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","title":"InvoiceEmailRequest"},"ManualHintRequest":{"properties":{"hint":{"type":"string","maxLength":500,"title":"Hint"}},"type":"object","required":["hint"],"title":"ManualHintRequest","description":"Request to set/update a manual hint for a product."},"ManualLearnRequest":{"properties":{"items":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"ManualLearnRequest","description":"Request to manually trigger product learning."},"ManualProductRequest":{"properties":{"item_name":{"type":"string","maxLength":200,"minLength":1,"title":"Item Name"},"manual_hint":{"type":"string","maxLength":500,"title":"Manual Hint","default":""}},"type":"object","required":["item_name"],"title":"ManualProductRequest","description":"Request to manually add a product to the catalog."},"ManualShopifyConnectRequest":{"properties":{"store_domain":{"type":"string","maxLength":256,"minLength":3,"title":"Store Domain"},"access_token":{"type":"string","maxLength":512,"minLength":8,"title":"Access Token"}},"type":"object","required":["store_domain","access_token"],"title":"ManualShopifyConnectRequest","description":"Request to connect using a manually obtained access token."},"MessageStatusRequest":{"properties":{"order_ids":{"items":{"type":"string"},"type":"array","title":"Order Ids"}},"type":"object","required":["order_ids"],"title":"MessageStatusRequest"},"MessageSyncRequest":{"properties":{"source_shop_id":{"type":"string","title":"Source Shop Id"}},"type":"object","required":["source_shop_id"],"title":"MessageSyncRequest","description":"Enable message settings sync from another shop."},"PasswordResetRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"}},"type":"object","required":["email"],"title":"PasswordResetRequest"},"PasswordUpdateRequest":{"properties":{"current_password":{"type":"string","maxLength":256,"minLength":1,"title":"Current Password"},"new_password":{"type":"string","maxLength":256,"minLength":8,"title":"New Password"}},"type":"object","required":["current_password","new_password"],"title":"PasswordUpdateRequest"},"PatchAuthenticVoiceRequest":{"properties":{"is_authentic":{"type":"boolean","title":"Is Authentic"}},"type":"object","required":["is_authentic"],"title":"PatchAuthenticVoiceRequest"},"PdfBatchRequest":{"properties":{"messages":{"items":{"$ref":"#/components/schemas/PdfSingleRequest"},"type":"array","title":"Messages"}},"type":"object","required":["messages"],"title":"PdfBatchRequest"},"PdfSingleRequest":{"properties":{"message_id":{"type":"string","title":"Message Id"},"customer_name":{"type":"string","title":"Customer Name"},"message":{"type":"string","title":"Message"}},"type":"object","required":["message_id","customer_name","message"],"title":"PdfSingleRequest"},"PrelaunchModeRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"}},"type":"object","required":["enabled"],"title":"PrelaunchModeRequest","description":"POST /prelaunch-mode body."},"PreviewRequest":{"properties":{"shop_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Shop Id"}},"type":"object","title":"PreviewRequest"},"PreviewURLRequest":{"properties":{"url":{"type":"string","maxLength":2000,"minLength":10,"title":"Url"},"category":{"type":"string","title":"Category","default":"brand"}},"type":"object","required":["url"],"title":"PreviewURLRequest","description":"Step 1: Preview URL summary before saving."},"ReactivateRequest":{"properties":{"brand_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Brand Id"}},"type":"object","title":"ReactivateRequest"},"RegenerateFromHistoryRequest":{"properties":{"message_id":{"type":"string","title":"Message Id"},"output_mode":{"type":"string","const":"full_slip","title":"Output Mode","default":"full_slip"}},"type":"object","required":["message_id"],"title":"RegenerateFromHistoryRequest","description":"Request to re-generate PDF from message history.\n\noutput_mode は Literal[\"full_slip\"] のみ許容 (2026-04-22 メッセージカード廃止)。\norder_data に items / delivery が欠けているレガシー注文については、\nbackend が内部的に generate_batch_pdf (カード PDF) にフォールバックするが、\nUI からは選択不可。"},"RegisterMonitorRequest":{"properties":{"url":{"type":"string","maxLength":2000,"minLength":10,"title":"Url"},"label":{"type":"string","title":"Label","default":""},"crawl_frequency":{"type":"string","title":"Crawl Frequency","default":"weekly"}},"type":"object","required":["url"],"title":"RegisterMonitorRequest"},"RegisterRequest":{"properties":{"redirect_uris":{"items":{"type":"string"},"type":"array","title":"Redirect Uris"},"client_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Name"},"grant_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Grant Types"},"response_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Response Types"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"},"token_endpoint_auth_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token Endpoint Auth Method"}},"type":"object","required":["redirect_uris"],"title":"RegisterRequest"},"RegisterSnapshotRequest":{"properties":{"url":{"type":"string","maxLength":2000,"minLength":10,"title":"Url"},"label":{"type":"string","title":"Label","default":""},"max_pages":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Max Pages","default":30}},"type":"object","required":["url"],"title":"RegisterSnapshotRequest"},"RelatedLink":{"properties":{"label":{"type":"string","maxLength":80,"minLength":1,"title":"Label"},"url":{"type":"string","maxLength":500,"minLength":1,"title":"Url"}},"type":"object","required":["label","url"],"title":"RelatedLink"},"ReorderBlocksRequest":{"properties":{"block_ids":{"items":{"type":"string"},"type":"array","title":"Block Ids"}},"type":"object","required":["block_ids"],"title":"ReorderBlocksRequest"},"ReorderMenusRequest":{"properties":{"menu_ids":{"items":{"type":"string"},"type":"array","title":"Menu Ids"}},"type":"object","required":["menu_ids"],"title":"ReorderMenusRequest","description":"Reorder menus."},"RunEvalRequest":{"properties":{"label":{"type":"string","maxLength":80,"minLength":1,"title":"Label","default":"eval"},"shop_id":{"type":"string","maxLength":64,"minLength":1,"title":"Shop Id","default":"cadbc33f-0de7-46e7-a067-10ab9ecc43d0"},"n":{"type":"integer","maximum":24.0,"minimum":1.0,"title":"N","default":12},"order_ids":{"items":{"type":"string"},"type":"array","maxItems":24,"title":"Order Ids"},"judge_model":{"type":"string","maxLength":64,"title":"Judge Model","default":"claude-sonnet-4-6"},"use_judge":{"type":"boolean","title":"Use Judge","default":true}},"type":"object","title":"RunEvalRequest"},"SelectWinnerRequest":{"properties":{"comparison_id":{"type":"string","maxLength":64,"minLength":1,"title":"Comparison Id"},"selected_engine":{"type":"string","maxLength":64,"minLength":1,"title":"Selected Engine"},"selection_note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Selection Note"}},"type":"object","required":["comparison_id","selected_engine"],"title":"SelectWinnerRequest"},"SendMessageRequest":{"properties":{"message":{"type":"string","maxLength":2000,"minLength":1,"title":"Message"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"}},"type":"object","required":["message"],"title":"SendMessageRequest"},"SetActiveBody":{"properties":{"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["is_active"],"title":"SetActiveBody"},"ShopifyAuthRequest":{"properties":{"shop_domain":{"type":"string","maxLength":256,"minLength":3,"title":"Shop Domain"},"frontend_origin":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Frontend Origin"},"custom_client_id":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Custom Client Id"},"custom_client_secret":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Custom Client Secret"}},"type":"object","required":["shop_domain"],"title":"ShopifyAuthRequest","description":"Request to start Shopify OAuth flow."},"ShopifyAuthResponse":{"properties":{"auth_url":{"type":"string","title":"Auth Url"},"shop_domain":{"type":"string","title":"Shop Domain"}},"type":"object","required":["auth_url","shop_domain"],"title":"ShopifyAuthResponse","description":"Response containing the authorization URL."},"SignupRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"password":{"type":"string","maxLength":256,"minLength":8,"title":"Password"},"tos_version":{"type":"string","maxLength":32,"title":"Tos Version","default":"1.0"}},"type":"object","required":["email","password"],"title":"SignupRequest"},"StyleAxesUpdateRequest":{"properties":{"formality":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Formality","default":50},"warmth":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Warmth","default":50},"detail":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Detail","default":50}},"type":"object","title":"StyleAxesUpdateRequest","description":"Save user-adjusted style axes after brand learning."},"SyncBlockRequest":{"properties":{"target_shop_ids":{"items":{"type":"string"},"type":"array","title":"Target Shop Ids"}},"type":"object","required":["target_shop_ids"],"title":"SyncBlockRequest"},"SyncHistoryRequest":{"properties":{"months_back":{"type":"integer","maximum":120.0,"minimum":0.0,"title":"Months Back","default":0}},"type":"object","title":"SyncHistoryRequest"},"TestConnectionRequest":{"properties":{"platform":{"type":"string","title":"Platform","default":"rakuten"},"service_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Secret"},"license_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"License Key"},"rakuten_service_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rakuten Service Secret"},"rakuten_license_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rakuten License Key"},"amazon_seller_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amazon Seller Id"},"amazon_mws_auth_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amazon Mws Auth Token"},"amazon_marketplace_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amazon Marketplace Id"},"shopify_store_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shopify Store Domain"},"shopify_access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shopify Access Token"},"shopify_client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shopify Client Id"},"shopify_client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shopify Client Secret"},"yahoo_app_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Yahoo App Id"},"yahoo_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Yahoo Secret"},"yahoo_seller_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Yahoo Seller Id"}},"type":"object","title":"TestConnectionRequest","description":"Platform-agnostic test connection request.\n\nSupports both legacy field names (service_secret/license_key) and\nplatform-prefixed names (rakuten_service_secret/rakuten_license_key)."},"URLLearnRequest":{"properties":{"url":{"type":"string","maxLength":2000,"minLength":10,"title":"Url"}},"type":"object","required":["url"],"title":"URLLearnRequest","description":"Request to learn product knowledge from a URL."},"UpdateAnnouncementRequest":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Title"},"body_md":{"anyOf":[{"type":"string","maxLength":20000,"minLength":1},{"type":"null"}],"title":"Body Md"},"severity":{"anyOf":[{"type":"string","enum":["info","warning","critical"]},{"type":"null"}],"title":"Severity"},"audience":{"anyOf":[{"type":"string","enum":["admin_only","public_only","both"]},{"type":"null"}],"title":"Audience"},"starts_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Starts At"},"ends_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ends At"},"incident_id":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Incident Id"},"related_links":{"anyOf":[{"items":{"$ref":"#/components/schemas/RelatedLink"},"type":"array"},{"type":"null"}],"title":"Related Links"}},"type":"object","title":"UpdateAnnouncementRequest"},"UpdateBlockRequest":{"properties":{"block_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Block Data"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"visible_platforms":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Visible Platforms"},"delivery_context_visibility":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Delivery Context Visibility"}},"type":"object","title":"UpdateBlockRequest"},"UpdateKnowledge":{"properties":{"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"use_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Use Level"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"UpdateKnowledge"},"UpdateLearnedRuleRequest":{"properties":{"action":{"type":"string","title":"Action"},"instruction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instruction"}},"type":"object","required":["action"],"title":"UpdateLearnedRuleRequest","description":"Update or delete a specific learned rule."},"UpdateMenuRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"action_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action Type"},"action_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action Url"},"action_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Action Data"},"icon_emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon Emoji"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"}},"type":"object","title":"UpdateMenuRequest","description":"Update a marketing menu."},"UpdatePageSettingsRequest":{"properties":{"page_settings":{"additionalProperties":true,"type":"object","title":"Page Settings"}},"type":"object","required":["page_settings"],"title":"UpdatePageSettingsRequest"},"UpdateProductRequest":{"properties":{"learned_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Learned Summary"},"learned_knowledge":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Learned Knowledge"}},"type":"object","title":"UpdateProductRequest","description":"Request to manually update product knowledge."},"UpdateRuleRequest":{"properties":{"rule_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rule Type"},"condition":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Condition"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"}},"type":"object","title":"UpdateRuleRequest","description":"Update a display rule."},"UpdateSettingRequest":{"properties":{"key":{"type":"string","maxLength":128,"minLength":1,"title":"Key"},"value":{"additionalProperties":true,"type":"object","title":"Value"}},"type":"object","required":["key","value"],"title":"UpdateSettingRequest"},"UpdateSettingsRequest":{"properties":{"shop_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Shop Name"},"shop_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Shop Url"},"message_tone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Tone"},"min_length":{"anyOf":[{"type":"integer","maximum":2000.0,"minimum":10.0},{"type":"null"}],"title":"Min Length"},"max_length":{"anyOf":[{"type":"integer","maximum":5000.0,"minimum":50.0},{"type":"null"}],"title":"Max Length"},"seasonal_greeting":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Seasonal Greeting"},"required_phrases":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Required Phrases"},"required_phrases_position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Required Phrases Position"},"forbidden_words":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Forbidden Words"},"repeat_customer_message_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Repeat Customer Message Enabled"},"repeat_rules":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Repeat Rules"},"product_keyword_rules":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Product Keyword Rules"},"review_request":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Review Request"},"review_request_text":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Review Request Text"},"coupon_code":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Coupon Code"},"coupon_text":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Coupon Text"},"closing_text":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Closing Text"},"opening_text":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Opening Text"},"message_blocks":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Message Blocks"},"addressee_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Addressee Format"},"font_id":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Font Id"},"paper_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Paper Size"},"font_size":{"anyOf":[{"type":"integer","maximum":72.0,"minimum":6.0},{"type":"null"}],"title":"Font Size"},"text_color":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}],"title":"Text Color"},"rakuten_service_secret":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Rakuten Service Secret"},"rakuten_license_key":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Rakuten License Key"},"anthropic_api_key":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Anthropic Api Key"},"yahoo_app_id":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Yahoo App Id"},"yahoo_secret":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Yahoo Secret"},"yahoo_seller_id":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Yahoo Seller Id"},"yahoo_public_key":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Yahoo Public Key"},"yahoo_public_key_version":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Yahoo Public Key Version"},"amazon_seller_id":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Amazon Seller Id"},"amazon_mws_auth_token":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Amazon Mws Auth Token"},"amazon_marketplace_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Amazon Marketplace Id"},"brand_profile":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Brand Profile"},"brand_profile_urls":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Brand Profile Urls"},"company_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Company Name"},"company_address":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Company Address"},"company_phone":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Company Phone"},"company_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Company Url"},"company_fax":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Company Fax"},"company_postal":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Company Postal"},"marketplace_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marketplace Logo Url"},"brand_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Logo Url"},"default_output_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Output Mode"},"slip_sections":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Slip Sections"},"accent_color":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}],"title":"Accent Color"},"header_style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Header Style"},"message_border_style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Border Style"},"custom_rules":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Custom Rules"},"soeru_link_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Soeru Link Enabled"},"message_sync_source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Sync Source Id"},"notify_batch_completion":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify Batch Completion"}},"type":"object","title":"UpdateSettingsRequest"},"UpdateShopRequest":{"properties":{"shop_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Name"},"shop_platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Platform"}},"type":"object","title":"UpdateShopRequest"},"UpdateSourceRequest":{"properties":{"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"crawl_frequency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Crawl Frequency"},"default_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Category"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"UpdateSourceRequest"},"UpsertManualField":{"properties":{"text":{"type":"string","maxLength":4000,"title":"Text","default":""}},"type":"object","title":"UpsertManualField"},"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"},"VoiceSyncRequest":{"properties":{"source_shop_id":{"type":"string","title":"Source Shop Id"}},"type":"object","required":["source_shop_id"],"title":"VoiceSyncRequest","description":"Enable voice sync from another shop."},"WaitlistRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"source":{"type":"string","maxLength":64,"title":"Source","default":"signup"}},"type":"object","required":["email"],"title":"WaitlistRequest"},"_ShopIdBody":{"properties":{"shop_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Id"}},"type":"object","title":"_ShopIdBody"},"routers__messages__FeedbackRequest":{"properties":{"message_id":{"type":"string","title":"Message Id"},"feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback"},"feedback_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback Reason"},"feedback_comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback Comment"}},"type":"object","required":["message_id"],"title":"FeedbackRequest"},"routers__public__FeedbackRequest":{"properties":{"feedback":{"type":"string","title":"Feedback"}},"type":"object","required":["feedback"],"title":"FeedbackRequest","description":"Customer feedback from QR landing page."}}}}