{"openapi":"3.0.3","info":{"title":"GangasLive — La Ganga API","description":"API REST del MVP de La Ganga (live shopping con subastas). Las pujas y el chat van por **WebSocket** (`wss://ws.laganga.live`, §10), no por REST. Pagos: Stripe (tarjeta, cobro silencioso) + SPIDI (Pago Móvil Bs por cédula, enrolamiento embebido + `pay_url` en iframe). Referencias §N = secciones del spec v4.2. Nota: los fallos de dependencias externas se devuelven como **424** (no 5xx) para que el proxy no los enmascare.","version":"0.4.0","contact":{"name":"LaGanga Soporte","email":"soporte@laganga.live","url":"https://laganga.live/contact"},"termsOfService":"https://laganga.live/terminos"},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{}},"paths":{"/health":{"get":{"responses":{"200":{"description":"Default Response"}},"operationId":"getHealth","description":"GET /health","summary":"GET /health"}},"/auth/register":{"post":{"summary":"Registrar comprador (email o teléfono + contraseña)","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"email":{"type":"string","format":"email"},"phone":{"type":"string"},"username":{"type":"string","minLength":3,"maxLength":30,"pattern":"^[a-zA-Z0-9_.]+$"},"password":{"type":"string","minLength":8},"display_name":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthRegister","description":"Registrar comprador (email o teléfono + contraseña)"}},"/auth/login":{"post":{"summary":"Iniciar sesión y obtener JWT","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"email":{"type":"string","format":"email"},"phone":{"type":"string"},"username":{"type":"string"},"identifier":{"type":"string"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthLogin","description":"Iniciar sesión y obtener JWT"}},"/auth/username-available":{"get":{"summary":"¿Username disponible? (+ sugerencias si está tomado)","tags":["Auth"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"username","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"available":{"type":"boolean"},"valid":{"type":"boolean"},"suggestions":{"type":"array","items":{"type":"string"}}}}}}}},"operationId":"getAuthUsernameAvailable","description":"¿Username disponible? (+ sugerencias si está tomado)"}},"/auth/refresh":{"post":{"summary":"Renovar el access con el refresh (rotación segura)","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthRefresh","description":"Renovar el access con el refresh (rotación segura)"}},"/auth/verify":{"post":{"summary":"Verificar cuenta (fase 2 — no implementado en el MVP)","tags":["Auth"],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthVerify","description":"Verificar cuenta (fase 2 — no implementado en el MVP)"}},"/auth/otp/request":{"post":{"summary":"Pedir código OTP por WhatsApp","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["phone"],"properties":{"phone":{"type":"string","minLength":7}}}}}},"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthOtpRequest","description":"Pedir código OTP por WhatsApp"}},"/auth/otp/verify":{"post":{"summary":"Verificar OTP → JWT (crea la cuenta por teléfono si no existe)","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["phone","code"],"properties":{"phone":{"type":"string"},"code":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthOtpVerify","description":"Verificar OTP → JWT (crea la cuenta por teléfono si no existe)"}},"/auth/phone/send-code":{"post":{"summary":"Enviar código por WhatsApp para verificar mi teléfono","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["phone"],"properties":{"phone":{"type":"string","minLength":7}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthPhoneSendCode","description":"Enviar código por WhatsApp para verificar mi teléfono"}},"/auth/phone/verify":{"post":{"summary":"Verificar mi teléfono con el código → lo pega a mi cuenta","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["phone","code"],"properties":{"phone":{"type":"string"},"code":{"type":"string"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthPhoneVerify","description":"Verificar mi teléfono con el código → lo pega a mi cuenta"}},"/auth/stepup/request":{"post":{"summary":"Iniciar verificación dual (código al correo + código al WhatsApp actual)","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["change_cedula","change_phone","settlement_method"]}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthStepupRequest","description":"Iniciar verificación dual (código al correo + código al WhatsApp actual)"}},"/auth/stepup/verify":{"post":{"summary":"Verificar los códigos duales → step-up token (10 min, scope=action)","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["stepup_id"],"properties":{"stepup_id":{"type":"string","format":"uuid"},"email_code":{"type":"string"},"phone_code":{"type":"string"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuthStepupVerify","description":"Verificar los códigos duales → step-up token (10 min, scope=action)"}},"/auth/forgot-password":{"post":{"summary":"Pedir restablecer contraseña (link por email o código por WhatsApp)","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"phone":{"type":"string","minLength":7}}}}}},"responses":{"200":{"description":"Siempre neutro (no revela si la cuenta existe)","content":{"application/json":{"schema":{"type":"object","description":"Siempre neutro (no revela si la cuenta existe)","properties":{"ok":{"type":"boolean"},"dev_token":{"type":"string","description":"Solo en dev/local: token de reset (email) si no hubo envío real"},"dev_code":{"type":"string","description":"Solo en dev/local: código de reset (WhatsApp) si no hubo envío real"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postAuthForgotPassword","description":"Pedir restablecer contraseña (link por email o código por WhatsApp)"}},"/auth/reset-password":{"post":{"summary":"Fijar contraseña nueva con el token (email) o código (WhatsApp)","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"token":{"type":"string","description":"Del link de email"},"phone":{"type":"string","description":"Si el reset fue por WhatsApp"},"code":{"type":"string","description":"Código de 6 dígitos (WhatsApp)"},"password":{"type":"string","minLength":8}}}}}},"responses":{"200":{"description":"Contraseña cambiada; deja logueado con sesión nueva (salvo cuenta suspendida)","content":{"application/json":{"schema":{"type":"object","description":"Contraseña cambiada; deja logueado con sesión nueva (salvo cuenta suspendida)","properties":{"ok":{"type":"boolean"},"user_id":{"type":"string","format":"uuid"},"token":{"type":"string","description":"Access JWT nuevo"},"refresh_token":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"token_invalido_o_expirado | token_o_phone_code_requerido"}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"demasiados_intentos"}}}}}}},"operationId":"postAuthResetPassword","description":"Fijar contraseña nueva con el token (email) o código (WhatsApp)"}},"/me":{"get":{"summary":"Ver mi perfil (incl. is_admin y spidi_enrolled)","tags":["Perfil"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"phoneNumber":{"type":"string","nullable":true,"description":"alias de phone"},"username":{"type":"string","nullable":true},"gender":{"type":"string","nullable":true,"description":"female|male|other|prefer_not_to_say"},"categories":{"type":"array","items":{"type":"string"},"description":"slugs de categorías de interés"},"role":{"type":"string","enum":["buyer","seller","admin","super_admin"]},"displayName":{"type":"string","nullable":true},"bio":{"type":"string","nullable":true},"avatarUrl":{"type":"string","nullable":true},"coverUrl":{"type":"string","nullable":true},"display_name":{"type":"string","nullable":true},"avatar_url":{"type":"string","nullable":true},"cover_url":{"type":"string","nullable":true},"buyer_verified":{"type":"boolean","description":"Teléfono verificado + SPIDI enrolado (v-115)"},"is_seller":{"type":"boolean","description":"role=seller o admin — gatea 'Ir en vivo' en el front (v-127)"},"cedulaType":{"type":"string","nullable":true},"cedulaNumber":{"type":"string","nullable":true},"phone_verified":{"type":"boolean","description":"Teléfono verificado por WhatsApp OTP"},"is_admin":{"type":"boolean"},"spidi_enrolled":{"type":"boolean","description":"Pagador SPIDI verificado (puede pujar en Bs)"},"kyc_status":{"type":"string","description":"none|pending|approved|rejected"},"entitlements":{"type":"object","description":"Entitlements activos (RevenueCat). Booleanos derivados de *_until.","properties":{"ganga_plus":{"type":"boolean","description":"Comprador premium: sin ads, badge, alertas, discovery"},"seller_pro":{"type":"boolean","description":"Vendedor premium: más lives/productos, analytics, destacado, badge"},"no_ads":{"type":"boolean","description":"Sin publicidad (incluido en ganga_plus o Remove Ads suelto)"}}},"bidding_blocked":{"type":"boolean","description":"v-144: true = tiene órdenes expiradas sin pagar → no puede pujar (paga la vencida y se desbloquea solo)"},"blocked_reason":{"type":"string","nullable":true,"enum":["impago",null],"description":"Motivo del bloqueo (v-144)"},"strikes":{"type":"integer","description":"Órdenes expiradas sin pagar (v-144)"},"completion_rate":{"type":"integer","nullable":true,"description":"v-146: % órdenes completadas vs fallidas (impago); null sin historial"},"orders_completed":{"type":"integer"},"orders_failed":{"type":"integer"},"win_pay_preference":{"type":"string","enum":["auto_card","ask"],"description":"v-143: auto_card = cobro silencioso al ganar · ask = selector Bs/USD"},"plus_until":{"type":"string","format":"date-time","nullable":true,"description":"Expiración Ganga+ (ISO) o null"},"seller_pro_until":{"type":"string","format":"date-time","nullable":true,"description":"Expiración Seller Pro (ISO) o null"},"shipping_address":{"type":"object","nullable":true,"additionalProperties":true},"verification":{"type":"object","description":"Checklist de verificación por etapas (gating del vendedor)","properties":{"phone":{"type":"string","enum":["complete","action_needed","pending"]},"settlement_method":{"type":"string","enum":["complete","action_needed","pending"]},"identity":{"type":"string","enum":["complete","action_needed","pending"]},"live_review":{"type":"string","enum":["complete","action_needed","pending"]}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"getMe","description":"Ver mi perfil (incl. is_admin y spidi_enrolled)"},"patch":{"summary":"Actualizar perfil, incl. cédula para SPIDI (§9.0, blindada por antifraude)","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"display_name":{"type":["string","null"]},"username":{"type":"string","minLength":3,"maxLength":30,"pattern":"^[a-zA-Z0-9_.]+$"},"bio":{"type":["string","null"],"maxLength":500},"avatar_url":{"type":["string","null"],"maxLength":500},"cover_url":{"type":["string","null"],"maxLength":500},"gender":{"type":"string","enum":["female","male","other","prefer_not_to_say"]},"categories":{"type":"array","maxItems":50,"items":{"type":"string","maxLength":40},"description":"slugs del catálogo (GET /categories). Deben existir/activas o devuelve 400."},"phone":{"type":"string"},"phone_number":{"type":"string"},"cedula_type":{"type":"string","enum":["V","E"]},"cedula_number":{"type":"string"},"win_pay_preference":{"type":"string","enum":["auto_card","ask"]},"shipping_address":{"type":"object","description":"Dirección de envío (v-93): el vendedor despacha a esta","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":20},"state":{"type":"string","maxLength":40},"city":{"type":"string","maxLength":60},"address":{"type":"string","maxLength":240},"reference":{"type":"string","maxLength":160},"mrw_agency":{"type":"boolean"}}}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"patchMe","description":"Actualizar perfil, incl. cédula para SPIDI (§9.0, blindada por antifraude)"},"delete":{"summary":"Eliminar mi cuenta: anonimiza la PII y revoca todas las sesiones (v-127)","tags":["Perfil"],"description":"email → deleted+<id>@laganga.invalid; teléfono/nombre/username/avatar/cédula/dirección limpiados; contraseña invalidada; refresh tokens revocados; push subscriptions y pagador SPIDI borrados. Las órdenes/lives/reviews se conservan anonimizadas. Idempotente: 400 si ya eliminada.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"deleteMe"}},"/me/notifications":{"get":{"summary":"Mis preferencias de notificación por categoría (sin fila = todo ON)","tags":["Perfil"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getMeNotifications","description":"Mis preferencias de notificación por categoría (sin fila = todo ON)"},"patch":{"summary":"Actualizar una preferencia de notificación","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["category"],"properties":{"category":{"type":"string","enum":["auctions","purchases","followed","promotional","sales","payouts","social"]},"push":{"type":"boolean"},"email":{"type":"boolean"},"in_app":{"type":"boolean"},"sms":{"type":"boolean"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"patchMeNotifications","description":"Actualizar una preferencia de notificación"}},"/me/notifications/feed":{"get":{"summary":"Feed in-app (campana): notificaciones recibidas + no leídas (v-108)","tags":["Perfil"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":30},"in":"query","name":"limit","required":false},{"schema":{"type":"boolean","default":false},"in":"query","name":"unread_only","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getMeNotificationsFeed","description":"Feed in-app (campana): notificaciones recibidas + no leídas (v-108)"}},"/me/notifications/read":{"post":{"summary":"Marcar notificación(es) in-app como leídas (v-108)","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Omitir = marca todas"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postMeNotificationsRead","description":"Marcar notificación(es) in-app como leídas (v-108)"}},"/seller/apply":{"post":{"summary":"Solicitar ser vendedor (KYC pending, aprobación manual en MVP)","tags":["Vendedor"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"display_name":{"type":"string"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellerApply","description":"Solicitar ser vendedor (KYC pending, aprobación manual en MVP)"}},"/seller/kyc/start":{"post":{"summary":"Iniciar verificación de identidad (Didit) → { url }","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"session_id":{"type":"string"}}}}}},"424":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postSellerKycStart","description":"Iniciar verificación de identidad (Didit) → { url }"}},"/seller/kyc-status":{"get":{"summary":"Consultar estado de KYC","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerKycStatus","description":"Consultar estado de KYC"}},"/seller/statement":{"get":{"summary":"Mi estado de cuenta (ventas por período)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerStatement","description":"Mi estado de cuenta (ventas por período)"}},"/seller/balance":{"get":{"summary":"Saldo: disponible / en proceso (Bs)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerBalance","description":"Saldo: disponible / en proceso (Bs)"}},"/seller/ledger":{"get":{"summary":"Movimientos: ventas, comisiones y retiros (más reciente primero)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerLedger","description":"Movimientos: ventas, comisiones y retiros (más reciente primero)"}},"/seller/payouts":{"get":{"summary":"Historial de retiros","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerPayouts","description":"Historial de retiros"},"post":{"summary":"Iniciar retiro del saldo disponible","tags":["Vendedor"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount_bs":{"type":"number","exclusiveMinimum":0}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellerPayouts","description":"Iniciar retiro del saldo disponible"}},"/seller/payouts/{id}/cancel":{"post":{"summary":"Cancelar un retiro no dispersado (libera el saldo)","tags":["Vendedor"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellerPayoutsByIdCancel","description":"Cancelar un retiro no dispersado (libera el saldo)"}},"/seller/settlement-method":{"post":{"summary":"Registrar método de cobro (banco/Pago Móvil para retiros)","tags":["Vendedor"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bank"],"properties":{"bank":{"type":"string","minLength":2,"maxLength":60},"bank_code":{"type":"string","maxLength":10,"description":"código SUDEBAN de 4 dígitos (p.ej. 0102)"},"account_type":{"type":"string","enum":["pago_movil","cuenta","debito_inmediato"],"default":"pago_movil","description":"debito_inmediato (v-137b) exige bank_code + cédula + teléfono (la cuenta NO — el riel identifica por identidad, cf. Farmatodo)"},"account":{"type":"string","maxLength":30,"description":"nº de cuenta (20 dígitos, OPCIONAL en debito_inmediato) o teléfono Pago Móvil"},"account_kind":{"type":"string","enum":["corriente","ahorro"],"description":"tipo de cuenta (solo si mandás cuenta)"},"phone":{"type":"string","maxLength":20,"description":"REQUERIDO en debito_inmediato (0412..., se normaliza a 58...)"},"holder_name":{"type":"string","maxLength":80},"holder_cedula":{"type":"string","maxLength":15,"description":"V-/E-/J- + número"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellerSettlementMethod","description":"Registrar método de cobro (banco/Pago Móvil para retiros)"},"get":{"summary":"Mi método de cobro (enmascarado)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerSettlementMethod","description":"Mi método de cobro (enmascarado)"}},"/seller/orders":{"get":{"summary":"Mis ventas (para despachar): status, tracking, recibo","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerOrders","description":"Mis ventas (para despachar): status, tracking, recibo"}},"/seller/health":{"get":{"summary":"Salud de cuenta: desempeño (despacho, disputas, rating, standing) — v-105","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerHealth","description":"Salud de cuenta: desempeño (despacho, disputas, rating, standing) — v-105"}},"/seller/shipping-tiers":{"get":{"summary":"Mis tiers de envío por peso (v-116)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerShippingTiers","description":"Mis tiers de envío por peso (v-116)"},"put":{"summary":"Fijar mis tiers de envío por peso (reemplaza todos) (v-116)","tags":["Vendedor"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tiers"],"properties":{"tiers":{"type":"array","maxItems":30,"items":{"type":"object","required":["max_weight_g","price_usd"],"properties":{"max_weight_g":{"type":"integer","minimum":1,"maximum":100000},"price_usd":{"type":"string"}}}}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"putSellerShippingTiers","description":"Fijar mis tiers de envío por peso (reemplaza todos) (v-116)"}},"/seller/veb-merchant":{"get":{"summary":"Estado de mi merchant en VE Banking (payouts automáticos)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerVebMerchant","description":"Estado de mi merchant en VE Banking (payouts automáticos)"}},"/seller/veb-merchant/sync":{"post":{"summary":"Re-dar de alta / sincronizar mi merchant (idempotente)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellerVebMerchantSync","description":"Re-dar de alta / sincronizar mi merchant (idempotente)"}},"/seller/veb-merchant/verify/start":{"post":{"summary":"Iniciar verificación (2 microabonos de céntimos)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellerVebMerchantVerifyStart","description":"Iniciar verificación (2 microabonos de céntimos)"}},"/seller/veb-merchant/verify":{"post":{"summary":"Confirmar los 2 montos de los microabonos","tags":["Vendedor"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount1","amount2"],"properties":{"amount1":{"type":["string","number"],"description":"1er microabono (0.01–0.99)"},"amount2":{"type":["string","number"],"description":"2º microabono (0.01–0.99)"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellerVebMerchantVerify","description":"Confirmar los 2 montos de los microabonos"}},"/sellers/{id}":{"get":{"summary":"Perfil público de un vendedor (storefront). :id = uuid O username (v-124) + listings","tags":["Vendedor"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"user_id (uuid) o @username (sin @)"}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellersById","description":"Perfil público de un vendedor (storefront). :id = uuid O username (v-124) + listings"}},"/sellers/{id}/follow":{"post":{"summary":"Seguir a un vendedor (v-93: {notifications:'all'|'none'} para el 🔔 está-en-vivo)","tags":["Vendedor"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"notifications":{"type":"string","enum":["all","none"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellersByIdFollow","description":"Seguir a un vendedor (v-93: {notifications:'all'|'none'} para el 🔔 está-en-vivo)"}},"/sellers/{id}/unfollow":{"post":{"summary":"Dejar de seguir a un vendedor","tags":["Vendedor"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellersByIdUnfollow","description":"Dejar de seguir a un vendedor"}},"/sellers/{id}/support":{"post":{"summary":"Apoyar a un vendedor (cheer): {count} opcional — heart=1, gift=10","tags":["Vendedor"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer","minimum":1,"maximum":100,"default":1}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellersByIdSupport","description":"Apoyar a un vendedor (cheer): {count} opcional — heart=1, gift=10"}},"/sellers/{id}/block":{"post":{"summary":"Bloquear a un vendedor/usuario (oculta sus lives y productos)","tags":["Vendedor"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSellersByIdBlock","description":"Bloquear a un vendedor/usuario (oculta sus lives y productos)"},"delete":{"summary":"Desbloquear","tags":["Vendedor"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteSellersByIdBlock","description":"Desbloquear"}},"/sellers/blocked":{"get":{"summary":"Mis usuarios bloqueados","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellersBlocked","description":"Mis usuarios bloqueados"}},"/products/":{"get":{"summary":"Listar mis productos (del vendedor del JWT). ?status filtra por estado.","tags":["Productos"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"status","required":false,"description":"Filtrar por estado (ready|live|sold|paid|shipped|unsold|cancelled)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"condition":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"price_usd":{"type":"string","nullable":true},"starting_usd":{"type":"string","nullable":true,"description":"Piso de subasta cronometrada"},"shipping_usd":{"type":"string","nullable":true,"description":"Estimado MRW (se paga al recibir)"},"video_url":{"type":"string","nullable":true},"for_sale":{"type":"boolean"},"sale_mode":{"type":"string","description":"fixed | timed_auction | giveaway"},"status":{"type":"string","description":"ready|live|sold|paid|shipped|unsold|cancelled"},"stock":{"type":"integer"},"photos":{"type":"array","items":{"type":"string"}},"order_id":{"type":"string","format":"uuid","nullable":true},"sold_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}}}}}}},"operationId":"getProducts","description":"Listar mis productos (del vendedor del JWT). ?status filtra por estado."},"post":{"summary":"Crear producto: precio fijo (buy-now) o subasta cronometrada (§B)","tags":["Productos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"condition":{"type":"string"},"description":{"type":"string","description":"Descripción larga del ítem (v-130)"},"photos":{"type":"array","items":{"type":"string"}},"price_usd":{"type":"string","description":"Buy-It-Now opcional"},"shipping_usd":{"type":"string","description":"Estimado envío MRW (informativo)"},"video_url":{"type":"string","description":"Video del producto (loop TikTok, v-92)"},"for_sale":{"type":"boolean","description":"Gangas directas: compra sin live (requiere price_usd)"},"stock":{"type":"integer","minimum":0,"maximum":9999},"product_type":{"type":"string","maxLength":40,"description":"Taxonomía del ítem (single|bundle|sealed|slab|...)"},"temporary_hours":{"type":"number","minimum":1,"maximum":8760,"description":"Si se define, el listado es TEMPORAL y se auto-oculta al vencer"},"weight_g":{"type":"integer","minimum":0,"maximum":100000,"description":"Peso en g → estimado de envío por tiers si no mandás shipping_usd"},"barcode":{"type":"string","maxLength":64,"description":"Código de barras / slab (scan)"},"sale_mode":{"type":"string","enum":["fixed","timed_auction"],"description":"timed_auction = subasta con reloj"},"starting_usd":{"type":"string","description":"Puja inicial (piso) — requerido si timed_auction"},"ends_in_hours":{"type":"number","description":"Duración en horas (default 24, máx 168)"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postProducts","description":"Crear producto: precio fijo (buy-now) o subasta cronometrada (§B)"}},"/products/marketplace":{"get":{"summary":"Alias del feed de Gangas directas (público)","tags":["Marketplace"],"responses":{"200":{"description":"Default Response"}},"operationId":"getProductsMarketplace","description":"Alias del feed de Gangas directas (público)"}},"/products/{id}/buy":{"post":{"summary":"Alias: comprar ya (Gangas directas)","tags":["Marketplace"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"order_id":{"type":"string"},"amount_ref_usd":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postProductsByIdBuy","description":"Alias: comprar ya (Gangas directas)"}},"/products/{id}/bids":{"post":{"summary":"Pujar en una Ganga directa cronometrada (timed auction)","tags":["Marketplace"],"description":"Mismo motor que el live (CAS atómico en Redis + anti-snipe). Requiere método de pago listo. Nadie paga por pujar: solo el ganador al cierre (lo cobra el worker).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_usd"],"properties":{"amount_usd":{"type":"string","description":"monto en USD, ej '4.00'"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"auction_id":{"type":"string"},"current_bid_usd":{"type":"string"},"min_next_usd":{"type":"string"},"ends_at":{"type":"string","format":"date-time","nullable":true},"bid_count":{"type":"integer"}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"min_next_usd":{"type":"string"}}}}}}},"operationId":"postProductsByIdBids"}},"/products/{id}":{"get":{"summary":"Ver producto (público). Si es timed auction, trae current_bid_usd/ends_at/bid_count.","tags":["Productos"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"getProductsById","description":"Ver producto (público). Si es timed auction, trae current_bid_usd/ends_at/bid_count."},"patch":{"summary":"Editar producto (solo el vendedor dueño). for_sale:false = pausar sin borrar","tags":["Productos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"condition":{"type":["string","null"]},"description":{"type":["string","null"]},"photos":{"type":"array","items":{"type":"string"}},"price_usd":{"type":["string","null"]},"starting_usd":{"type":["string","null"],"description":"Piso de subasta (solo inventario, no en subasta activa)"},"shipping_usd":{"type":["string","null"]},"video_url":{"type":["string","null"]},"for_sale":{"type":"boolean","description":"false = pausar el listado (Inventory, sale del feed sin borrarlo)"},"stock":{"type":"integer","minimum":0},"product_type":{"type":["string","null"]},"weight_g":{"type":["integer","null"],"minimum":0},"barcode":{"type":["string","null"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"patchProductsById","description":"Editar producto (solo el vendedor dueño). for_sale:false = pausar sin borrar"},"delete":{"summary":"Borrar un producto propio (soft-delete: sale de los feeds) (v-121)","tags":["Productos"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteProductsById","description":"Borrar un producto propio (soft-delete: sale de los feeds) (v-121)"}},"/products/{id}/comments":{"get":{"summary":"Comentarios de un producto (público, más reciente primero) (v-124)","tags":["Productos"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":30},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"offset","required":false},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"user_id":{"type":"string","format":"uuid"},"username":{"type":"string","nullable":true},"user_display":{"type":"string"},"avatar_url":{"type":"string","nullable":true},"text":{"type":"string"},"created_at":{"type":"string"}}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"getProductsByIdComments","description":"Comentarios de un producto (público, más reciente primero) (v-124)"},"post":{"summary":"Comentar un producto (v-124)","tags":["Productos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","minLength":1,"maxLength":500}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"user_id":{"type":"string","format":"uuid"},"username":{"type":"string","nullable":true},"user_display":{"type":"string"},"avatar_url":{"type":"string","nullable":true},"text":{"type":"string"},"created_at":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postProductsByIdComments","description":"Comentar un producto (v-124)"}},"/products/{id}/comments/{commentId}":{"delete":{"summary":"Borrar un comentario (el autor o el vendedor dueño del producto) (v-124)","tags":["Productos"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"commentId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteProductsByIdCommentsByCommentid","description":"Borrar un comentario (el autor o el vendedor dueño del producto) (v-124)"}},"/products/{id}/duplicate":{"post":{"summary":"Duplicar un producto propio como listado nuevo (import-from-inventory, v-107)","tags":["Productos"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postProductsByIdDuplicate","description":"Duplicar un producto propio como listado nuevo (import-from-inventory, v-107)"}},"/products/by-barcode/{code}":{"get":{"summary":"Buscar un producto propio por código de barras (v-117)","tags":["Productos"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getProductsByBarcodeByCode","description":"Buscar un producto propio por código de barras (v-117)"}},"/private-gangas/":{"post":{"summary":"Crear ganga privada (alto monto, oculta del feed; buy_now o auction)","tags":["Gangas Privadas"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","mode"],"properties":{"title":{"type":"string"},"condition":{"type":"string"},"photos":{"type":"array","items":{"type":"string"}},"video_url":{"type":"string"},"shipping_usd":{"type":"string"},"mode":{"type":"string","enum":["buy_now","auction"]},"access_mode":{"type":"string","enum":["open","approval"],"default":"open"},"price_usd":{"type":"string","description":"requerido si buy_now"},"starting_usd":{"type":"string","description":"requerido si auction"},"ends_in_hours":{"type":"number","description":"auction: default 24, máx 168"},"live_id":{"type":"string","format":"uuid","description":"opcional: dentro de un live"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postPrivateGangas","description":"Crear ganga privada (alto monto, oculta del feed; buy_now o auction)"}},"/private-gangas/join":{"post":{"summary":"Entrar a una ganga privada con su código (open = ya; approval = solicitud)","tags":["Gangas Privadas"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postPrivateGangasJoin","description":"Entrar a una ganga privada con su código (open = ya; approval = solicitud)"}},"/private-gangas/mine":{"get":{"summary":"Mis gangas privadas (vendedor)","tags":["Gangas Privadas"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getPrivateGangasMine","description":"Mis gangas privadas (vendedor)"}},"/private-gangas/{code}":{"get":{"summary":"Ver una ganga privada por código (miembro aprobado o dueño)","tags":["Gangas Privadas"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getPrivateGangasByCode","description":"Ver una ganga privada por código (miembro aprobado o dueño)"}},"/private-gangas/{id}/bids":{"post":{"summary":"Pujar en una ganga privada (auction; miembro aprobado)","tags":["Gangas Privadas"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_usd"],"properties":{"amount_usd":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postPrivateGangasByIdBids","description":"Pujar en una ganga privada (auction; miembro aprobado)"}},"/private-gangas/{id}/buy":{"post":{"summary":"Comprar ya una ganga privada (buy_now; miembro aprobado)","tags":["Gangas Privadas"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postPrivateGangasByIdBuy","description":"Comprar ya una ganga privada (buy_now; miembro aprobado)"}},"/private-gangas/{id}/requests":{"get":{"summary":"Solicitudes de acceso pendientes (dueño)","tags":["Gangas Privadas"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getPrivateGangasByIdRequests","description":"Solicitudes de acceso pendientes (dueño)"}},"/private-gangas/{id}/requests/{userId}/approve":{"post":{"summary":"Aprobar solicitud (dueño)","tags":["Gangas Privadas"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"userId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postPrivateGangasByIdRequestsByUseridApprove","description":"Aprobar solicitud (dueño)"}},"/private-gangas/{id}/requests/{userId}/reject":{"post":{"summary":"Rechazar solicitud (dueño)","tags":["Gangas Privadas"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"userId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postPrivateGangasByIdRequestsByUseridReject","description":"Rechazar solicitud (dueño)"}},"/private-gangas/{id}/close":{"post":{"summary":"Cerrar la ganga (dueño). Si es subasta, fuerza el cierre (el worker consolida).","tags":["Gangas Privadas"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postPrivateGangasByIdClose","description":"Cerrar la ganga (dueño). Si es subasta, fuerza el cierre (el worker consolida)."}},"/invites/":{"post":{"summary":"Crear link de invitación (auto = entra directo | approval = con aprobación) (v-125)","tags":["Invitaciones"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["auto","approval"]},"note":{"type":"string","maxLength":200}}}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"share_url":{"type":"string"},"mode":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postInvites","description":"Crear link de invitación (auto = entra directo | approval = con aprobación) (v-125)"}},"/invites/mine":{"get":{"summary":"Mis links de invitación con entrados/pendientes (v-125)","tags":["Invitaciones"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"share_url":{"type":"string"},"mode":{"type":"string"},"status":{"type":"string"},"joined_count":{"type":"integer"},"pending_count":{"type":"integer"},"created_at":{"type":"string"}}}}}}}},"operationId":"getInvitesMine","description":"Mis links de invitación con entrados/pendientes (v-125)"}},"/invites/join":{"post":{"summary":"Unirse con un código: auto → joined | approval → pending (v-125)","tags":["Invitaciones"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string","minLength":4,"maxLength":40}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["joined","pending"]}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"410":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postInvitesJoin","description":"Unirse con un código: auto → joined | approval → pending (v-125)"}},"/invites/{id}/requests":{"get":{"summary":"Solicitudes pendientes de una invitación (dueño) (v-125)","tags":["Invitaciones"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","format":"uuid"},"display_name":{"type":"string","nullable":true},"username":{"type":"string","nullable":true},"created_at":{"type":"string"}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"getInvitesByIdRequests","description":"Solicitudes pendientes de una invitación (dueño) (v-125)"}},"/invites/{id}/requests/{userId}/approve":{"post":{"summary":"Aprobar solicitud → joined + push al comprador (v-125)","tags":["Invitaciones"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"userId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postInvitesByIdRequestsByUseridApprove","description":"Aprobar solicitud → joined + push al comprador (v-125)"}},"/invites/{id}/requests/{userId}/reject":{"post":{"summary":"Rechazar solicitud (v-125)","tags":["Invitaciones"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"userId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postInvitesByIdRequestsByUseridReject","description":"Rechazar solicitud (v-125)"}},"/invites/{id}/close":{"post":{"summary":"Cerrar la invitación: el link deja de aceptar joins (v-125)","tags":["Invitaciones"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postInvitesByIdClose","description":"Cerrar la invitación: el link deja de aceptar joins (v-125)"}},"/lives/":{"get":{"summary":"Listado de lives: paginado, ordenable y con búsqueda (público)","tags":["Lives"],"description":"Home por defecto (status=scheduled,live ordenado por created_at desc). Soporta limit/offset (paginación; total en el header X-Total-Count), sort/sort_direction, y search sobre search_fields (title,seller,category,notes).","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"offset","required":false},{"schema":{"type":"string","enum":["created_at","started_at","scheduled_at","title","viewers"],"default":"created_at"},"in":"query","name":"sort","required":false},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sort_direction","required":false},{"schema":{"type":"string","maxLength":100},"in":"query","name":"search","required":false,"description":"texto libre (ILIKE)"},{"schema":{"type":"string"},"in":"query","name":"search_fields","required":false,"description":"campos donde buscar, coma-separado: title,seller,category,notes (default: title,seller)"},{"schema":{"type":"string"},"in":"query","name":"category","required":false,"description":"filtra por categoría (v-64)"},{"schema":{"type":"boolean","default":false},"in":"query","name":"followed_only","required":false,"description":"Followed Hosts: solo vendedores que sigo (requiere token) (v-113)"},{"schema":{"type":"string"},"in":"query","name":"status","required":false,"description":"estados coma-separado: scheduled,live,ended,canceled (default: scheduled,live)"}],"responses":{"200":{"description":"Default Response"}},"operationId":"getLives"},"post":{"summary":"Crear live (genera sala LiveKit única)","tags":["Lives"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"cover_url":{"type":"string"},"category":{"type":"string"},"notes":{"type":"string","maxLength":2000,"description":"Show Notes (nota fija del show)"},"scheduled_at":{"type":"string","format":"date-time"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postLives","description":"Crear live (genera sala LiveKit única)"}},"/lives/{id}":{"get":{"summary":"Detalle de un live (público; con Bearer trae is_following)","tags":["Lives"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"getLivesById","description":"Detalle de un live (público; con Bearer trae is_following)"},"patch":{"summary":"Editar live: título/portada/categoría/Show Notes (solo el dueño)","tags":["Lives"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"cover_url":{"type":"string"},"category":{"type":"string"},"notes":{"type":"string","maxLength":2000}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"patchLivesById","description":"Editar live: título/portada/categoría/Show Notes (solo el dueño)"}},"/lives/{id}/start":{"post":{"summary":"Iniciar transmisión (solo el dueño)","tags":["Lives"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postLivesByIdStart","description":"Iniciar transmisión (solo el dueño)"}},"/lives/{id}/end":{"post":{"summary":"Finalizar transmisión (solo el dueño)","tags":["Lives"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postLivesByIdEnd","description":"Finalizar transmisión (solo el dueño)"}},"/lives/{id}/lots":{"get":{"summary":"Lotes de un show: subasta/buy_now/giveaway con estado y puja actual (público)","tags":["Lives"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"getLivesByIdLots","description":"Lotes de un show: subasta/buy_now/giveaway con estado y puja actual (público)"}},"/lives/schedule":{"post":{"summary":"Programar N shows de una vez desde una lista de fechas (v-99)","tags":["Lives"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["dates"],"properties":{"title":{"type":"string"},"category":{"type":"string"},"cover_url":{"type":"string"},"notes":{"type":"string"},"dates":{"type":"array","items":{"type":"string","format":"date-time"},"minItems":1,"maxItems":30}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postLivesSchedule","description":"Programar N shows de una vez desde una lista de fechas (v-99)"}},"/gifts":{"get":{"summary":"Catálogo de regalos del live con su costo en coins (v-160)","tags":["Live"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"label":{"type":"string"},"icon":{"type":"string"},"coins":{"type":"integer","description":"costo en coins (v-160)"},"value":{"type":"integer","description":"puntos del contador simbólico del live"}}}}}}}},"operationId":"getGifts","description":"Catálogo de regalos del live con su costo en coins (v-160)"}},"/auctions/":{"post":{"summary":"Crear un lote bajo un live: subasta o precio fijo (buy_now, v-66)","tags":["Auction Engine"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["live_id","product_id"],"properties":{"live_id":{"type":"string","format":"uuid"},"product_id":{"type":"string","format":"uuid"},"format":{"type":"string","enum":["auction","buy_now"],"default":"auction"},"timer_type":{"type":"string","enum":["classic","sudden_death"],"default":"classic","description":"💀 sudden_death: cada puja resetea el timer a soft_close_sec"},"start_price_usd":{"type":"string","description":"USD como string (subasta)"},"buy_now_usd":{"type":"string","description":"USD como string (precio fijo)"},"price_usd":{"type":"string","description":"alias de buy_now_usd"},"min_increment_usd":{"type":"string","default":"1"},"soft_close_sec":{"type":"integer","default":10,"minimum":3,"maximum":60,"description":"Anti-snipe / ventana sudden death (§7.2)"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuctions","description":"Crear un lote bajo un live: subasta o precio fijo (buy_now, v-66)"}},"/auctions/{id}/buy":{"post":{"summary":"Comprar un lote de precio fijo al instante (buy_now, v-66)","tags":["Auction Engine"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"order_id":{"type":"string"},"amount_ref_usd":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postAuctionsByIdBuy","description":"Comprar un lote de precio fijo al instante (buy_now, v-66)"}},"/auctions/{id}/open":{"post":{"summary":"Abrir subasta: siembra estado en Redis y fija ends_at (§7, §6)","tags":["Auction Engine"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"duration_sec":{"type":"integer","default":60,"minimum":5,"maximum":86400}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuctionsByIdOpen","description":"Abrir subasta: siembra estado en Redis y fija ends_at (§7, §6)"}},"/auctions/{id}/close":{"post":{"summary":"Cerrar ya (host): fuerza ends_at=now; el worker cierra en el próximo tick (§6.4)","tags":["Auction Engine"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuctionsByIdClose","description":"Cerrar ya (host): fuerza ends_at=now; el worker cierra en el próximo tick (§6.4)"}},"/auctions/{id}/reopen":{"post":{"summary":"Reabrir una subasta vencida sin vender (unsold) o cancelada","tags":["Auction Engine"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"duration_sec":{"type":"integer","default":60,"minimum":5,"maximum":86400}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuctionsByIdReopen","description":"Reabrir una subasta vencida sin vender (unsold) o cancelada"}},"/auctions/{id}/extend":{"post":{"summary":"Sumar tiempo a una subasta en curso (host): +N segundos al ends_at (v-119)","tags":["Auction Engine"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["seconds"],"properties":{"seconds":{"type":"integer","minimum":1,"maximum":3600}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAuctionsByIdExtend","description":"Sumar tiempo a una subasta en curso (host): +N segundos al ends_at (v-119)"}},"/giveaways/":{"post":{"summary":"Abrir un sorteo bajo un live (dueño del live)","tags":["Run of Show"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["live_id","product_id"],"properties":{"live_id":{"type":"string","format":"uuid"},"product_id":{"type":"string","format":"uuid"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postGiveaways","description":"Abrir un sorteo bajo un live (dueño del live)"}},"/giveaways/{id}/enter":{"post":{"summary":"Entrar al sorteo (gratis, AMOE)","tags":["Run of Show"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"entered":{"type":"boolean"},"entries_count":{"type":"integer"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postGiveawaysByIdEnter","description":"Entrar al sorteo (gratis, AMOE)"}},"/giveaways/{id}/draw":{"post":{"summary":"Sortear ganador (dueño). Selección aleatoria server-side","tags":["Run of Show"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"winner":{"type":"string","nullable":true},"winner_display":{"type":"string","nullable":true},"order_id":{"type":"string","nullable":true}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postGiveawaysByIdDraw","description":"Sortear ganador (dueño). Selección aleatoria server-side"}},"/giveaways/{id}":{"get":{"summary":"Estado del sorteo (incluye si ya entré)","tags":["Run of Show"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"getGiveawaysById","description":"Estado del sorteo (incluye si ya entré)"}},"/coupons/mine":{"get":{"summary":"Mis cupones (otorga el de bienvenida si no existe)","tags":["Cupones"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"amount_usd":{"type":"string"},"status":{"type":"string","description":"active | applied"},"order_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"applied_at":{"type":"string","format":"date-time","nullable":true}}}}}}}},"operationId":"getCouponsMine","description":"Mis cupones (otorga el de bienvenida si no existe)"}},"/coupons/redeem":{"post":{"summary":"Canjear código promo → cupón en la cuenta","tags":["Cupones"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string","minLength":3,"maxLength":30}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"amount_usd":{"type":"string"},"kind":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"410":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postCouponsRedeem","description":"Canjear código promo → cupón en la cuenta"}},"/disputes":{"get":{"summary":"Mis disputas (?role=seller default | buyer)","tags":["Órdenes / Pagos"],"parameters":[{"schema":{"type":"string","enum":["seller","buyer"],"default":"seller"},"in":"query","name":"role","required":false},{"schema":{"type":"string","enum":["open","resolved"]},"in":"query","name":"status","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getDisputes","description":"Mis disputas (?role=seller default | buyer)"}},"/marketplace/products":{"get":{"summary":"Feed de Gangas directas (público): for_sale con stock, Bs a tasa BCV","tags":["Marketplace"],"responses":{"200":{"description":"Default Response"}},"operationId":"getMarketplaceProducts","description":"Feed de Gangas directas (público): for_sale con stock, Bs a tasa BCV"}},"/marketplace/products/{id}/buy":{"post":{"summary":"Comprar ya (Gangas directas) → { order_id } awaiting_payment","tags":["Marketplace"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"order_id":{"type":"string"},"amount_ref_usd":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postMarketplaceProductsByIdBuy","description":"Comprar ya (Gangas directas) → { order_id } awaiting_payment"}},"/media":{"post":{"summary":"Subir video/foto de producto a R2 → { url } (multipart: file, kind)","tags":["Productos"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"413":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"424":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}}},"operationId":"postMedia","description":"Subir video/foto de producto a R2 → { url } (multipart: file, kind)"}},"/me/avatar":{"post":{"summary":"Subir/actualizar mi foto de perfil (multipart: file) → { avatar_url }","tags":["Perfil"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"avatar_url":{"type":"string"},"url":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"413":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"424":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}}},"operationId":"postMeAvatar","description":"Subir/actualizar mi foto de perfil (multipart: file) → { avatar_url }"}},"/shopify/connect":{"post":{"summary":"Conectar mi tienda Shopify (dominio + Admin API token de Custom App)","tags":["Shopify"],"description":"El vendedor crea una Custom App en su tienda (Settings → Apps → Develop apps, scope read_products) y pega su dominio .myshopify.com + token shpat_. El token es SECRETO (se guarda cifrado en el server, nunca vuelve en respuestas). Errores legibles en 424.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["shop_domain","access_token"],"properties":{"shop_domain":{"type":"string","minLength":4,"maxLength":120},"access_token":{"type":"string","minLength":10,"maxLength":200}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"shop_name":{"type":"string"},"currency":{"type":"string"},"warning":{"type":"string"}}}}}},"424":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}}},"operationId":"postShopifyConnect"}},"/shopify/status":{"get":{"summary":"Estado de mi conexión Shopify (sin token)","tags":["Shopify"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getShopifyStatus","description":"Estado de mi conexión Shopify (sin token)"}},"/shopify/disconnect":{"delete":{"summary":"Desconectar mi tienda (borra el token)","tags":["Shopify"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteShopifyDisconnect","description":"Desconectar mi tienda (borra el token)"}},"/shopify/import":{"post":{"summary":"Importar productos de mi Shopify (re-import = actualizar, no duplicar)","tags":["Shopify"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"for_sale":{"type":"boolean","default":false,"description":"publicar directo en Gangas directas"},"assume_usd":{"type":"boolean","default":false,"description":"obligatorio si la tienda no está en USD"},"limit":{"type":"integer","minimum":1,"maximum":250,"default":250}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"imported":{"type":"integer"},"updated":{"type":"integer"},"skipped":{"type":"integer"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"currency":{"type":"string"}}}}}},"424":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}}},"operationId":"postShopifyImport","description":"Importar productos de mi Shopify (re-import = actualizar, no duplicar)"}},"/payment-methods/stripe/public-key":{"get":{"summary":"Clave publicable de Stripe (pk_...) para Stripe.js","tags":["Métodos de pago"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"public_key":{"type":"string","nullable":true}}}}}}},"operationId":"getPaymentMethodsStripePublicKey","description":"Clave publicable de Stripe (pk_...) para Stripe.js"}},"/payment-methods/setup-intent":{"post":{"summary":"Crear SetupIntent para guardar tarjeta con Elements (§9.1)","tags":["Métodos de pago"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postPaymentMethodsSetupIntent","description":"Crear SetupIntent para guardar tarjeta con Elements (§9.1)"}},"/payment-methods/spidi/enroll":{"post":{"summary":"SPIDI: enrolar pagador por cédula → pay_url (una vez, §9.2)","tags":["Métodos de pago"],"description":"Requiere cédula en el perfil (PATCH /me). El front embebe `pay_url` en un iframe y hace polling de GET /orders/{id}/status/check. Errores: **400** (falta cédula/BCV), **424** (SPIDI rechazó — el `detalle` trae el motivo real). Nunca 5xx (los enmascara el proxy).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"pay_url":{"type":"string","description":"URL hospedada de SPIDI para el iframe"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"424":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}}},"operationId":"postPaymentMethodsSpidiEnroll"}},"/payment-methods/veb/banks":{"get":{"summary":"veb: bancos de la pasarela (selector C2P del comprador y método de cobro del vendedor)","tags":["Métodos de pago"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Código SUDEBAN con cero inicial (0102)"},"name":{"type":"string"},"logo":{"type":"string","nullable":true,"description":"URL del logo del banco (viene de la pasarela); null si no lo manda"}}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"getPaymentMethodsVebBanks","description":"veb: bancos de la pasarela (selector C2P del comprador y método de cobro del vendedor)"}},"/payment-methods/veb":{"get":{"summary":"veb: mis cuentas de Débito Inmediato guardadas (v-140)","tags":["Métodos de pago"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"cedula_ok":{"type":"boolean","description":"false → PATCH /me con la cédula primero"},"accounts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"bank_code":{"type":"string"},"bank_name":{"type":"string","nullable":true},"phone_masked":{"type":"string"}}}}}}}}}},"operationId":"getPaymentMethodsVeb","description":"veb: mis cuentas de Débito Inmediato guardadas (v-140)"},"post":{"summary":"veb: guardar cuenta de Débito Inmediato (banco + teléfono) (v-140)","tags":["Métodos de pago"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bank_code","phone"],"properties":{"bank_code":{"type":"string","description":"Código SUDEBAN 01XX, p.ej. 0102 (acepta 102)"},"bank_name":{"type":"string"},"phone":{"type":"string","description":"0412..., +58412... o 58412..."}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"bank_code":{"type":"string"},"bank_name":{"type":"string","nullable":true},"phone_masked":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postPaymentMethodsVeb","description":"veb: guardar cuenta de Débito Inmediato (banco + teléfono) (v-140)"}},"/payment-methods/veb/{id}":{"delete":{"summary":"veb: eliminar cuenta de Débito Inmediato guardada (v-140)","tags":["Métodos de pago"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"deletePaymentMethodsVebById","description":"veb: eliminar cuenta de Débito Inmediato guardada (v-140)"}},"/payment-methods/":{"get":{"summary":"Listar mis tarjetas guardadas","tags":["Métodos de pago"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getPaymentMethods","description":"Listar mis tarjetas guardadas"}},"/payment-methods/spidi":{"delete":{"summary":"Desenrolar Pago Móvil (SPIDI) como método guardado (v-127)","tags":["Métodos de pago"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deletePaymentMethodsSpidi","description":"Desenrolar Pago Móvil (SPIDI) como método guardado (v-127)"}},"/payment-methods/{id}":{"delete":{"summary":"Eliminar una tarjeta guardada (detach en Stripe + fila local) (v-129)","tags":["Métodos de pago"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"424":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}}},"operationId":"deletePaymentMethodsById","description":"Eliminar una tarjeta guardada (detach en Stripe + fila local) (v-129)"}},"/orders/":{"get":{"summary":"Listar mis compras (con ciclo de vida, tracking y recibo)","tags":["Órdenes / Pagos"],"description":"Órdenes donde soy comprador. Trae status (paid/shipped/delivered/disputed), tracking, receipt y dispute.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["awaiting_payment","paid","shipped","delivered","disputed","expired","canceled","fulfilled"]},"source":{"type":"string"},"amount_usd":{"type":"string"},"discount_usd":{"type":"string","description":"Cupón aplicado (v-69)"},"coupon_applied":{"type":"boolean"},"fine_usd":{"type":"number","nullable":true,"description":"v-145: multa para 'cancelar pagando' (solo expiradas)"},"revivable":{"type":"boolean","description":"v-149: expirada con artículo aún disponible → puede pagar completo (POST /:id/revive)"},"product_title":{"type":"string","nullable":true},"auction_id":{"type":"string","format":"uuid","nullable":true},"pay_deadline":{"type":"string","format":"date-time","nullable":true},"shipped_at":{"type":"string","format":"date-time","nullable":true},"delivered_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"tracking":{"type":"object","nullable":true,"properties":{"carrier":{"type":"string","nullable":true},"number":{"type":"string","nullable":true}}},"dispute":{"type":"object","nullable":true,"properties":{"reason":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"status":{"type":"string"},"disputed_at":{"type":"string","format":"date-time","nullable":true}}},"receipt":{"type":"object","properties":{"itemPrice":{"type":"number"},"commission":{"type":"number"},"processing_fee":{"type":"number","description":"Fee del riel veb (v-142, lo absorbe el vendedor)"},"spidi_fee":{"type":"number"},"shipping":{"type":"number"},"discount":{"type":"number","description":"Cupón (v-69)"},"total":{"type":"number","description":"Lo que pagó el comprador (item − cupón)"},"net":{"type":"number"}}}}}}}}}},"operationId":"getOrders"}},"/orders/{id}":{"get":{"summary":"Ver una orden","tags":["Órdenes / Pagos"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getOrdersById","description":"Ver una orden"}},"/orders/{id}/pay":{"get":{"summary":"Instrucciones de pago: SPIDI pay_url o veb monto+destino (§9.2, v-139)","tags":["Órdenes / Pagos"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"pay_url":{"type":"string","nullable":true,"description":"payment_url de SPIDI para el iframe (null en veb)"},"channel":{"type":"string"},"amount_ves":{"type":"string","nullable":true,"description":"veb: monto exacto en Bs a transferir"},"bcv_rate":{"type":"string","nullable":true,"description":"veb: tasa BCV congelada de la sesión"},"reference_submitted":{"type":"boolean","description":"veb: ya registró una referencia"},"destination":{"type":"object","nullable":true,"description":"veb: cuenta Pago Móvil destino (Chu Capital)","properties":{"bank_code":{"type":"string"},"bank_name":{"type":"string"},"phone":{"type":"string"},"rif":{"type":"string"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"getOrdersByIdPay","description":"Instrucciones de pago: SPIDI pay_url o veb monto+destino (§9.2, v-139)"}},"/orders/{id}/revive":{"post":{"summary":"Revivir orden expirada para pagar completo (anula la multa) (v-149)","tags":["Órdenes / Pagos"],"description":"Solo si `revivable: true` (artículo disponible: sin second-chance viva/pagada y producto no relistado). La orden vuelve a awaiting_payment con ventana nueva y tasa BCV fresca; el comprador paga por el selector normal (C2P/tarjeta/referencia).","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["awaiting_payment"]},"pay_deadline":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdRevive"}},"/orders/{id}/pm/reference":{"post":{"summary":"veb: registrar referencia de Pago Móvil para verificación (v-139)","tags":["Órdenes / Pagos"],"description":"Tras transferir a la cuenta destino (GET /:id/pay), el comprador registra la referencia (4-32 dígitos). status: paid = acreditado · pending = el banco aún la procesa (polling) · 422 reference_rejected = corregir y reintentar · 503 = reintentar en unos segundos.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reference"],"properties":{"reference":{"type":"string","minLength":4,"maxLength":40},"date":{"type":"string","description":"Fecha del movimiento YYYY-MM-DD (opcional)"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["paid","pending"]}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdPmReference"}},"/orders/{id}/c2p/request":{"post":{"summary":"veb C2P: solicitar débito inmediato (el banco emite el OTP) (v-140)","tags":["Órdenes / Pagos"],"description":"Enviar `bank_id` (cuenta guardada de /payment-methods/veb) O `bank_code`+`phone` inline (con `save:true` la guarda). El monto sale de la orden (§9.7). Luego POST /:id/c2p/confirm con el token que el banco le dio al comprador.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bank_id":{"type":"string","format":"uuid"},"bank_code":{"type":"string"},"bank_name":{"type":"string"},"phone":{"type":"string"},"save":{"type":"boolean","description":"true → guarda la cuenta inline en /payment-methods/veb"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"intent_id":{"type":"string"},"amount_ves":{"type":"string","nullable":true},"bcv_rate":{"type":"string","nullable":true}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdC2pRequest"}},"/orders/{id}/cancel-request":{"post":{"summary":"Solicitar cancelación al vendedor (orden pendiente de pago) (v-146)","tags":["Órdenes / Pagos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":300}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending"]},"expires_at":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdCancelRequest","description":"Solicitar cancelación al vendedor (orden pendiente de pago) (v-146)"}},"/orders/{id}/cancel-request/respond":{"post":{"summary":"Vendedor responde la solicitud: accept = cancela SIN multa (v-146)","tags":["Órdenes / Pagos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accept"],"properties":{"accept":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdCancelRequestRespond","description":"Vendedor responde la solicitud: accept = cancela SIN multa (v-146)"}},"/orders/{id}/fine/request":{"post":{"summary":"veb: solicitar débito C2P de la MULTA por impago (orden expirada) (v-145)","tags":["Órdenes / Pagos"],"description":"Body igual a /c2p/request (bank_id o bank_code+phone). 200 → {intent_id, fine_usd, amount_ves}. Al confirmar la multa, la orden expirada pasa a canceled y el bloqueo de pujas se levanta automáticamente.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bank_id":{"type":"string","format":"uuid"},"bank_code":{"type":"string"},"phone":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"intent_id":{"type":"string"},"fine_usd":{"type":"number"},"amount_ves":{"type":"string","nullable":true},"bcv_rate":{"type":"string","nullable":true}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdFineRequest"}},"/orders/{id}/fine/confirm":{"post":{"summary":"veb: ejecutar la MULTA con el token del banco → orden canceled (v-145)","tags":["Órdenes / Pagos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","minLength":6,"maxLength":8}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["paid","pending"]},"order_status":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdFineConfirm","description":"veb: ejecutar la MULTA con el token del banco → orden canceled (v-145)"}},"/orders/{id}/appeal":{"post":{"summary":"Apelar una orden expirada: 'sí pagué / no fue mi culpa' (v-145)","tags":["Órdenes / Pagos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":500},"reference":{"type":"string","maxLength":40,"description":"Referencia bancaria como prueba (se verifica al instante)"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["paid_honored","open"]},"appeal_id":{"type":"string","nullable":true}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdAppeal","description":"Apelar una orden expirada: 'sí pagué / no fue mi culpa' (v-145)"}},"/orders/{id}/c2p/confirm":{"post":{"summary":"veb C2P: ejecutar el débito con el token del banco (6-8 dígitos) (v-140)","tags":["Órdenes / Pagos"],"description":"422 → `error` ∈ fondos_insuficientes | limite_excedido | token_rejected (genérico) | banco_no_disponible (fuera de horario/servicio — reintentar luego); `detail` trae el motivo crudo. Clasificación por códigos reales del riel R4 (AM04/51, AM02, TKCM/08/55, VE01/41/90/91). En /c2p/request el genérico es c2p_rejected.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","minLength":6,"maxLength":8}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["paid","pending"]}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdC2pConfirm"}},"/orders/{id}/charge-card":{"post":{"summary":"Cobrar mi tarjeta guardada (USD) para esta orden (selector, v-143)","tags":["Órdenes / Pagos"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["paid","pending","requires_action"]}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdChargeCard","description":"Cobrar mi tarjeta guardada (USD) para esta orden (selector, v-143)"}},"/orders/{id}/status/check":{"get":{"summary":"Polling en vivo: GET al provider = verdad (§9.7)","tags":["Órdenes / Pagos"],"description":"La /app hace polling cada 4s y decide por `status` ∈ pending|paid|expired|failed|requires_action.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"Estado del pago (lo que consume la /app)"},"state":{"type":"string","description":"Alias de status (compat)"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"getOrdersByIdStatusCheck"}},"/orders/{id}/dispute":{"post":{"summary":"Abrir disputa (comprador) — protección al comprador","tags":["Órdenes / Pagos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":2},"note":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdDispute","description":"Abrir disputa (comprador) — protección al comprador"}},"/orders/{id}/ship":{"post":{"summary":"Marcar despachado con tracking (vendedor)","tags":["Órdenes / Pagos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"carrier":{"type":"string"},"tracking":{"type":"string"},"tracking_number":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdShip","description":"Marcar despachado con tracking (vendedor)"}},"/orders/{id}/deliver":{"post":{"summary":"Confirmar recepción (comprador)","tags":["Órdenes / Pagos"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postOrdersByIdDeliver","description":"Confirmar recepción (comprador)"}},"/orders/sales":{"get":{"summary":"Mis ventas (vendedor) — para despachar","tags":["Órdenes / Pagos"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getOrdersSales","description":"Mis ventas (vendedor) — para despachar"}},"/orders/{id}/review":{"post":{"summary":"Calificar al vendedor por una orden entregada (1..5). Una review por orden.","tags":["Órdenes / Pagos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rating"],"properties":{"rating":{"type":"integer","minimum":1,"maximum":5},"text":{"type":"string","maxLength":1000}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postOrdersByIdReview","description":"Calificar al vendedor por una orden entregada (1..5). Una review por orden."}},"/sellers/{id}/reviews":{"get":{"summary":"Reviews de un vendedor (público) + rating_avg/rating_count. :id = uuid o username (v-124)","tags":["Vendedor"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"offset","required":false},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"user_id (uuid) o username"}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellersByIdReviews","description":"Reviews de un vendedor (público) + rating_avg/rating_count. :id = uuid o username (v-124)"}},"/products/{id}/offers":{"post":{"summary":"Hacer una oferta sobre un producto buy-now (v-98)","tags":["Marketplace"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_usd"],"properties":{"amount_usd":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postProductsByIdOffers","description":"Hacer una oferta sobre un producto buy-now (v-98)"}},"/seller/offers":{"get":{"summary":"Ofertas recibidas sobre mis productos (v-98)","tags":["Vendedor"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSellerOffers","description":"Ofertas recibidas sobre mis productos (v-98)"}},"/me/offers":{"get":{"summary":"Mis ofertas (comprador) (v-98)","tags":["Perfil"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getMeOffers","description":"Mis ofertas (comprador) (v-98)"}},"/offers/{id}/accept":{"post":{"summary":"Aceptar una oferta/contraoferta → crea la orden (v-98)","tags":["Marketplace"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postOffersByIdAccept","description":"Aceptar una oferta/contraoferta → crea la orden (v-98)"}},"/offers/{id}/reject":{"post":{"summary":"Rechazar una oferta/contraoferta (v-98)","tags":["Marketplace"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postOffersByIdReject","description":"Rechazar una oferta/contraoferta (v-98)"}},"/offers/{id}/counter":{"post":{"summary":"Contraofertar (vendedor) (v-98)","tags":["Marketplace"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_usd"],"properties":{"amount_usd":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postOffersByIdCounter","description":"Contraofertar (vendedor) (v-98)"}},"/offers/{id}/withdraw":{"post":{"summary":"Retirar mi oferta (comprador) (v-98)","tags":["Marketplace"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postOffersByIdWithdraw","description":"Retirar mi oferta (comprador) (v-98)"}},"/dm/{userId}":{"post":{"summary":"Enviar un mensaje directo a un usuario (v-100)","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","minLength":1,"maxLength":2000}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"userId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postDmByUserid","description":"Enviar un mensaje directo a un usuario (v-100)"},"get":{"summary":"Hilo de mensajes con un usuario (marca leídos) (v-100)","tags":["Perfil"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"userId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getDmByUserid","description":"Hilo de mensajes con un usuario (marca leídos) (v-100)"}},"/dm":{"get":{"summary":"Mi inbox de mensajes directos (v-100)","tags":["Perfil"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getDm","description":"Mi inbox de mensajes directos (v-100)"}},"/saved":{"post":{"summary":"Guardar un producto o live (v-101)","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["item_type","item_id"],"properties":{"item_type":{"type":"string","enum":["product","live"]},"item_id":{"type":"string","format":"uuid"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postSaved","description":"Guardar un producto o live (v-101)"},"get":{"summary":"Mis guardados (productos + lives) (v-101)","tags":["Perfil"],"parameters":[{"schema":{"type":"string","enum":["product","live"]},"in":"query","name":"type","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSaved","description":"Mis guardados (productos + lives) (v-101)"}},"/saved/{itemType}/{itemId}":{"delete":{"summary":"Quitar de guardados (v-101)","tags":["Perfil"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"itemType","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"itemId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteSavedByItemtypeByItemid","description":"Quitar de guardados (v-101)"}},"/me/addresses":{"get":{"summary":"Mis direcciones (v-102)","tags":["Perfil"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getMeAddresses","description":"Mis direcciones (v-102)"},"post":{"summary":"Agregar dirección (v-102)","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"},"state":{"type":"string"},"city":{"type":"string"},"address":{"type":"string"},"reference":{"type":"string"},"mrw_agency":{"type":"string"},"make_default":{"type":"boolean"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postMeAddresses","description":"Agregar dirección (v-102)"}},"/me/addresses/{id}":{"patch":{"summary":"Editar dirección (v-102)","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"},"state":{"type":"string"},"city":{"type":"string"},"address":{"type":"string"},"reference":{"type":"string"},"mrw_agency":{"type":"string"},"make_default":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"patchMeAddressesById","description":"Editar dirección (v-102)"},"delete":{"summary":"Borrar dirección (v-102)","tags":["Perfil"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteMeAddressesById","description":"Borrar dirección (v-102)"}},"/me/addresses/{id}/default":{"post":{"summary":"Marcar dirección como default (v-102)","tags":["Perfil"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postMeAddressesByIdDefault","description":"Marcar dirección como default (v-102)"}},"/me/addresses/{id}/return":{"post":{"summary":"Marcar dirección como de retorno (v-102)","tags":["Perfil"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postMeAddressesByIdReturn","description":"Marcar dirección como de retorno (v-102)"}},"/webhooks/stripe":{"post":{"summary":"Stripe: payment_intent.succeeded (idempotente + GET + guard, §9.1)","tags":["Webhooks"],"description":"ACK 200 siempre. Firma Stripe-Signature verificada. Body crudo requerido.","responses":{"200":{"description":"Default Response"}},"operationId":"postWebhooksStripe"}},"/webhooks/spidi":{"post":{"summary":"SPIDI: solo eventos de éxito (los fallos por polling, §9.2)","tags":["Webhooks"],"description":"ACK 200 siempre. Firma HMAC verificada. Los fallos se captan por polling, no aquí.","responses":{"200":{"description":"Default Response"}},"operationId":"postWebhooksSpidi"}},"/webhooks/whatsapp":{"post":{"summary":"WhatsApp gateway: delivery status (ACK 200)","tags":["Webhooks"],"description":"Recibe estados de entrega del gateway. No requiere challenge (Baileys, no Meta).","responses":{"200":{"description":"Default Response"}},"operationId":"postWebhooksWhatsapp"}},"/webhooks/didit":{"post":{"summary":"Didit KYC: status.updated (firma verificada, idempotente)","tags":["Webhooks"],"description":"ACK 200. Firma HMAC v2/simple. Actualiza kyc_status por vendor_data (userId).","responses":{"200":{"description":"Default Response"}},"operationId":"postWebhooksDidit"}},"/webhooks/revenuecat":{"post":{"summary":"RevenueCat: suscripciones → entitlements (Bearer auth, idempotente, §9.7)","tags":["Webhooks"],"description":"ACK 200 (salvo 401 auth mala). Authorization: Bearer <RC_WEBHOOK_SECRET>. Mapea INITIAL_PURCHASE/RENEWAL/PRODUCT_CHANGE/UNCANCELLATION/NON_RENEWING_PURCHASE/SUBSCRIPTION_EXTENDED → activa (*_until = expiración); EXPIRATION/BILLING_ISSUE → desactiva; CANCELLATION → mantiene hasta expirar.","responses":{"200":{"description":"Default Response"}},"operationId":"postWebhooksRevenuecat"}},"/webhooks/banking":{"post":{"summary":"VE Banking: eventos de pago (HMAC raw-body, idempotente, sin reintentos del emisor)","tags":["Webhooks"],"description":"ACK 200 rápido (<10s). Verifica X-Webhook-Signature (HMAC-SHA256 hex del raw body con VE_BANKING_WEBHOOK_SECRET). Idempotencia por paymentId+status. NO marca órdenes: la confirmación de dinero exige GET-verdad al provider (§9.7).","responses":{"200":{"description":"Default Response"}},"operationId":"postWebhooksBanking"}},"/livekit/token":{"get":{"summary":"Token de video: host publica, viewer/invitado suscribe (§11)","tags":["LiveKit"],"description":"Sin Bearer → token de invitado (solo suscribir). Con Bearer → normal.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"query","name":"live_id","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"getLivekitToken"}},"/admin/coin-packs":{"get":{"summary":"Listar paquetes de coins (incluye inactivos) (v-160)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminCoinPacks","description":"Listar paquetes de coins (incluye inactivos) (v-160)"},"post":{"summary":"Crear un paquete de coins (v-160)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","label","coins","price_usd"],"properties":{"code":{"type":"string","minLength":2,"maxLength":32},"label":{"type":"string","minLength":1,"maxLength":60},"coins":{"type":"integer","minimum":1},"bonus_coins":{"type":"integer","minimum":0,"default":0},"price_usd":{"type":"number","minimum":0.01},"apple_product_id":{"type":"string"},"google_product_id":{"type":"string"},"sort":{"type":"integer","default":0}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminCoinPacks","description":"Crear un paquete de coins (v-160)"}},"/admin/coin-packs/{id}":{"patch":{"summary":"Editar un paquete de coins (precio, bonus, activar/desactivar) (v-160)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":60},"coins":{"type":"integer","minimum":1},"bonus_coins":{"type":"integer","minimum":0},"price_usd":{"type":"number","minimum":0.01},"apple_product_id":{"type":"string"},"google_product_id":{"type":"string"},"sort":{"type":"integer"},"active":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"patchAdminCoinPacksById","description":"Editar un paquete de coins (precio, bonus, activar/desactivar) (v-160)"}},"/admin/coins/adjust":{"post":{"summary":"Ajustar el saldo de coins de un usuario (auditado) (v-160)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["user_id","delta"],"properties":{"user_id":{"type":"string","format":"uuid"},"delta":{"type":"integer","description":"positivo acredita, negativo debita"},"note":{"type":"string","maxLength":140}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminCoinsAdjust","description":"Ajustar el saldo de coins de un usuario (auditado) (v-160)"}},"/admin/coins/stats":{"get":{"summary":"Resumen de la economia de coins (v-160)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminCoinsStats","description":"Resumen de la economia de coins (v-160)"}},"/admin/payouts/{id}/reverse":{"post":{"summary":"Reversar un retiro no dispersado (libera el saldo del vendedor)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":120}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminPayoutsByIdReverse","description":"Reversar un retiro no dispersado (libera el saldo del vendedor)"}},"/admin/settings":{"get":{"summary":"Configurador de negocio: todos los números ajustables (v-145)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminSettings","description":"Configurador de negocio: todos los números ajustables (v-145)"}},"/admin/settings/{key}":{"put":{"summary":"Ajustar un número de negocio (whitelist + rango) (v-145)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["value"],"properties":{"value":{"type":"number"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"key","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"key":{"type":"string"},"value":{"type":"number"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"putAdminSettingsByKey","description":"Ajustar un número de negocio (whitelist + rango) (v-145)"}},"/admin/appeals":{"get":{"summary":"Apelaciones de impago (open por defecto) (v-145)","tags":["Admin"],"parameters":[{"schema":{"type":"string","enum":["open","accepted","rejected"],"default":"open"},"in":"query","name":"status","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminAppeals","description":"Apelaciones de impago (open por defecto) (v-145)"}},"/admin/appeals/{id}/resolve":{"post":{"summary":"Resolver apelación: accept = perdonar orden (expired→canceled) (v-145)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accept"],"properties":{"accept":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postAdminAppealsByIdResolve","description":"Resolver apelación: accept = perdonar orden (expired→canceled) (v-145)"}},"/admin/orders/{id}/forgive":{"post":{"summary":"Perdonar orden (expirada o pendiente): cancela sin multa + libera artículo (v-151)","tags":["Admin"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string"},"warning":{"type":"string","description":"Efecto del perdón — informa, no prohíbe"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postAdminOrdersByIdForgive","description":"Perdonar orden (expirada o pendiente): cancela sin multa + libera artículo (v-151)"}},"/admin/orders/{id}":{"delete":{"summary":"ELIMINAR una orden y sus dependencias (pruebas/limpieza) (v-151b)","tags":["Admin"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"deleted":{"type":"boolean"},"warning":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"deleteAdminOrdersById","description":"ELIMINAR una orden y sus dependencias (pruebas/limpieza) (v-151b)"}},"/admin/users":{"get":{"summary":"Listar usuarios (solo admin). ?q para buscar","tags":["Admin"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"q","required":false},{"schema":{"type":"string","enum":["ok","review","blocked"]},"in":"query","name":"risk","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminUsers","description":"Listar usuarios (solo admin). ?q para buscar"}},"/admin/users/{id}":{"get":{"summary":"Ficha de un usuario (IP, país, dispositivo) — solo admin","tags":["Admin"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminUsersById","description":"Ficha de un usuario (IP, país, dispositivo) — solo admin"},"delete":{"summary":"Eliminar usuario (solo admin; 409 si tiene datos)","tags":["Admin"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteAdminUsersById","description":"Eliminar usuario (solo admin; 409 si tiene datos)"}},"/admin/users/{id}/ban":{"post":{"summary":"Banear usuario (solo admin)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminUsersByIdBan","description":"Banear usuario (solo admin)"}},"/admin/users/{id}/unban":{"post":{"summary":"Quitar baneo (solo admin)","tags":["Admin"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminUsersByIdUnban","description":"Quitar baneo (solo admin)"}},"/admin/lives/{id}/end":{"post":{"summary":"Terminar un live (admin): status=ended, opcional mark_demo (v-128)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mark_demo":{"type":"boolean","default":false}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminLivesByIdEnd","description":"Terminar un live (admin): status=ended, opcional mark_demo (v-128)"}},"/admin/users/{id}/kyc":{"post":{"summary":"Aprobar/rechazar KYC de un vendedor (solo admin)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["approved","rejected"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminUsersByIdKyc","description":"Aprobar/rechazar KYC de un vendedor (solo admin)"}},"/admin/orders":{"get":{"summary":"Listar todas las órdenes (solo admin)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminOrders","description":"Listar todas las órdenes (solo admin)"}},"/admin/stats":{"get":{"summary":"Métricas de plataforma (solo admin)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminStats","description":"Métricas de plataforma (solo admin)"}},"/admin/reports":{"get":{"summary":"Listar reportes (solo admin). ?status=open|reviewed|dismissed","tags":["Admin"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"status","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminReports","description":"Listar reportes (solo admin). ?status=open|reviewed|dismissed"}},"/admin/reports/{id}/status":{"post":{"summary":"Cambiar estado de un reporte (solo admin)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["open","reviewed","dismissed"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminReportsByIdStatus","description":"Cambiar estado de un reporte (solo admin)"}},"/admin/users/{id}/role":{"patch":{"summary":"Cambiar el rol de un usuario (solo admin)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["buyer","seller","admin"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"patchAdminUsersByIdRole","description":"Cambiar el rol de un usuario (solo admin)"}},"/admin/users/{id}/token":{"post":{"summary":"Generar token dev para un usuario (solo admin, cap 7d)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expires_in":{}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminUsersByIdToken","description":"Generar token dev para un usuario (solo admin, cap 7d)"}},"/admin/fraud":{"get":{"summary":"Cola de alertas de fraude (solo admin)","tags":["Admin"],"parameters":[{"schema":{"type":"string","enum":["open","reviewing","resolved","dismissed"]},"in":"query","name":"status","required":false},{"schema":{"type":"string"},"in":"query","name":"kind","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminFraud","description":"Cola de alertas de fraude (solo admin)"}},"/admin/users/{id}/attempts":{"get":{"summary":"Historial kyc_attempts de un usuario (solo admin)","tags":["Admin"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminUsersByIdAttempts","description":"Historial kyc_attempts de un usuario (solo admin)"}},"/admin/fraud/{id}/resolve":{"post":{"summary":"Resolver alerta de fraude: approve | reject | ban | request_proof","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["approve","reject","ban","request_proof"]},"note":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminFraudByIdResolve","description":"Resolver alerta de fraude: approve | reject | ban | request_proof"}},"/admin/users/{id}/reveal-cedula":{"post":{"summary":"Ver la cédula completa de un usuario (AUDITADO, solo admin)","tags":["Admin"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminUsersByIdRevealCedula","description":"Ver la cédula completa de un usuario (AUDITADO, solo admin)"}},"/admin/users/{id}/set-admin":{"post":{"summary":"Dar o quitar is_admin (independiente del role)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["is_admin"],"properties":{"is_admin":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminUsersByIdSetAdmin","description":"Dar o quitar is_admin (independiente del role)"}},"/admin/payouts":{"get":{"summary":"Cola de retiros del vendedor (solo admin)","tags":["Admin"],"parameters":[{"schema":{"type":"string","enum":["processing","completed","failed"]},"in":"query","name":"status","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminPayouts","description":"Cola de retiros del vendedor (solo admin)"}},"/admin/payouts/{id}/complete":{"post":{"summary":"Marcar retiro transferido (solo admin)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminPayoutsByIdComplete","description":"Marcar retiro transferido (solo admin)"}},"/admin/payouts/{id}/fail":{"post":{"summary":"Marcar retiro fallido (devuelve el saldo) — solo admin","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminPayoutsByIdFail","description":"Marcar retiro fallido (devuelve el saldo) — solo admin"}},"/admin/disputes":{"get":{"summary":"Cola de disputas (solo admin)","tags":["Admin"],"parameters":[{"schema":{"type":"string","enum":["open","resolved"]},"in":"query","name":"status","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminDisputes","description":"Cola de disputas (solo admin)"}},"/admin/disputes/{orderId}/resolve":{"post":{"summary":"Resolver disputa: refund_buyer | release_seller (solo admin)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["refund_buyer","release_seller"]},"note":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"orderId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"action":{"type":"string"},"order_status":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postAdminDisputesByOrderidResolve","description":"Resolver disputa: refund_buyer | release_seller (solo admin)"}},"/admin/demo/start":{"post":{"summary":"Iniciar demo/carga: N lives + M bots (chat+pujas reales por WS)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"lives":{"type":"integer","minimum":1,"maximum":100,"default":3},"bots_per_live":{"type":"integer","minimum":0,"maximum":100,"default":10},"chat_every_ms":{"type":"integer","minimum":500,"maximum":60000,"default":4000},"bid_every_ms":{"type":"integer","minimum":500,"maximum":60000,"default":7000},"duration_sec":{"type":"integer","minimum":30,"maximum":21600,"default":3600},"video_urls":{"type":"array","items":{"type":"string","maxLength":1000},"maxItems":100}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminDemoStart","description":"Iniciar demo/carga: N lives + M bots (chat+pujas reales por WS)"}},"/admin/demo/stop":{"post":{"summary":"Detener la demo activa y limpiar","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminDemoStop","description":"Detener la demo activa y limpiar"}},"/admin/demo/status":{"get":{"summary":"Estado de la demo (bots conectados en vivo)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminDemoStatus","description":"Estado de la demo (bots conectados en vivo)"}},"/admin/demo/config":{"get":{"summary":"Config del showcase 24/7 (slots + ritmos + enabled)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminDemoConfig","description":"Config del showcase 24/7 (slots + ritmos + enabled)"},"put":{"summary":"Editar config del showcase (videos/ritmos/slots) sin relanzar (v-132)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bots_per_live":{"type":"integer","minimum":0,"maximum":50},"chat_every_ms":{"type":"integer","minimum":500,"maximum":60000},"bid_every_ms":{"type":"integer","minimum":500,"maximum":60000},"round_sec":{"type":"integer","minimum":30,"maximum":21600},"lives":{"type":"array","maxItems":20,"items":{"type":"object","properties":{"slot":{"type":"integer"},"title":{"type":"string","maxLength":120},"category":{"type":"string","maxLength":40},"video_url":{"type":"string","maxLength":1000},"lots":{"type":"array","maxItems":50,"items":{"type":"object","properties":{"title":{"type":"string","maxLength":120},"image_url":{"type":"string","maxLength":1000},"start_usd":{"type":"string","maxLength":20}}}}}}}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"putAdminDemoConfig","description":"Editar config del showcase (videos/ritmos/slots) sin relanzar (v-132)"}},"/admin/demo/showcase/start":{"post":{"summary":"Encender el showcase 24/7 (worker lo mantiene vivo) (v-132)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminDemoShowcaseStart","description":"Encender el showcase 24/7 (worker lo mantiene vivo) (v-132)"}},"/admin/demo/showcase/stop":{"post":{"summary":"Apagar el showcase 24/7 (v-132)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminDemoShowcaseStop","description":"Apagar el showcase 24/7 (v-132)"}},"/admin/promo-codes":{"post":{"summary":"Crear código promo (solo admin)","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","amount_usd"],"properties":{"code":{"type":"string","minLength":3,"maxLength":30,"pattern":"^[a-zA-Z0-9_-]+$"},"amount_usd":{"type":"number","exclusiveMinimum":0,"maximum":100},"max_uses":{"type":"integer","minimum":1,"maximum":100000,"default":100},"expires_at":{"type":"string","format":"date-time"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminPromoCodes","description":"Crear código promo (solo admin)"},"get":{"summary":"Listar códigos promo (solo admin)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminPromoCodes","description":"Listar códigos promo (solo admin)"}},"/admin/promo-codes/{code}/deactivate":{"post":{"summary":"Desactivar código promo","tags":["Admin"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminPromoCodesByCodeDeactivate","description":"Desactivar código promo"}},"/admin/refunds":{"get":{"summary":"Cola de reembolsos manuales (solo admin)","tags":["Admin"],"parameters":[{"schema":{"type":"string","enum":["open","processing","done","rejected"]},"in":"query","name":"status","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminRefunds","description":"Cola de reembolsos manuales (solo admin)"}},"/admin/refunds/{id}/resolve":{"post":{"summary":"Resolver reembolso: done (transferido) | rejected — solo admin","tags":["Admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["done","rejected"]},"note":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postAdminRefundsByIdResolve","description":"Resolver reembolso: done (transferido) | rejected — solo admin"}},"/admin/metrics/concurrency":{"get":{"summary":"Espectadores de video concurrentes (todos los lives) + alarma (v-122)","tags":["Admin"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminMetricsConcurrency","description":"Espectadores de video concurrentes (todos los lives) + alarma (v-122)"}},"/push/public-key":{"get":{"summary":"Clave pública VAPID para suscribirse (Anexo A)","tags":["Push"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"public_key":{"type":"string","nullable":true}}}}}}},"operationId":"getPushPublicKey","description":"Clave pública VAPID para suscribirse (Anexo A)"}},"/me/push-subscriptions":{"get":{"summary":"Mis suscripciones push (diagnóstico, endpoints enmascarados)","tags":["Push"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getMePushSubscriptions","description":"Mis suscripciones push (diagnóstico, endpoints enmascarados)"},"post":{"summary":"Registrar suscripción de push del dispositivo","tags":["Push"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["endpoint","keys"],"properties":{"endpoint":{"type":"string"},"keys":{"type":"object","required":["p256dh","auth"],"properties":{"p256dh":{"type":"string"},"auth":{"type":"string"}}}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postMePushSubscriptions","description":"Registrar suscripción de push del dispositivo"},"delete":{"summary":"Borrar una suscripción de push","tags":["Push"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["endpoint"],"properties":{"endpoint":{"type":"string"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteMePushSubscriptions","description":"Borrar una suscripción de push"}},"/me/push-test":{"post":{"summary":"Enviarme un push de prueba + diagnóstico (v-120)","tags":["Push"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postMePushTest","description":"Enviarme un push de prueba + diagnóstico (v-120)"}},"/reports/":{"post":{"summary":"Reportar (v-93: categoría + detalle obligatorio)","tags":["Reportes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target_type","target_id","category","reason"],"properties":{"target_type":{"type":"string","enum":["user","live","message","seller","product"]},"target_id":{"type":"string","format":"uuid"},"category":{"type":"string","enum":["emergencia","inapropiado","prohibidos","estafa","menores","abuso"]},"reason":{"type":"string","minLength":5,"maxLength":1000}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postReports","description":"Reportar (v-93: categoría + detalle obligatorio)"}},"/reports/mine":{"get":{"summary":"Mis reportes con estado (tracker)","tags":["Reportes"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getReportsMine","description":"Mis reportes con estado (tracker)"}},"/categories/tree":{"get":{"summary":"Árbol de categorías activas con live_count + viewer_count en vivo (público)","tags":["Lives"],"parameters":[{"schema":{"type":"string","enum":["recommended","popular","az"],"default":"recommended"},"in":"query","name":"sort","required":false,"description":"recommended = orden curado (sort_order) · popular = viewer_count · az = nombre (v-113)"}],"responses":{"200":{"description":"Default Response"}},"operationId":"getCategoriesTree","description":"Árbol de categorías activas con live_count + viewer_count en vivo (público)"}},"/categories/{slug}/follow":{"post":{"summary":"Seguir una categoría (v-114)","tags":["Categorías"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postCategoriesBySlugFollow","description":"Seguir una categoría (v-114)"},"delete":{"summary":"Dejar de seguir una categoría (v-114)","tags":["Categorías"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteCategoriesBySlugFollow","description":"Dejar de seguir una categoría (v-114)"}},"/me/followed-categories":{"get":{"summary":"Mis categorías seguidas (v-114)","tags":["Categorías"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getMeFollowedCategories","description":"Mis categorías seguidas (v-114)"}},"/categories":{"get":{"summary":"Catálogo de categorías ACTIVAS (para el picker de onboarding y los filtros del home)","tags":["Categorías"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"emoji":{"type":"string","nullable":true},"parent_slug":{"type":"string","nullable":true},"sort_order":{"type":"integer"},"active":{"type":"boolean"}}}}}}}},"operationId":"getCategories","description":"Catálogo de categorías ACTIVAS (para el picker de onboarding y los filtros del home)"}},"/admin/categories/ingest":{"post":{"summary":"Ingestar categorías desde CSV (multipart: file). Upsert por slug, no duplica.","tags":["Categorías"],"description":"CSV con encabezado. Columnas por NOMBRE (orden libre): slug,name,emoji,parent_slug,sort_order,active. Requiere al menos slug y name. El slug se normaliza (minúsculas, guiones). Re-ingestar ACTUALIZA lo existente. Campo de texto opcional 'deactivate_missing'=true (enviarlo ANTES del file) → desactiva las que no vengan en el CSV.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"inserted":{"type":"integer"},"updated":{"type":"integer"},"deactivated":{"type":"integer"},"skipped":{"type":"integer","description":"filas sin slug/name válidos"},"total_rows":{"type":"integer"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}},"424":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"detalle":{"type":"string"}}}}}}},"operationId":"postAdminCategoriesIngest"}},"/admin/categories":{"get":{"summary":"Listar todo el catálogo (admin, incluye inactivas)","tags":["Categorías"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getAdminCategories","description":"Listar todo el catálogo (admin, incluye inactivas)"}},"/admin/categories/{slug}":{"put":{"summary":"Crear o editar una categoría (JSON)","tags":["Categorías"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"emoji":{"type":"string","maxLength":16,"nullable":true},"parent_slug":{"type":"string","nullable":true},"sort_order":{"type":"integer"},"active":{"type":"boolean"}}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"putAdminCategoriesBySlug","description":"Crear o editar una categoría (JSON)"},"delete":{"summary":"Desactivar una categoría (soft: active=false)","tags":["Categorías"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteAdminCategoriesBySlug","description":"Desactivar una categoría (soft: active=false)"}},"/bcv":{"get":{"summary":"Tasa BCV actual (Bs/USD) — para montos en vivo (v-103)","tags":["Perfil"],"responses":{"200":{"description":"Default Response"}},"operationId":"getBcv","description":"Tasa BCV actual (Bs/USD) — para montos en vivo (v-103)"}},"/support/topics":{"get":{"summary":"Help center: árbol de temas → artículos (v-109)","tags":["Soporte"],"responses":{"200":{"description":"Default Response"}},"operationId":"getSupportTopics","description":"Help center: árbol de temas → artículos (v-109)"}},"/support/topics/{topic}/{article}":{"get":{"summary":"Help center: artículo con pasos y acción sugerida (v-109)","tags":["Soporte"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"topic","required":true},{"schema":{"type":"string"},"in":"path","name":"article","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"getSupportTopicsByTopicByArticle","description":"Help center: artículo con pasos y acción sugerida (v-109)"}},"/clips":{"post":{"summary":"Guardar un clip (metadata; el video ya está en R2). order_id = Video Receipt (v-110)","tags":["Clips"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["video_url"],"properties":{"live_id":{"type":"string","format":"uuid"},"order_id":{"type":"string","format":"uuid","description":"Liga el clip a una orden (Video Receipt)"},"title":{"type":"string","maxLength":120},"video_url":{"type":"string","maxLength":600},"thumb_url":{"type":"string","maxLength":600},"start_ms":{"type":"integer","minimum":0},"end_ms":{"type":"integer","minimum":0},"visibility":{"type":"string","enum":["private","public"],"default":"private"},"ttl_hours":{"type":"number","minimum":1,"maximum":8760,"description":"TTL opcional (receipt efímero)"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postClips","description":"Guardar un clip (metadata; el video ya está en R2). order_id = Video Receipt (v-110)"},"get":{"summary":"Mis clips (v-110)","tags":["Clips"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getClips","description":"Mis clips (v-110)"}},"/clips/{id}":{"get":{"summary":"Ver un clip (público si compartido y vigente) (v-110)","tags":["Clips"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"getClipsById","description":"Ver un clip (público si compartido y vigente) (v-110)"},"delete":{"summary":"Borrar un clip propio (v-110)","tags":["Clips"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"deleteClipsById","description":"Borrar un clip propio (v-110)"}},"/lives/{id}/clips":{"get":{"summary":"Clips públicos de un live (v-110)","tags":["Clips"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response"}},"operationId":"getLivesByIdClips","description":"Clips públicos de un live (v-110)"}},"/coins/packs":{"get":{"summary":"Paquetes de coins a la venta (v-160)","tags":["Coins"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"label":{"type":"string"},"coins":{"type":"integer","description":"coins base"},"bonus_coins":{"type":"integer","description":"extra promocional"},"total_coins":{"type":"integer","description":"coins + bonus — lo que se acredita"},"price_usd":{"type":"number"},"apple_product_id":{"type":"string","nullable":true},"google_product_id":{"type":"string","nullable":true}}}}}}}},"operationId":"getCoinsPacks","description":"Paquetes de coins a la venta (v-160)"}},"/coins/balance":{"get":{"summary":"Mi saldo de coins (v-160)","tags":["Coins"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"balance":{"type":"integer"},"lifetime_earned":{"type":"integer","description":"recibidas por regalos (vendedor)"},"lifetime_spent":{"type":"integer","description":"gastadas en regalos"}}}}}}},"operationId":"getCoinsBalance","description":"Mi saldo de coins (v-160)"}},"/coins/ledger":{"get":{"summary":"Movimientos de mis coins (v-160)","tags":["Coins"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"before","required":false,"description":"paginación: created_at del último visto (ISO)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getCoinsLedger","description":"Movimientos de mis coins (v-160)"}},"/coins/purchase":{"post":{"summary":"Comprar un paquete de coins (v-160)","tags":["Coins"],"description":"Crea la compra con el precio y los coins CONGELADOS del pack. Con `channel=stripe_card` cobra la tarjeta guardada al instante. Con `channel=veb_ves` congela la tasa BCV y devuelve el monto en Bs: el pago se completa con `/c2p/request` + `/c2p/confirm` (Débito Inmediato) o con `/reference` (transferencia ya hecha).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pack_code","channel"],"properties":{"pack_code":{"type":"string"},"channel":{"type":"string","enum":["stripe_card","veb_ves"]}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postCoinsPurchase"}},"/coins/purchases":{"get":{"summary":"Mis compras de coins (v-160)","tags":["Coins"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getCoinsPurchases","description":"Mis compras de coins (v-160)"}},"/coins/purchases/{id}/c2p/request":{"post":{"summary":"Débito Inmediato: pedir la clave por SMS para pagar coins (v-160)","tags":["Coins"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bank_code","phone"],"properties":{"bank_code":{"type":"string","description":"código SUDEBAN de GET /payment-methods/veb/banks"},"phone":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postCoinsPurchasesByIdC2pRequest","description":"Débito Inmediato: pedir la clave por SMS para pagar coins (v-160)"}},"/coins/purchases/{id}/c2p/confirm":{"post":{"summary":"Débito Inmediato: confirmar con la clave del SMS (v-160)","tags":["Coins"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","pattern":"^\\d{6,8}$"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postCoinsPurchasesByIdC2pConfirm","description":"Débito Inmediato: confirmar con la clave del SMS (v-160)"}},"/coins/purchases/{id}/reference":{"post":{"summary":"Reportar la referencia de una transferencia Pago Móvil por coins (v-160)","tags":["Coins"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reference"],"properties":{"reference":{"type":"string","pattern":"^\\d{4,32}$"},"date":{"type":"string","description":"YYYY-MM-DD del movimiento (opcional)"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postCoinsPurchasesByIdReference","description":"Reportar la referencia de una transferencia Pago Móvil por coins (v-160)"}},"/gifts/send":{"post":{"summary":"Enviar un regalo en el live — descuenta coins (v-160)","tags":["Coins"],"description":"El costo sale del catálogo del servidor (GET /gifts), no del body. El descuento es atómico: si no alcanza responde 409 `saldo_insuficiente`. Al acreditarse difunde el evento WS `gift` al room, igual que antes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["live_id","code"],"properties":{"live_id":{"type":"string","format":"uuid"},"code":{"type":"string","description":"código del regalo (GET /gifts)"},"qty":{"type":"integer","minimum":1,"maximum":50,"default":1}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"balance":{"type":"integer"},"coins_spent":{"type":"integer"},"gift_id":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"balance":{"type":"integer"},"needed":{"type":"integer"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}},"operationId":"postGiftsSend"}},"/coins/earnings":{"get":{"summary":"Coins ganadas por regalos y condiciones de canje (v-160)","tags":["Coins"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"balance":{"type":"integer","description":"coins disponibles para canjear"},"lifetime_earned":{"type":"integer"},"rate_usd":{"type":"number","description":"USD por coin al canjear"},"fee_pct":{"type":"number","description":"comisión de La Ganga sobre el canje"},"min_coins":{"type":"integer","description":"mínimo canjeable"},"estimated_net_usd":{"type":"number","description":"lo que recibiría hoy por todo su saldo"}}}}}}},"operationId":"getCoinsEarnings","description":"Coins ganadas por regalos y condiciones de canje (v-160)"}},"/coins/redeem":{"post":{"summary":"Canjear coins por saldo en USD (v-160)","tags":["Coins"],"description":"Convierte coins en saldo retirable. La Ganga retiene `coin_redeem_fee_pct` (10% por defecto). El neto entra al balance del vendedor y sale por los retiros normales.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"coins":{"type":"integer","minimum":1,"description":"omitir = canjear todo el saldo"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postCoinsRedeem"}},"/coins/redemptions":{"get":{"summary":"Historial de canjes (v-160)","tags":["Coins"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getCoinsRedemptions","description":"Historial de canjes (v-160)"}},"/coins/gifts/received":{"get":{"summary":"Regalos que he recibido (v-160)","tags":["Coins"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"query","name":"live_id","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"limit","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getCoinsGiftsReceived","description":"Regalos que he recibido (v-160)"}},"/me/wellbeing":{"get":{"summary":"Mis controles de bienestar (límites + PIN) (v-111)","tags":["Perfil"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"getMeWellbeing","description":"Mis controles de bienestar (límites + PIN) (v-111)"},"put":{"summary":"Fijar controles de bienestar (v-111)","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"watch_minutes_per_day":{"type":"integer","minimum":0,"maximum":1440,"nullable":true},"spend_limit_usd":{"type":"string","description":"USD como string; null/omitido = sin tope"},"spend_window":{"type":"string","enum":["day","week","month"]},"pin":{"type":"string","minLength":4,"maxLength":12,"description":"Set/clear del PIN; omitir = no tocar"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"putMeWellbeing","description":"Fijar controles de bienestar (v-111)"}},"/me/wellbeing/verify-pin":{"post":{"summary":"Verificar el PIN de bienestar (v-111)","tags":["Perfil"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pin"],"properties":{"pin":{"type":"string"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}},"operationId":"postMeWellbeingVerifyPin","description":"Verificar el PIN de bienestar (v-111)"}},"/openapi.json":{"get":{"responses":{"200":{"description":"Default Response"}},"operationId":"getOpenapiJson","description":"GET /openapi.json","summary":"GET /openapi.json"}}},"servers":[{"url":"https://api.laganga.live","description":"Producción (Coolify)"}],"tags":[{"name":"Auth","description":"Registro, login, verificación (§12, §15)"},{"name":"Perfil","description":"Datos propios, incl. cédula para SPIDI (§9.0)"},{"name":"Vendedor","description":"Alta y KYC del vendedor (§12)"},{"name":"Productos","description":"Catálogo; fotos por URL firmada de R2 (§5)"},{"name":"Lives","description":"Transmisiones y home (§12, §13)"},{"name":"Auction Engine","description":"Abrir/cerrar subastas + precio fijo buy_now (§7). Las PUJAS van por WS (§10)"},{"name":"Run of Show","description":"Cola de lotes en vivo: sorteos (giveaways) + formatos de lote (v-66)"},{"name":"Cupones","description":"Regalo de bienvenida (v-69): 1 por usuario, aplicado server-side al cobrar"},{"name":"Marketplace","description":"Gangas directas (v-92): tienda sin live, video TikTok, compra inmediata"},{"name":"Shopify","description":"Conectar la tienda del vendedor e importar su catálogo (Custom App token)"},{"name":"Métodos de pago","description":"Tarjetas Stripe card-on-file (§9.1)"},{"name":"Órdenes / Pagos","description":"Órdenes, pay_url SPIDI y polling de estado (§9)"},{"name":"Webhooks","description":"Stripe/SPIDI: idempotentes, firma verificada (§9.7)"},{"name":"LiveKit","description":"Tokens de video por rol (§11)"},{"name":"Admin","description":"Panel super admin: usuarios/KYC, órdenes, métricas (§18)"},{"name":"Push","description":"Web Push (VAPID, Anexo A Fase 2). WS en la sala, push fuera"},{"name":"Reportes","description":"Moderación: reportar usuario/live/mensaje"},{"name":"Coins","description":"Monedas de los regalos (v-160): compra de paquetes, saldo, envío de regalos y canje a USD del vendedor (La Ganga retiene su comisión en el canje)"}],"externalDocs":{"description":"LaGanga para desarrolladores","url":"https://laganga.live/developers"}}