{"openapi":"3.1.0","info":{"title":"HyeAn Match Server","version":"0.1.0"},"paths":{"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/feedback":{"post":{"summary":"Feedback","description":"Record the user's confirmed pick for a match (approval or override).","operationId":"feedback_feedback_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/ui/generate":{"post":{"summary":"Ui Generate","description":"Generate a game UI shell from one sentence (beta). Returns an assembled preview (base64 PNG)\n+ a placement spec. Uses the built-in transparent sample pool by default; with mine=true and an\nAPI key, matches sprites from your own indexed pack. No Unity required — works for everyone.","operationId":"ui_generate_ui_generate_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UIGenRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/download/cheongmyeong_kit.zip":{"get":{"summary":"Download Audio Kit","description":"Cheongmyeong indexing kit — runs on the user's GPU; uploads vectors+previews, never originals.","operationId":"download_audio_kit_download_cheongmyeong_kit_zip_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/download/HyeAnMatchWindow.cs":{"get":{"summary":"Download Unity Plugin","description":"Download the Unity editor extension — drop it into Assets/Editor/ and you're done.","operationId":"download_unity_plugin_download_HyeAnMatchWindow_cs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/signup":{"post":{"summary":"Signup","description":"Sign up with an email and get a free API key instantly. Existing emails receive a key hint instead.","operationId":"signup_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"}}}}}}},"/match":{"post":{"summary":"Match","description":"Match a sentence to assets in your library. Returns 5 candidates, winner_index (AI pick) and match_quality (good|weak|none). Set rerank=false for instant embedding-only results.","operationId":"match_match_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index/add":{"post":{"summary":"Index Add","description":"Register a batch of 256px thumbnails from your library. Indexing runs in the background.\nUploads are screened for prohibited content (explicit adult material); blocked images are never\nstored and appear as `blocked` in the /index/status job counters. Game art, fantasy and stylized\nviolence are fine.","operationId":"index_add_index_add_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexAddRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/axis":{"post":{"summary":"Axis","description":"오디오 전용 — 두 극 사이의 '축'으로 결과를 줄 세운다 (무거움↔가벼움 슬라이더).\n\n왜 별도 엔드포인트인가 (Phase 0 실측):\n  절대 쿼리는 감쇠 수식어를 못 듣는다. \"a small weak explosion\" AUC 43% = 무작위 이하로,\n  작은 걸 달라는데 오히려 큰 걸 준다 (모델이 명사에 꽂히고 수식어를 무시).\n  반면 두 극의 **차이 벡터**로 정렬하면 85~94%로 안정적이다.\n  → 폴라 속성은 자유 텍스트가 아니라 이 축으로 받는 것이 정답.\n파일명 검색이 원리적으로 못 하는 기능 (\"Impact 01~50 중 묵직한 것\").","operationId":"axis_axis_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AxisRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index/status":{"get":{"summary":"Index Status","description":"Indexing progress and counts for your library.","operationId":"index_status_index_status_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index/list":{"get":{"summary":"Index List","description":"인덱싱된 에셋의 경로 목록 (폴더별 집계 + 전체 경로). 유저가 뭐가 들어갔는지 확인용.","operationId":"index_list_index_list_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index":{"delete":{"summary":"Index Clear","description":"Delete your entire index (thumbnails and vectors).","operationId":"index_clear_index_delete","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index/add_vectors":{"post":{"summary":"Index Add Vectors","description":"Register assets with client-computed 1152-dim vectors (for custom pipelines).\nContent screening applies: blocked items are listed in `blocked_paths` (partial batches still\nsucceed with 200); if every item is blocked the request fails with 422 `CONTENT_BLOCKED`.","operationId":"index_add_vectors_index_add_vectors_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorAddRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index/add_audio":{"post":{"summary":"Index Add Audio","description":"Register audio clips with client-computed vectors + 10s ogg previews (Cheongmyeong indexer kit).","operationId":"index_add_audio_index_add_audio_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioVectorAddRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index/diff":{"post":{"summary":"Index Diff","description":"Compare your folder's file list with the server index — then upload thumbnails only for new files.","operationId":"index_diff_index_diff_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncPaths"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index/prune":{"post":{"summary":"Index Prune","description":"Remove assets no longer present in your folder. Index quota is freed; used caption credits are not refunded.","operationId":"index_prune_index_prune_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncPaths"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/index/remove":{"post":{"summary":"Index Remove","description":"Remove selected images (paths) and/or whole folders from your index.\nIndex quota is freed; used caption credits are not refunded (embedding/caption GPU already spent).","operationId":"index_remove_index_remove_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account":{"get":{"summary":"Account","description":"Your plan, quotas and usage.","operationId":"account_account_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/caption/generate":{"post":{"summary":"Caption Generate","description":"Generate search captions for uncaptioned assets. Credits are deducted per completed caption only.\nOptional body {paths, folders}: caption only those (still uncaptioned). Empty body = all pending, upload order.","operationId":"caption_generate_caption_generate_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/CaptionRequest"},{"type":"null"}],"title":"Req"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/caption/cancel":{"post":{"summary":"Caption Cancel","description":"Stop caption generation — clears your pending caption queue. Credits are only charged on\ncompletion, so cancelling never charges for un-generated captions. Re-run /caption/generate anytime.","operationId":"caption_cancel_caption_cancel_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/caption/mode":{"post":{"summary":"Caption Mode","description":"Set caption style for your account: \"game\" (default) or \"general\" — general drops game\nassumptions, better for real photos / non-game image libraries. Applies to captions generated\nfrom now on; existing captions are kept. Re-run /caption/generate to (re)caption with the new style.","operationId":"caption_mode_caption_mode_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptionModeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/billing/status":{"get":{"summary":"Billing Status","description":"Whether card checkout is available.","operationId":"billing_status_billing_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/billing/checkout":{"post":{"summary":"Billing Checkout","description":"Create a card checkout session for a plan or caption pack. Returns the payment page URL.","operationId":"billing_checkout_billing_checkout_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$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"}}}}}}},"/review":{"post":{"summary":"Submit Review","description":"Submit a review. Your first review earns bonus caption credits. Reviews may be quoted publicly only if allow_public is true.","operationId":"submit_review_review_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/caption/balance":{"get":{"summary":"Caption Balance","description":"Caption credit balance and usage summary.","operationId":"caption_balance_caption_balance_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/caption/status":{"get":{"summary":"Caption Status","description":"Caption generation progress for your library.","operationId":"caption_status_caption_status_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AudioVectorAddRequest":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AudioVectorItem"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"AudioVectorAddRequest"},"AudioVectorItem":{"properties":{"path":{"type":"string","title":"Path"},"preview_b64":{"type":"string","title":"Preview B64"},"audio_vec":{"items":{"type":"number"},"type":"array","title":"Audio Vec"},"cap_vec":{"items":{"type":"number"},"type":"array","title":"Cap Vec"},"caption":{"type":"string","title":"Caption","default":""},"fname_vec":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Fname Vec"},"duration_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Sec"}},"type":"object","required":["path","preview_b64","audio_vec","cap_vec"],"title":"AudioVectorItem"},"AxisRequest":{"properties":{"high":{"type":"string","title":"High"},"low":{"type":"string","title":"Low"},"query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query"},"pool":{"type":"integer","title":"Pool","default":50},"top_k":{"type":"integer","title":"Top K","default":20},"ids":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Ids"}},"type":"object","required":["high","low"],"title":"AxisRequest"},"CaptionModeRequest":{"properties":{"mode":{"type":"string","title":"Mode"}},"type":"object","required":["mode"],"title":"CaptionModeRequest"},"CaptionRequest":{"properties":{"paths":{"items":{"type":"string"},"type":"array","title":"Paths","default":[]},"folders":{"items":{"type":"string"},"type":"array","title":"Folders","default":[]}},"type":"object","title":"CaptionRequest"},"CheckoutRequest":{"properties":{"plan":{"type":"string","title":"Plan"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"}},"type":"object","required":["plan"],"title":"CheckoutRequest"},"FeedbackRequest":{"properties":{"query":{"type":"string","title":"Query"},"candidates":{"items":{"type":"string"},"type":"array","title":"Candidates"},"ai_winner":{"type":"string","title":"Ai Winner"},"user_choice":{"type":"string","title":"User Choice"},"overridden":{"type":"boolean","title":"Overridden"},"layout_rule_preset":{"type":"string","title":"Layout Rule Preset","default":""},"client":{"type":"string","title":"Client","default":"unknown"},"context":{"type":"string","title":"Context","default":"game-icon"},"match_id":{"type":"string","title":"Match Id","default":""}},"type":"object","required":["query","candidates","ai_winner","user_choice","overridden"],"title":"FeedbackRequest","description":"A user's confirmed selection for a match — sent by any client (Unity, web, or your own pipeline)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IndexAddRequest":{"properties":{"items":{"items":{"$ref":"#/components/schemas/IndexItem"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"IndexAddRequest"},"IndexItem":{"properties":{"path":{"type":"string","title":"Path"},"thumb_b64":{"type":"string","title":"Thumb B64"}},"type":"object","required":["path","thumb_b64"],"title":"IndexItem"},"MatchRequest":{"properties":{"query":{"type":"string","title":"Query"},"top_k":{"type":"integer","title":"Top K","default":5},"context":{"type":"string","title":"Context","default":"game-icon"},"rerank":{"type":"boolean","title":"Rerank","default":true}},"type":"object","required":["query"],"title":"MatchRequest"},"RemoveRequest":{"properties":{"paths":{"items":{"type":"string"},"type":"array","title":"Paths","default":[]},"folders":{"items":{"type":"string"},"type":"array","title":"Folders","default":[]}},"type":"object","title":"RemoveRequest"},"ReviewRequest":{"properties":{"rating":{"type":"integer","title":"Rating"},"text":{"type":"string","title":"Text"},"name":{"type":"string","title":"Name","default":""},"allow_public":{"type":"boolean","title":"Allow Public","default":false}},"type":"object","required":["rating","text"],"title":"ReviewRequest"},"SignupRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"SignupRequest"},"SyncPaths":{"properties":{"paths":{"items":{"type":"string"},"type":"array","title":"Paths"}},"type":"object","required":["paths"],"title":"SyncPaths"},"UIGenRequest":{"properties":{"request":{"type":"string","title":"Request"},"mine":{"type":"boolean","title":"Mine","default":false}},"type":"object","required":["request"],"title":"UIGenRequest","description":"T1 UI 껍데기 생성 요청 (베타)."},"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"},"VectorAddRequest":{"properties":{"items":{"items":{"$ref":"#/components/schemas/VectorItem"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"VectorAddRequest"},"VectorItem":{"properties":{"path":{"type":"string","title":"Path"},"thumb_b64":{"type":"string","title":"Thumb B64"},"img_vec":{"items":{"type":"number"},"type":"array","title":"Img Vec"},"txt_vec":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Txt Vec"}},"type":"object","required":["path","thumb_b64","img_vec"],"title":"VectorItem"}}}}