{"openapi":"3.1.0","info":{"title":"LubanPNG API","description":"TinyPNG 式图片压缩与放大服务。API Key 放在 Authorization: Bearer 头；每个响应带 X-Quota-Limit / X-Quota-Remaining / X-Quota-Reset。","license":{"name":"MIT","identifier":"MIT"},"version":"1.1.0"},"paths":{"/v1/auth/logout":{"post":{"tags":["账号"],"operationId":"logout","responses":{"200":{"description":"已注销","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_OkResponse"}}}}}}},"/v1/auth/otp":{"post":{"tags":["账号"],"operationId":"request_otp","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpRequest"}}},"required":true},"responses":{"200":{"description":"验证码已发送","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_OtpResponse"}}}},"400":{"description":"邮箱无效","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"429":{"description":"发送过于频繁","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"503":{"description":"邮件服务未配置","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}}}},"/v1/auth/verify":{"post":{"tags":["账号"],"operationId":"verify_otp","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyRequest"}}},"required":true},"responses":{"200":{"description":"登录成功，响应设置会话 Cookie","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_VerifyResponse"}}}},"400":{"description":"验证码错误或过期","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"429":{"description":"错误次数过多","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}}}},"/v1/events/visit":{"post":{"tags":["埋点"],"operationId":"record_visit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitRequest"}}},"required":true},"responses":{"200":{"description":"访问事件已记录","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_OkResponse"}}}},"400":{"description":"参数错误","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}}}},"/v1/images/compress":{"post":{"tags":["图片压缩"],"operationId":"upload_image","requestBody":{"description":"上传一张 PNG / JPEG / GIF / WebP / AVIF 图片，入队压缩并扣减 1 次额度；可选 convert 指定输出格式（png、jpeg、webp、avif），转换额外扣减 1 次；透明图转 JPEG 时需用 background 指定 #RRGGBB 背景色","content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UploadForm"}}},"required":true},"responses":{"200":{"description":"已入队","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_UploadResponse"}}}},"400":{"description":"参数错误或不支持的格式","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"413":{"description":"文件超过当前套餐上限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"429":{"description":"本期额度用尽或触发限速","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}},"security":[{"api_key":[]}]}},"/v1/images/compress/{task_id}":{"get":{"tags":["图片压缩"],"operationId":"get_task_status","parameters":[{"name":"task_id","in":"path","description":"任务 ID","required":true,"schema":{"type":"string"}},{"name":"wait","in":"query","required":false,"schema":{"type":["integer","null"],"format":"int64","minimum":0},"example":30}],"responses":{"200":{"description":"任务状态；带 wait 时最多等待该秒数直到终态","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_TaskStatusView"}}}},"404":{"description":"任务不存在","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}},"security":[{"api_key":[]}]}},"/v1/images/download/{filename}":{"get":{"tags":["图片压缩"],"operationId":"download_file","parameters":[{"name":"filename","in":"path","description":"任务状态里 compressed_url 的文件名","required":true,"schema":{"type":"string"}}],"responses":{"302":{"description":"跳转到 10 分钟内有效的对象存储地址"},"404":{"description":"文件不存在或已过期","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}},"security":[{"api_key":[]}]}},"/v1/images/upscale":{"post":{"tags":["图片放大"],"operationId":"upscale_image","requestBody":{"description":"上传一张静态 PNG 或 JPEG 图片，按 scale（x2 或 x4）放大，输出固定为 PNG 并计减 1 次额度；输入上限 2.25MP、单边 2048、20MB；失败或超时不计次；排队上限 10，超限返回 429","content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UpscaleForm"}}},"required":true},"responses":{"200":{"description":"已入队","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_UploadResponse"}}}},"400":{"description":"参数错误、尺寸超限或格式不支持（仅 PNG/JPEG）","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"413":{"description":"文件超过放大输入上限（20MB）","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"429":{"description":"本期额度用尽、触发限速或放大队列已满","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"503":{"description":"放大服务不可用","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}},"security":[{"api_key":[]}]}},"/v1/me":{"get":{"tags":["账号"],"operationId":"me","responses":{"200":{"description":"当前身份、套餐与本期额度；未登录时返回匿名设备额度","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_MeView"}}}}},"security":[{"api_key":[]}]}},"/v1/me/api-keys":{"get":{"tags":["账号"],"operationId":"list_api_keys","responses":{"200":{"description":"可用的 API Key 列表","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_Vec_ApiKeyView"}}}},"401":{"description":"未登录","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}}},"post":{"tags":["账号"],"operationId":"create_api_key","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}},"required":true},"responses":{"200":{"description":"新建成功，完整 Key 只在此响应里出现一次","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_CreatedApiKeyView"}}}},"400":{"description":"名称无效或已达套餐上限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}},"401":{"description":"未登录","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}}}},"/v1/me/api-keys/{id}":{"delete":{"tags":["账号"],"operationId":"revoke_api_key","parameters":[{"name":"id","in":"path","description":"Key ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"已吊销","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_OkResponse"}}}},"404":{"description":"Key 不存在或已吊销","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponseError"}}}}}}},"/v1/me/tasks":{"get":{"tags":["账号"],"operationId":"list_tasks","responses":{"200":{"description":"当前身份最近的压缩任务，最多 50 条","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse_Vec_TaskStatusView"}}}}},"security":[{"api_key":[]}]}}},"components":{"schemas":{"ApiKeyView":{"type":"object","required":["id","name","prefix","suffix","created_at"],"properties":{"created_at":{"type":"string"},"id":{"type":"string"},"last_used_at":{"type":["string","null"]},"name":{"type":"string"},"prefix":{"type":"string","example":"lp_live_a8f3"},"suffix":{"type":"string","example":"k2q9"}}},"ApiResponseError":{"type":"object","required":["code","msg"],"properties":{"code":{"type":"integer","format":"int32","example":1001},"data":{},"msg":{"type":"string","example":"错误信息"}}},"ApiResponse_CreatedApiKeyView":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"object","required":["id","name","key","prefix","suffix","created_at"],"properties":{"created_at":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"suffix":{"type":"string"}}},"msg":{"type":"string","example":"success"}}},"ApiResponse_MeView":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"object","required":["subject","plan","quota"],"properties":{"email":{"type":["string","null"]},"plan":{"$ref":"#/components/schemas/PlanView"},"quota":{"$ref":"#/components/schemas/QuotaView"},"subject":{"type":"string","example":"account"}}},"msg":{"type":"string","example":"success"}}},"ApiResponse_OkResponse":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}},"msg":{"type":"string","example":"success"}}},"ApiResponse_OtpResponse":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"object","required":["sent","expires_in","resend_after"],"properties":{"expires_in":{"type":"integer","format":"int64","example":600},"resend_after":{"type":"integer","format":"int64","example":60},"sent":{"type":"boolean"}}},"msg":{"type":"string","example":"success"}}},"ApiResponse_TaskStatusView":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"object","required":["task_id","status","progress","source","kind","original_name","original_size","quota_units","no_gain","created_at","downloadable"],"properties":{"completed_at":{"type":["integer","null"],"format":"int64","example":1691234600},"compressed_size":{"type":["integer","null"],"format":"int64","example":512000,"minimum":0},"compressed_url":{"type":["string","null"],"example":"/v1/images/download/550e8400-e29b-41d4-a716-446655440000.png"},"created_at":{"type":"integer","format":"int64","example":1691234567},"downloadable":{"type":"boolean"},"error_msg":{"type":["string","null"]},"expires_at":{"type":["integer","null"],"format":"int64","example":1691321000},"kind":{"type":"string","example":"compress"},"no_gain":{"type":"boolean"},"original_name":{"type":"string","example":"photo.png"},"original_size":{"type":"integer","format":"int64","example":1024000,"minimum":0},"output_format":{"type":["string","null"],"example":"png"},"progress":{"type":"integer","format":"int32","example":100,"minimum":0},"queue_position":{"type":["integer","null"],"format":"int64","example":1},"quota_units":{"type":"integer","format":"int32","example":1},"scale":{"type":["string","null"],"example":"x4"},"source":{"type":"string","example":"web"},"status":{"type":"string","example":"completed"},"target_format":{"type":["string","null"],"example":"webp"},"task_id":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"}}},"msg":{"type":"string","example":"success"}}},"ApiResponse_UploadResponse":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"object","required":["task_id"],"properties":{"task_id":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"}}},"msg":{"type":"string","example":"success"}}},"ApiResponse_Vec_ApiKeyView":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"array","items":{"type":"object","required":["id","name","prefix","suffix","created_at"],"properties":{"created_at":{"type":"string"},"id":{"type":"string"},"last_used_at":{"type":["string","null"]},"name":{"type":"string"},"prefix":{"type":"string","example":"lp_live_a8f3"},"suffix":{"type":"string","example":"k2q9"}}}},"msg":{"type":"string","example":"success"}}},"ApiResponse_Vec_TaskStatusView":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"array","items":{"type":"object","required":["task_id","status","progress","source","kind","original_name","original_size","quota_units","no_gain","created_at","downloadable"],"properties":{"completed_at":{"type":["integer","null"],"format":"int64","example":1691234600},"compressed_size":{"type":["integer","null"],"format":"int64","example":512000,"minimum":0},"compressed_url":{"type":["string","null"],"example":"/v1/images/download/550e8400-e29b-41d4-a716-446655440000.png"},"created_at":{"type":"integer","format":"int64","example":1691234567},"downloadable":{"type":"boolean"},"error_msg":{"type":["string","null"]},"expires_at":{"type":["integer","null"],"format":"int64","example":1691321000},"kind":{"type":"string","example":"compress"},"no_gain":{"type":"boolean"},"original_name":{"type":"string","example":"photo.png"},"original_size":{"type":"integer","format":"int64","example":1024000,"minimum":0},"output_format":{"type":["string","null"],"example":"png"},"progress":{"type":"integer","format":"int32","example":100,"minimum":0},"queue_position":{"type":["integer","null"],"format":"int64","example":1},"quota_units":{"type":"integer","format":"int32","example":1},"scale":{"type":["string","null"],"example":"x4"},"source":{"type":"string","example":"web"},"status":{"type":"string","example":"completed"},"target_format":{"type":["string","null"],"example":"webp"},"task_id":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"}}}},"msg":{"type":"string","example":"success"}}},"ApiResponse_VerifyResponse":{"type":"object","required":["code","msg","data"],"properties":{"code":{"type":"integer","format":"int32","example":0},"data":{"type":"object","required":["email","plan_id","created"],"properties":{"created":{"type":"boolean"},"email":{"type":"string"},"plan_id":{"type":"string","example":"free"}}},"msg":{"type":"string","example":"success"}}},"CreateApiKeyRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","example":"本机 CLI"}}},"CreatedApiKeyView":{"type":"object","required":["id","name","key","prefix","suffix","created_at"],"properties":{"created_at":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"suffix":{"type":"string"}}},"MeView":{"type":"object","required":["subject","plan","quota"],"properties":{"email":{"type":["string","null"]},"plan":{"$ref":"#/components/schemas/PlanView"},"quota":{"$ref":"#/components/schemas/QuotaView"},"subject":{"type":"string","example":"account"}}},"OkResponse":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}},"OtpRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string","example":"you@example.com"}}},"OtpResponse":{"type":"object","required":["sent","expires_in","resend_after"],"properties":{"expires_in":{"type":"integer","format":"int64","example":600},"resend_after":{"type":"integer","format":"int64","example":60},"sent":{"type":"boolean"}}},"PlanView":{"type":"object","required":["id","name","period","quota","max_file_size","retention_hours","max_api_keys"],"properties":{"id":{"type":"string","example":"free"},"max_api_keys":{"type":"integer","format":"int32","example":1},"max_file_size":{"type":"integer","format":"int64","example":5242880},"name":{"type":"string","example":"免费"},"period":{"type":"string","example":"month"},"quota":{"type":"integer","format":"int32","example":50},"retention_hours":{"type":"integer","format":"int32","example":24}}},"QuotaView":{"type":"object","required":["period_key","limit","used","held","remaining","resets_at"],"properties":{"held":{"type":"integer","format":"int32","example":0},"limit":{"type":"integer","format":"int32","example":50},"period_key":{"type":"string","example":"2026-09"},"remaining":{"type":"integer","format":"int32","example":43},"resets_at":{"type":"string","example":"2026-10-01T00:00:00+08:00"},"used":{"type":"integer","format":"int32","example":7}}},"TaskStatusView":{"type":"object","required":["task_id","status","progress","source","kind","original_name","original_size","quota_units","no_gain","created_at","downloadable"],"properties":{"completed_at":{"type":["integer","null"],"format":"int64","example":1691234600},"compressed_size":{"type":["integer","null"],"format":"int64","example":512000,"minimum":0},"compressed_url":{"type":["string","null"],"example":"/v1/images/download/550e8400-e29b-41d4-a716-446655440000.png"},"created_at":{"type":"integer","format":"int64","example":1691234567},"downloadable":{"type":"boolean"},"error_msg":{"type":["string","null"]},"expires_at":{"type":["integer","null"],"format":"int64","example":1691321000},"kind":{"type":"string","example":"compress"},"no_gain":{"type":"boolean"},"original_name":{"type":"string","example":"photo.png"},"original_size":{"type":"integer","format":"int64","example":1024000,"minimum":0},"output_format":{"type":["string","null"],"example":"png"},"progress":{"type":"integer","format":"int32","example":100,"minimum":0},"queue_position":{"type":["integer","null"],"format":"int64","example":1},"quota_units":{"type":"integer","format":"int32","example":1},"scale":{"type":["string","null"],"example":"x4"},"source":{"type":"string","example":"web"},"status":{"type":"string","example":"completed"},"target_format":{"type":["string","null"],"example":"webp"},"task_id":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"}}},"UploadForm":{"type":"object","required":["file"],"properties":{"background":{"type":["string","null"],"example":"#ffffff"},"convert":{"type":["string","null"],"example":"webp"},"file":{"type":"string","format":"binary"}}},"UploadResponse":{"type":"object","required":["task_id"],"properties":{"task_id":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"}}},"UpscaleForm":{"type":"object","required":["file","scale"],"properties":{"file":{"type":"string","format":"binary"},"scale":{"type":"string","example":"x4"}}},"VerifyRequest":{"type":"object","required":["email","code"],"properties":{"code":{"type":"string","example":"482913"},"email":{"type":"string","example":"you@example.com"}}},"VerifyResponse":{"type":"object","required":["email","plan_id","created"],"properties":{"created":{"type":"boolean"},"email":{"type":"string"},"plan_id":{"type":"string","example":"free"}}},"VisitRequest":{"type":"object","required":["path"],"properties":{"path":{"type":"string","example":"/pricing"},"referrer_host":{"type":["string","null"],"example":"www.v2ex.com"},"utm_campaign":{"type":["string","null"],"example":"cli-launch"},"utm_medium":{"type":["string","null"],"example":"post"},"utm_source":{"type":["string","null"],"example":"v2ex"}}}},"securitySchemes":{"api_key":{"type":"http","scheme":"bearer","bearerFormat":"lp_live_…"}}},"tags":[{"name":"图片压缩","description":"上传、状态查询与下载；网页、API、CLI 共用一份额度"},{"name":"图片放大","description":"上传静态图片按 x2 或 x4 放大，输出 PNG；与压缩共用一份额度，失败不计次"},{"name":"账号","description":"邮箱验证码登录、API Key 与本期额度"},{"name":"埋点","description":"网页访问事件，服务端补齐身份、IP 与 UA"}]}