{"openapi":"3.0.3","info":{"title":"Shuifit personal try-on API","version":"1.0.0","description":"Existing authenticated account API for trusted server/local agents. Not scoped OAuth or an agent-specific key. Obtain permission to upload images and spend credits. POST generation is NOT idempotent; never blindly retry an uncertain submission. Results retained for 30 days. No payment or account deletion tools are included."},"servers":[{"url":"https://www.shuifit.com"}],"externalDocs":{"url":"https://www.shuifit.com/developers"},"security":[{"accountSession":[]}],"x-shuifit-tryon":{"costCredits":1,"mode":"quality","chargePolicy":"reserve-on-acceptance-charge-on-success","idempotent":false,"imageMimeTypes":["image/jpeg","image/png","image/webp"],"maxImageBytes":10485760},"paths":{"/api/mobile/credits":{"get":{"operationId":"getCreditBalance","summary":"Read account credit balance","description":"Total balance may include credits reserved for queued jobs; submission performs the final availability check.","responses":{"200":{"description":"Balance","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"credits":{"type":"object","properties":{"total":{"type":"integer"},"paid":{"type":"integer"},"trial":{"type":"integer"}}}}}}}},"401":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/mobile/tryon/async":{"post":{"operationId":"submitPersonalTryOn","summary":"Submit one paid asynchronous try-on","x-openai-isConsequential":true,"description":"Requires user authorization to upload both images and spend credits. Returns 202 and a generationId. No idempotency key support: on a lost response inspect recent history rather than repeat POST. Requires the existing generation worker to be running.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["modelImage","garmentImage","tryOnMode"],"properties":{"modelImage":{"type":"string","format":"binary","description":"JPEG, PNG or WebP; maximum 10485760 bytes per image. Upload file bytes, not a URL."},"garmentImage":{"type":"string","format":"binary","description":"JPEG, PNG or WebP; maximum 10485760 bytes per image. Upload file bytes, not a URL."},"tryOnMode":{"type":"string","enum":["quality"]},"garmentRole":{"type":"string","enum":["top","bottom","dress"],"default":"top"},"aspectRatio":{"type":"string","enum":["portrait_9_16","landscape_16_9","square_1_1"]}}}}}},"responses":{"202":{"description":"Queued; credits reserved, not yet charged","content":{"application/json":{"schema":{"type":"object","required":["ok","generationId","status","cost","remainingCredits"],"properties":{"ok":{"type":"boolean"},"generationId":{"type":"string"},"status":{"type":"string","enum":["queued"]},"cost":{"type":"integer"},"remainingCredits":{"type":"integer"}}}}}},"400":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/mobile/generations/{generationId}/status":{"get":{"operationId":"getTryOnStatus","summary":"Poll an owned generation","parameters":[{"name":"generationId","in":"path","required":true,"schema":{"type":"string"}}],"description":"Poll every 5 seconds with backoff. Stop on succeeded or failed. Download promptly on success; download endpoint enforces retention.","responses":{"200":{"description":"Generation state","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"generation":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","processing","succeeded","failed"]},"cost":{"type":"integer"},"reservedCost":{"type":"integer"},"downloadUrl":{"type":"string","nullable":true},"errorCode":{"type":"string","nullable":true},"errorMessage":{"type":"string","nullable":true}}}}}}}},"401":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/mobile/generations/{generationId}/image":{"get":{"operationId":"downloadTryOnImage","summary":"Download an owned unexpired result","parameters":[{"name":"generationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"JPEG image","content":{"image/jpeg":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/mobile/generations":{"get":{"operationId":"listRecentTryOns","summary":"List up to 50 owned recent generations","description":"Use to investigate uncertain POST outcomes. Do not assume absence immediately means submission failed.","responses":{"200":{"description":"Recent history","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"items":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Request failed; inspect message and optional errorCode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"accountSession":{"type":"http","scheme":"bearer","description":"Account session from trusted login; send only to www.shuifit.com over HTTPS."}},"schemas":{"Error":{"type":"object","required":["ok","message"],"properties":{"ok":{"type":"boolean","enum":[false]},"message":{"type":"string"},"errorCode":{"type":"string"}}}}}}