{"openapi":"3.1.0","info":{"title":"Hotiq API","version":"0.1.0","description":"API back-end de l'ad spy e-commerce Afrique de l'Ouest. Auth : POST /api/auth/otp/request puis /verify, renvoie un JWT à passer en `Authorization: Bearer`. Sans jeton ou en plan Découverte : 3 résultats max, score et numéros WhatsApp masqués. Erreurs : `{ error: { code, message } }`. Montants en FCFA."},"servers":[{"url":"https://api.hotiq.app"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"responses":{"Error":{"description":"Erreur","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"paths":{"/api/health":{"get":{"summary":"Santé + nombre de pubs","tags":["Système"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}}}},"/api/auth/otp/request":{"post":{"summary":"Envoyer un code OTP (e-mail ou téléphone 229/225/221/228/237)","tags":["Auth"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target":{"type":"string"}}}}}}}},"/api/auth/otp/verify":{"post":{"summary":"Vérifier le code, renvoie { token, isNew, user }","tags":["Auth"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target":{"type":"string"},"code":{"type":"string"}}}}}}}},"/api/me":{"get":{"summary":"Profil, plan, limites","tags":["Compte"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}]},"patch":{"summary":"Onboarding (pays, niche, budget, déjà vendu en COD)","tags":["Compte"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"country":{"type":"string","enum":["BJ","CI","SN","TG","CM"]},"niche":{"type":"string"},"dailyAdBudgetFcfa":{"type":"integer"},"hasSoldCod":{"type":"boolean"}}}}}}}},"/api/plans":{"get":{"summary":"Plans et prix","tags":["Compte"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}}}},"/api/ads":{"get":{"summary":"Recherche de pubs","tags":["Ad Spy"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Mot-clé (texte, titre, domaine)"},{"name":"country","in":"query","required":false,"schema":{"type":"string"},"description":"BJ,CI,SN,TG,CM (séparés par virgule)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer"},"description":""},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"max 50"},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["image","video","carousel","dpa","dco","other"]},"description":""},{"name":"funnel","in":"query","required":false,"schema":{"type":"string","enum":["whatsapp","shopify","youcan","woocommerce","landing","messenger","unknown"]},"description":"Type de tunnel"},{"name":"minDays","in":"query","required":false,"schema":{"type":"integer"},"description":"Jours actifs min"},{"name":"minScore","in":"query","required":false,"schema":{"type":"integer"},"description":"Score min 0-100"},{"name":"hasPrice","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]},"description":"Prix FCFA détecté"},{"name":"activeOnly","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]},"description":"défaut true"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["score","days","recent","variants"]},"description":""}]}},"/api/ads/{id}":{"get":{"summary":"Fiche pub + historique quotidien","tags":["Ad Spy"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ad_archive_id Meta"}]}},"/api/advertisers/{id}":{"get":{"summary":"Fiche concurrent : pubs, tunnels, produits","tags":["Ad Spy"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"page_id Meta"}]}},"/api/products":{"get":{"summary":"Produits gagnants (pubs regroupées)","tags":["Ad Spy"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Mot-clé (texte, titre, domaine)"},{"name":"country","in":"query","required":false,"schema":{"type":"string"},"description":"BJ,CI,SN,TG,CM (séparés par virgule)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer"},"description":""},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"max 50"},{"name":"minScore","in":"query","required":false,"schema":{"type":"integer"},"description":""},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["score","ads","advertisers","recent"]},"description":""}]}},"/api/products/{id}":{"get":{"summary":"Fiche produit + pubs","tags":["Ad Spy"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}]}},"/api/stats":{"get":{"summary":"Pubs suivies par pays (landing)","tags":["Public"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}}}},"/api/margin":{"post":{"summary":"Calculateur de marge COD","tags":["Public"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"productCost":{"type":"number"},"freight":{"type":"number"},"delivery":{"type":"number"},"cpa":{"type":"number"},"refusalRate":{"type":"number"},"callCost":{"type":"number"},"sellingPrice":{"type":"number"}}}}}}}},"/api/favorites":{"get":{"summary":"Mes favoris","tags":["Favoris"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}]},"post":{"summary":"Ajouter","tags":["Favoris"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"adId":{"type":"string"},"collection":{"type":"string"}}}}}}},"delete":{"summary":"Retirer","tags":["Favoris"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"adId":{"type":"string"},"collection":{"type":"string"}}}}}}}},"/api/pages":{"get":{"summary":"Mes pages de vente","tags":["Pages"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}]},"post":{"summary":"Créer une page","tags":["Pages"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string"},"priceFcfa":{"type":"integer"},"comparePriceFcfa":{"type":"integer"},"images":{"type":"array","items":{"type":"string"}},"whatsappNumber":{"type":"string"},"depositType":{"type":"string","enum":["percent","fixed"]},"depositValue":{"type":"integer"},"content":{"type":"object"},"sourceAdId":{"type":"string"},"published":{"type":"boolean"}}}}}}}},"/api/pages/{id}":{"get":{"summary":"Lire","tags":["Pages"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}]},"patch":{"summary":"Modifier","tags":["Pages"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string"},"priceFcfa":{"type":"integer"},"comparePriceFcfa":{"type":"integer"},"images":{"type":"array","items":{"type":"string"}},"whatsappNumber":{"type":"string"},"depositType":{"type":"string","enum":["percent","fixed"]},"depositValue":{"type":"integer"},"content":{"type":"object"},"sourceAdId":{"type":"string"},"published":{"type":"boolean"}}}}}}},"delete":{"summary":"Supprimer","tags":["Pages"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}]}},"/api/public/pages/{slug}":{"get":{"summary":"Page publiée (rendu front)","tags":["Public"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":""}]}},"/api/public/pages/{slug}/orders":{"post":{"summary":"Checkout COD : renvoie orderId, whatsappUrl, acompte","tags":["Public"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":""}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"customerName":{"type":"string"},"phone":{"type":"string"},"city":{"type":"string"},"district":{"type":"string"},"quantity":{"type":"integer"},"note":{"type":"string"}}}}}}}},"/api/orders":{"get":{"summary":"Mes commandes (format=csv pour export)","tags":["Commandes"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["nouvelle","confirmee","livree","refusee","annulee"]},"description":""},{"name":"pageId","in":"query","required":false,"schema":{"type":"integer"},"description":""},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["json","csv"]},"description":""}]}},"/api/orders/{id}":{"patch":{"summary":"Changer le statut","tags":["Commandes"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["nouvelle","confirmee","livree","refusee","annulee"]},"note":{"type":"string"}}}}}}}},"/api/admin/runs":{"get":{"summary":"Santé de la collecte et coût Apify (admin)","tags":["Admin"],"responses":{"200":{"description":"OK"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":[]}]}},"/api/billing/checkout":{"post":{"summary":"Démarrer un abonnement payant : renvoie { payUrl } (page de paiement mobile money AbonaPay). Le plan s'active au paiement.","tags":["Compte"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["vendeur","pro","agence"]}}}}}},"responses":{"200":{"description":"OK"},"502":{"$ref":"#/components/responses/Error"}}}}}}