QueryWin repère les requêtes pour lesquelles votre site obtient déjà des impressions sans qu’aucune page n’y réponde, rédige l’article manquant et prépare votre produit pour sa soumission aux annuaires, plateformes de lancement, communautés et sites déjà cités dans les réponses des IA. Cette API confie ces deux chaînes à vos scripts et à vos assistants IA. La publication et la soumission se font toujours avec vos propres identifiants et comptes : QueryWin ne se connecte jamais à votre CMS et ne soumet jamais rien lui-même.
Trois étapes. Tout ce qui suit est un simple appel REST avec un seul en-tête.
1
Créer une clé
Dans le tableau de bord QueryWin, rubrique « API ». La clé en clair ne s’affiche qu’une fois, à sa création. N’accordez que les scopes nécessaires : une clé sans aucune case cochée est en lecture seule.
2
Transmettre la clé en jeton Bearer
Ajoutez l’en-tête Authorization (valeur Bearer qw_live_…) à chaque requête. X-API-Key fonctionne aussi, pour les outils qui ne permettent de définir qu’un seul en-tête.
3
Savoir quoi écrire, puis récupérer le brouillon
La liste des sujets est gratuite et ne consomme aucun crédit. Générer un plan ou un brouillon débite des crédits et nécessite le scope spend.
bash
# 1. Sites sur lesquels cette clé peut agir
curl "https://www.querywin.com/api/v1/sites" \
-H "Authorization: Bearer $QUERYWIN_API_KEY"
# 2. Sujets à écrire cette semaine (gratuit, aucun crédit)
curl "https://www.querywin.com/api/v1/topics?siteId=YOUR_SITE_ID" \
-H "Authorization: Bearer $QUERYWIN_API_KEY"
bash
# 3. Récupérer le brouillon (Markdown + JSON-LD avec les données renseignées)
curl "https://www.querywin.com/api/v1/topics/article?siteId=YOUR_SITE_ID&key=standard%20wardrobe%20depth" \
-H "Authorization: Bearer $QUERYWIN_API_KEY"
# 4. Votre script le publie sur votre propre blog, puis renvoie l’URL
curl -X POST https://www.querywin.com/api/v1/topics/published \
-H "Authorization: Bearer $QUERYWIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"siteId": "YOUR_SITE_ID",
"key": "standard wardrobe depth",
"url": "https://example.com/blog/standard-wardrobe-depth"
}'
Chaque réponse est encapsulée : {"success": true, "data": …}. Les erreurs sont des codes lisibles par une machine, jamais des phrases : QueryWin est multilingue, et une phrase en anglais codée en dur finirait affichée telle quelle sur une page en français.
La chaîne de contenu
Cinq étapes, dont deux seulement sont payantes. L’étape 4 vous revient : QueryWin vous remet le Markdown et les données structurées, et c’est vous qui publiez.
Étape
Endpoint
Coût
Trouver les requêtes avec des impressions mais sans page
GET /v1/topics
Gratuit
Générer un plan étayé par des sources
POST /v1/topics/outline
Crédits
En faire un brouillon publiable
POST /v1/topics/article
Crédits
Le publier sur votre propre blog
votre propre CMS
—
Renvoyer l’URL à QueryWin
POST /v1/topics/published
Gratuit
QueryWin ne se connecte jamais à votre CMS, ne détient jamais les identifiants de votre site et ne publie jamais à votre place. Cette API vous remet le contenu ; l’écriture se fait sur votre machine, avec vos propres identifiants. C’est la limite elle-même, pas une façon de la contourner.
La chaîne de diffusion
Sept étapes, dont une seule est payante. L’étape 6 vous revient : QueryWin vous remet les contenus de soumission de chaque canal, et c’est vous (ou votre agent, avec vos propres comptes) qui les soumettez. QueryWin revérifie ensuite lui-même chaque fiche publiée.
Étape
Endpoint
Coût
Lister vos produits et le taux de complétion de chaque fiche
GET /v1/products
Gratuit
Lister les canaux où soumettre, triés par pertinence, y compris les sites que citent les réponses des IA
GET /v1/channels?productId=
Gratuit
Créer une campagne à partir des canaux choisis
POST /v1/campaigns
Gratuit
Récupérer les contenus préparés d’une tâche
GET /v1/tasks/{id}
Gratuit
Les réécrire pour ce canal
POST /v1/tasks/{id}/materials
Crédits
Les soumettre
vos propres comptes
—
Signaler la soumission, puis la publication avec l’URL de la fiche
POST /v1/tasks/{id}/status
Gratuit
published correspond à ce que vous avez déclaré ; verified, à ce que QueryWin a constaté en revérifiant la fiche environ 72 heures plus tard : un lien vers votre produit sur les annuaires (y compris d’outils IA), une mention partout ailleurs. Ce sont deux champs distincts. Et un site cité dans les réponses des IA (citedByAi) vaut la peine d’être sollicité ; ce n’est pas une garantie qu’il vous référencera.
Scopes
Chaque clé porte les permissions accordées à sa création. GET /v1/usage les renvoie : inutile de les découvrir en tombant sur une erreur 403.
read
Toujours actif
Tous les endpoints GET : sites, lacunes de contenu, plans, brouillons, produits, canaux, campagnes, tâches et leurs contenus, consommation.
publish
Désactivé par défaut
Créer et mettre à jour des fiches produit, importer des images et enregistrer ce qui s’est passé : l’URL d’un article publié (également soumise à Bing, Yandex, Seznam et Naver, pas à Google), une nouvelle campagne, une tâche marquée comme soumise ou publiée. Gratuit, mais chaque appel crée un enregistrement qui a des conséquences : les campagnes sont décomptées de votre offre, et une fiche publiée est revérifiée.
spend
Désactivé par défaut
Générer des plans et des brouillons, et réécrire des contenus de soumission pour un canal. Ces actions débitent des crédits. N’accordez ce scope que si vous voulez que l’appelant (un script ou un assistant IA) puisse dépenser de lui-même.
Il n’y a pas de hiérarchie : publish n’implique pas spend, et spend n’implique pas publish. Ce sont deux types de risque différents. Un appel pour lequel votre clé n’a pas le scope requis renvoie une erreur 403 avec missing_scope_<name> et la liste des scopes dont vous disposez.
Consommation de crédits
Deux endpoints débitent des crédits : POST /v1/topics/outline et POST /v1/topics/article. Trois garde-fous les protègent.
Garde-fou
Ce qu’il empêche
confirmSpend
Un script qui continue d’être débité après une hausse de prix.
Limite quotidienne
Une boucle incontrôlée qui épuise le solde en une nuit. Renvoie une erreur 429 avec l’heure de réinitialisation.
Empreinte des entrées
Un double débit pour le même sujet. Des entrées identiques renvoient gratuitement le résultat en cache : vous pouvez relancer sans risque une requête expirée.
confirmSpend est un plafond d’autorisation, pas un montant exact. Envoyez une valeur supérieure ou égale au prix actuel : seul le coût réel est débité, souvent zéro quand le résultat est en cache. Si le prix dépasse un jour votre plafond, l’appel échoue avec confirm_spend_too_low au lieu de débiter davantage en silence.
Les erreurs sont des codes, jamais des phrases. Interprétez ces codes au lieu de les afficher tels quels : ils sont faits pour être convertis en vos propres libellés.
Un résultat métier n’est pas une erreur
Un appel de génération qui n’a pas pu produire de résultat valide renvoie HTTP 200 avec data.ok = false et un code data.failure : vous pouvez ainsi le distinguer d’un échec d’authentification ou d’une connexion interrompue. Ces appels ne sont pas facturés.
120 requêtes par minute et par clé. Au-delà, vous recevez une erreur 429 avec l’heure de réinitialisation. Cette limite est distincte de la limite quotidienne de génération ci-dessus.
MCP pour les agents IA
Les deux chaînes sont disponibles via le Model Context Protocol, avec la même clé et le même en-tête d’authentification. Ajoutez le serveur à Claude Code, Cursor, n8n ou tout autre outil compatible MCP sur HTTP.
Dix-neuf outils. Fiches produit : create_product, get_product, update_product, import_product_image. Contenu : list_sites, get_usage, list_content_gaps, get_outline, get_article_draft, generate_outline, generate_article_draft, mark_published. Diffusion : list_products, list_channels, create_campaign, list_tasks, get_task, write_task_materials, report_task_status. Demandez à votre assistant quoi écrire cette semaine ou où soumettre votre produit ensuite : il ira chercher la réponse lui-même.
prompt
À l’aide du serveur MCP QueryWin, trouvez les trois plus grosses lacunes de contenu de mon site,
montrez-moi les requêtes derrière chacune et dites-moi combien coûterait le brouillon de la première.
Les outils sont filtrés par scope. Avec une clé en lecture seule, les outils de génération n’apparaissent même pas dans la liste d’outils de l’assistant : un agent ne peut pas appeler un outil qu’il ne voit pas. Donnez à chaque agent sa propre clé, pour pouvoir la révoquer sans toucher à vos autres intégrations.
L’authentification se fait par jeton Bearer, ce que la spécification MCP autorise (l’autorisation y est facultative). Les clients qui permettent de définir un en-tête (Claude Code, Cursor, n8n) se connectent directement. Les hôtes qui exigent un écran de consentement OAuth risquent de ne pas y parvenir.
Account
GET/v1/sites
Lister les sites sur lesquels cette clé peut agir
Commencez ici. Tous les autres endpoints prennent le siteId renvoyé par cet appel. Sans siteId, ils se rabattent sur le premier site connecté : sans conséquence pour un compte à site unique, mais un bug en puissance pour tous les autres.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
SiteList
└sites
array<Site>
└siteId
string
└domain
string
└gscProperty
string
La propriété Search Console, telle quelle : sc-domain:example.com ou https://example.com/.
└syncStatus
enum
Valeurs : pendingsyncingdonefailed
└syncedThroughpeut être null
string
Les données Search Console ont 2 à 3 jours de décalage. Chaque indicateur de ce site est arrêté à cette date : précisez-le si vous affichez ces chiffres, où que ce soit.
Prix actuels, générations gratuites, solde de crédits et limites quotidiennes
À lire avant toute génération. C’est la même source de vérité que celle dont se sert l’interface web pour décider de ce qu’affiche chaque bouton : la disponibilité est décidée côté serveur, et non à force d’essais et d’erreurs.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
Usage
└scopes
array<enum>
Ce que cette clé a le droit de faire. Lisez-le une fois au démarrage, plutôt que de découvrir vos droits en tombant sur une erreur 403.Valeurs : readpublishspend
└credits
object
└balance
integer
└outline
StepUsage
└available
boolean
Vaut false lorsque le moteur de génération n’est pas configuré. N’appelez pas alors l’endpoint POST correspondant.
└pricePerOutline
integer
Crédits par plan (présent uniquement sur outline).
└pricePerArticle
integer
Crédits par brouillon (présent uniquement sur article).
└pricePerTask
integer
Crédits par réécriture pour un canal (présent uniquement sur materials).
└freeRemaining
integer
Générations gratuites restantes sur ce compte, comptées par sujet distinct (plans, brouillons) ou par tâche distincte (contenus), et non par clic sur un bouton. Les générations gratuites exigent elles aussi confirmSpend.
└daily
DailyLimit
Garde-fou contre un script qui s’emballe, comptabilisé en base de données sur tous les points d’entrée (les actions dans l’interface web comptent aussi). Remise à zéro à minuit, heure locale, et non sur une fenêtre glissante.
└used
integer
└limit
integer
└remaining
integer
└resetAt
string
└article
StepUsage
└available
boolean
Vaut false lorsque le moteur de génération n’est pas configuré. N’appelez pas alors l’endpoint POST correspondant.
└pricePerOutline
integer
Crédits par plan (présent uniquement sur outline).
└pricePerArticle
integer
Crédits par brouillon (présent uniquement sur article).
└pricePerTask
integer
Crédits par réécriture pour un canal (présent uniquement sur materials).
└freeRemaining
integer
Générations gratuites restantes sur ce compte, comptées par sujet distinct (plans, brouillons) ou par tâche distincte (contenus), et non par clic sur un bouton. Les générations gratuites exigent elles aussi confirmSpend.
└daily
DailyLimit
Garde-fou contre un script qui s’emballe, comptabilisé en base de données sur tous les points d’entrée (les actions dans l’interface web comptent aussi). Remise à zéro à minuit, heure locale, et non sur une fenêtre glissante.
└used
integer
└limit
integer
└remaining
integer
└resetAt
string
└materials
StepUsage
└available
boolean
Vaut false lorsque le moteur de génération n’est pas configuré. N’appelez pas alors l’endpoint POST correspondant.
└pricePerOutline
integer
Crédits par plan (présent uniquement sur outline).
└pricePerArticle
integer
Crédits par brouillon (présent uniquement sur article).
└pricePerTask
integer
Crédits par réécriture pour un canal (présent uniquement sur materials).
└freeRemaining
integer
Générations gratuites restantes sur ce compte, comptées par sujet distinct (plans, brouillons) ou par tâche distincte (contenus), et non par clic sur un bouton. Les générations gratuites exigent elles aussi confirmSpend.
└daily
DailyLimit
Garde-fou contre un script qui s’emballe, comptabilisé en base de données sur tous les points d’entrée (les actions dans l’interface web comptent aussi). Remise à zéro à minuit, heure locale, et non sur une fenêtre glissante.
└used
integer
└limit
integer
└remaining
integer
└resetAt
string
└distribution
DistributionQuota
Les limites de diffusion de l’offre et leur consommation actuelle. Une limite à null signifie qu’il n’y a pas de limite.
└plan
string
└limits
object
└channelspeut être null
integer
Nombre de canaux distincts sur lesquels un produit peut avoir des tâches, compté sur la période channelsPeriod.
└channelsPeriod
enum
month (offres payantes) : décompte par mois calendaire (UTC), chaque mois permet donc un nouveau lot de canaux. total (offre gratuite) : décompte sur toute la durée de vie du produit.Valeurs : monthtotal
└tasksPerMonthpeut être null
integer
Nombre de tâches pouvant être créées par mois calendaire (UTC), tous produits confondus.
└activeCampaignspeut être null
integer
Nombre de campagnes pouvant être actives simultanément.
Requêtes avec des impressions mais sans page dédiée
Gratuit, sans facturation externe (l’API elle-même nécessite une offre payante). Recalculé à chaque appel à partir de vos propres données Search Console, sans aucune base de mots-clés externe — et c’est tout l’intérêt : « vous avez déjà des impressions et aucune page pour y répondre », aucun outil de mots-clés ne peut vous le dire.
Les résultats sont triés par opportunité. Les sujets écartés par l’utilisateur dans l’interface sont exclus.
Paramètres de requête
Champ
Type
Description
siteId
string
Issu de GET /v1/sites. Par défaut, le premier site connecté.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
TopicList
└siteIdpeut être null
string
└topics
array<Topic>
└key
string
L’identifiant du cluster : renvoyez-le tel quel dans key à tous les autres endpoints de sujets. C’est le texte normalisé de la requête représentative ; il peut donc contenir des espaces, des barres obliques et des caractères non latins. Envoyez-le toujours en paramètre de requête ou dans le corps, jamais dans le chemin de l’URL.
└title
string
La requête du cluster qui génère le plus d’impressions, telle quelle. Ce n’est pas un titre généré : celui-ci est fourni avec le plan.
└shape
enum
comparison signifie que ce cluster recoupe votre liste de concurrents. L’article doit établir une comparaison, pas présenter le concurrent : sinon, c’est pour lui que vous écrivez.Valeurs : comparisonroundupguide
└intent
string
└members
array<TopicMember>
└text
string
La requête, telle que saisie.
└impressions
integer
└clicks
integer
└positionpeut être null
number
└landingUrlpeut être null
string
La page que Search Console associe actuellement à cette requête, s’il y en a une.
└impressions
integer
Valeur mesurée, issue de Search Console.
└clicks
integer
Valeur mesurée, issue de Search Console.
└positionpeut être null
number
Valeur mesurée : position moyenne sur le cluster, pondérée par les impressions.
└competitor
boolean
└score
number
└rank
integer
└upsideClicks
integer
Il s’agit d’une estimation, et non d’une mesure : clics supplémentaires par mois si une page dédiée atteignait la position 3. Ce champ est volontairement séparé de clicks et impressions, et doit rester visuellement distinct partout où vous l’affichez. Présenter une projection comme une donnée mesurée est l’écueil classique de cette catégorie de produits.
└status
enum
Valeurs : newdismissedplannedpublished
└outlineAtpeut être null
string
└articleAtpeut être null
string
Ne le déduisez pas de outlineAt. Avoir un plan ne signifie pas qu’un brouillon existe : ce sont deux étapes payantes distinctes.
└totalQueries
integer
Nombre total de requêtes distinctes couvertes par ces sujets.
Erreurs possibles
401Authentification refusée
404site_not_found — ce siteId n’appartient pas à ce compte
Ne déclenche jamais de génération et ne coûte jamais rien. article vaut null tant qu’aucun brouillon n’existe.
Paramètres de requête
Champ
Type
Description
keyobligatoire
string
L’identifiant du cluster, issu de GET /v1/topics.
siteId
string
Issu de GET /v1/sites. Par défaut, le premier site connecté.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
ArticleResult
└articlepeut être null
Article
└title
string
└description
string
Méta-description.
└markdown
string
Le corps à publier.
└jsonLd
string
Les données structurées de cet article, déjà remplies. JSON valide : placez-le dans une balise script de type application/ld+json sur la page publiée.
└wordCount
integer
└warnings
array<ArticleWarning>
Les formules qui sonnent comme écrites par une IA. Le brouillon reste utilisable : elles sont signalées plutôt que réécrites en silence. Consignez-les dans vos logs. Dans un pipeline automatisé, c’est le seul moment où quelqu’un pourrait s’en apercevoir.
Transformer le plan en brouillon prêt à publier (consomme des crédits)
L’appel le plus cher du produit. Synchrone : peut prendre une à deux minutes.
Un plan doit exister au préalable : sans plan, vous obtenez failure: "no_outline". C’est le plan qui porte les éléments factuels (les vraies requêtes derrière le cluster, les pages que l’IA cite aujourd’hui, le dédoublonnage avec vos pages existantes). S’en passer ramènerait cet appel à un simple outil de rédaction par IA, sans rien derrière.
article.markdown est le corps à publier. article.jsonLd contient les données structurées, déjà remplies avec le contenu de cet article. **article.warnings doit être consigné dans vos logs, pas ignoré** : chaque avertissement pointe une formule précise qui sonne comme écrite par une IA, et dans un pipeline automatisé, personne ne relit le brouillon avant sa mise en ligne.
Les brouillons qui échouent à la validation structurelle (sections manquantes, questions obligatoires sans réponse, liens inventés, JSON-LD invalide) sont écartés et ne sont pas facturés.
Corps de la requête
Champ
Type
Description
keyobligatoire
string
L’identifiant du cluster, issu de GET /v1/topics.
siteId
string
Par défaut, le premier site connecté.
confirmSpendobligatoire
integer
Un plafond d’autorisation en crédits, et non un montant exact. Envoyez une valeur supérieure ou égale au prix actuel indiqué par GET /v1/usage ; seul le coût réel est débité, souvent zéro lorsque le résultat est en cache. Si le prix dépasse un jour votre plafond, l’appel est refusé au lieu de débiter davantage en silence. Obligatoire même s’il vous reste des générations gratuites : elles finiront par s’épuiser, et ce ne doit pas être à ce moment-là que votre script découvre que cet endpoint est payant. (min 0)
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
ArticleOutcome
└ok
boolean
└failure
enum
Présent uniquement lorsque ok vaut false. Le statut HTTP reste 200.Valeurs : topic_not_foundno_outlineengine_unavailableengine_failedno_valid_article
└articlepeut être null
Article
└title
string
└description
string
Méta-description.
└markdown
string
Le corps à publier.
└jsonLd
string
Les données structurées de cet article, déjà remplies. JSON valide : placez-le dans une balise script de type application/ld+json sur la page publiée.
└wordCount
integer
└warnings
array<ArticleWarning>
Les formules qui sonnent comme écrites par une IA. Le brouillon reste utilisable : elles sont signalées plutôt que réécrites en silence. Consignez-les dans vos logs. Dans un pipeline automatisé, c’est le seul moment où quelqu’un pourrait s’en apercevoir.
Vaut false lorsqu’un résultat en cache a été renvoyé : rien n’a été débité.
└creditsSpent
integer
└freeUsed
boolean
└rejected
array<string>
Défauts structurels qui ont fait écarter le brouillon (sans facturation) : missing_sections, missing_faq, invented_link, invalid_json_ld, comparison_without_contrast, body_too_short.
Erreurs possibles
400key_required, confirm_spend_required ou confirm_spend_too_low (le corps contient le price actuel)
401Authentification refusée
402insufficient_credits — le corps contient requiredCredits, currentBalance, shortfall
403missing_scope_spend — cette clé ne dispose pas du droit spend
429rate_limited ou daily_limit_reached (le corps contient resetAt)
À entrées identiques, le plan en cache est renvoyé sans nouveau débit : l’empreinte couvre le cluster et son statut vis-à-vis de vos concurrents, vous pouvez donc relancer sans risque une requête HTTP qui a échoué.
Les résultats métier (moteur indisponible, sortie refusée à la validation) renvoient HTTP 200 avec ok: false et un code failure. Un solde de crédits insuffisant, lui, renvoie une vraie erreur 402.
Corps de la requête
Champ
Type
Description
keyobligatoire
string
L’identifiant du cluster, issu de GET /v1/topics.
siteId
string
Par défaut, le premier site connecté.
confirmSpendobligatoire
integer
Un plafond d’autorisation en crédits, et non un montant exact. Envoyez une valeur supérieure ou égale au prix actuel indiqué par GET /v1/usage ; seul le coût réel est débité, souvent zéro lorsque le résultat est en cache. Si le prix dépasse un jour votre plafond, l’appel est refusé au lieu de débiter davantage en silence. Obligatoire même s’il vous reste des générations gratuites : elles finiront par s’épuiser, et ce ne doit pas être à ce moment-là que votre script découvre que cet endpoint est payant. (min 0)
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
OutlineOutcome
└ok
boolean
└failure
enum
Présent uniquement lorsque ok vaut false. Le statut HTTP reste 200 : c’est un résultat, pas une erreur.Valeurs : topic_not_foundengine_unavailableengine_failedno_valid_outline
└outlinepeut être null
Outline
└title
string
└slug
string
└angle
string
La thèse que cette page doit défendre.
└sections
array<object>
└heading
string
└points
array<string>
└faq
array<object>
Les questions auxquelles la page doit répondre. Ce sont les passages que reprennent les réponses des IA.
└question
string
└answer
string
└schemaType
string
Le type JSON-LD adapté à cette page.
└internalLinks
array<string>
Les pages de votre propre site vers lesquelles un lien est pertinent. Choisies parmi de vraies URL, jamais inventées.
└generated
boolean
Vaut false lorsqu’un résultat en cache a été renvoyé : rien n’a été débité.
└creditsSpent
integer
└freeUsed
boolean
└rejected
array<string>
Règles de validation enfreintes par la sortie du modèle. Utile à consigner comme signal de qualité.
Erreurs possibles
400key_required, confirm_spend_required ou confirm_spend_too_low (le corps contient le price actuel)
401Authentification refusée
402insufficient_credits — le corps contient requiredCredits, currentBalance, shortfall
403missing_scope_spend — cette clé ne dispose pas du droit spend
429rate_limited ou daily_limit_reached (le corps contient resetAt)
Cet appel boucle la boucle : il marque le sujet comme publié, enregistre l’URL et la soumet à IndexNow en votre nom.
IndexNow couvre Bing, Yandex, Seznam et Naver — pas Google. Google n’a pas d’endpoint d’indexation instantanée équivalent ; il découvre la page via votre sitemap.
La soumission IndexNow ne fait jamais échouer l’appel : votre article est déjà publié, et c’est ce fait que l’appel enregistre. Consultez le champ indexnow pour savoir ce qui s’est réellement passé. La soumission exige que le fichier de clé IndexNow soit vérifié pour le site (à configurer une fois dans le tableau de bord).
Enregistrer l’URL permet aussi à QueryWin de mesurer à nouveau les requêtes visées par cet article, une fois qu’il a eu le temps de faire effet.
Corps de la requête
Champ
Type
Description
keyobligatoire
string
siteId
string
urlobligatoire
string
L’URL où vous l’avez publié. http/https uniquement. La page n’est pas récupérée à ce stade.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
PublishedResult
└clusterKey
string
└status
enum
Valeurs : published
└publishedUrl
string
└publishedAt
string
└indexnow
object
Bing, Yandex, Seznam et Naver. Pas Google.
└pushed
boolean
└outcome
string
skipped signifie généralement que le fichier de clé n’est pas encore vérifié.
└engines
string
Erreurs possibles
400key_required, url_required ou invalid_url (http/https uniquement)
401Authentification refusée
403missing_scope_publish — cette clé ne dispose pas du droit publish
Les campagnes (hors archivées, sauf avec includeArchived=true), ainsi que les limites de diffusion de l’offre et leur consommation actuelle. Gratuit.
Paramètres de requête
Champ
Type
Description
productId
string
Uniquement les campagnes de ce produit.
includeArchived
boolean
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
CampaignList
└campaigns
array<Campaign>
└campaignId
string
└productId
string
└name
string
└status
enum
completed est calculé : toutes les tâches sont publiées, vérifiées, en échec ou ignorées.Valeurs : activecompletedarchived
└quota
integer
Nombre de canaux retenus à la création de la campagne.
└startsAt
string
└endsAtpeut être null
string
└counts
object
└total
integer
└submitted
integer
submitted + published + verified.
└live
integer
published + verified.
└blocked
integer
└done
integer
└byStatus
object
└createdAt
string
└quota
DistributionQuota
Les limites de diffusion de l’offre et leur consommation actuelle. Une limite à null signifie qu’il n’y a pas de limite.
└plan
string
└limits
object
└channelspeut être null
integer
Nombre de canaux distincts sur lesquels un produit peut avoir des tâches, compté sur la période channelsPeriod.
└channelsPeriod
enum
month (offres payantes) : décompte par mois calendaire (UTC), chaque mois permet donc un nouveau lot de canaux. total (offre gratuite) : décompte sur toute la durée de vie du produit.Valeurs : monthtotal
└tasksPerMonthpeut être null
integer
Nombre de tâches pouvant être créées par mois calendaire (UTC), tous produits confondus.
└activeCampaignspeut être null
integer
Nombre de campagnes pouvant être actives simultanément.
Créer une campagne à partir d’une liste explicite de canaux
Une tâche par identifiant de canal, avec ses contenus de soumission préparés immédiatement à partir de la fiche produit, sans frais. Transmettez les canaux réellement choisis : une campagne enregistre où vous avez décidé de soumettre, ce n’est pas un filtre que le serveur se charge d’étendre.
Les canaux sur lesquels le produit a déjà une tâche en cours ou soumise sont ignorés et listés dans skipped, avec un motif (already_open, already_submitted, not_found, broken, inactive, other_product, locked). S’il ne reste rien, l’appel renvoie HTTP 200 avec ok: false et failure: "no_valid_targets". Dépasser le quota de diffusion de l’offre entraîne un refus : **409 quota_exceeded**, avec dimension, limit, used et requested. Rien n’est créé, pas même la partie qui aurait tenu dans le quota.
Corps de la requête
Champ
Type
Description
productIdobligatoire
string
nameobligatoire
string
targetIdsobligatoire
array<string>
Identifiants de canaux issus de GET /v1/channels. Uniquement les canaux choisis.
endsAt
string
Échéance facultative, affichée dans le tableau de bord. Rien n’est clôturé automatiquement.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
CreateCampaignOutcome
└ok
boolean
└failure
enum
Présent lorsque ok vaut false.Valeurs : no_valid_targets
└campaign
Campaign
└campaignId
string
└productId
string
└name
string
└status
enum
completed est calculé : toutes les tâches sont publiées, vérifiées, en échec ou ignorées.Valeurs : activecompletedarchived
└quota
integer
Nombre de canaux retenus à la création de la campagne.
└startsAt
string
└endsAtpeut être null
string
└counts
object
└total
integer
└submitted
integer
submitted + published + verified.
└live
integer
published + verified.
└blocked
integer
└done
integer
└byStatus
object
└createdAt
string
└tasks
array<Task>
└taskId
string
└campaignId
string
└productId
string
└status
enum
published correspond à ce que vous avez déclaré. verified correspond à ce que QueryWin a constaté sur la page de la fiche (un lien pour les annuaires et les annuaires d’outils IA, une mention ailleurs). Distinguez-les lorsque vous en rendez compte.Valeurs : plannedpreparedin_progressblockedsubmittedpublishedverifiedfailedskipped
Contenus obligatoires absents de la fiche. Complétez la fiche dans le tableau de bord : la tâche se prépare à nouveau d’elle-même.
└listingUrlpeut être null
string
└markedBy
enum
Auteur du dernier changement de statut : une personne (ou cette API), l’extension de navigateur ou QueryWin lui-même.Valeurs : userdevicesystem
└hasGenerated
boolean
Une version réécrite pour ce canal existe.
└reviewDueAtpeut être null
string
Date à laquelle revenir vérifier après la soumission (submittedAt + délai de validation du canal).
└submittedAtpeut être null
string
└publishedAtpeut être null
string
└verifiedAtpeut être null
string
└next
array<string>
Statuts que vous pouvez définir depuis le statut actuel via POST /v1/tasks/{id}/status.
└target
object
└targetId
string
└name
string
└url
string
└submitUrl
string
└kind
string
└source
enum
Valeurs : seeduserrivals
└language
string
└requiresBacklink
boolean
└checkpeut être null
object
La vérification que QueryWin effectue sur la fiche après sa mise en ligne. Vaut null tant que la tâche n’est pas publiée.
└kind
enum
Ce qui est recherché : un lien vers le produit (annuaires, annuaires d’outils IA) ou une mention de la marque (tous les autres types).Valeurs : link_livemention_seen
└statepeut être null
enum
confirmed = constaté. unconfirmed = introuvable lors d’une série de vérifications (statut inchangé ; vérifiez l’URL). lost = présent auparavant, disparu depuis (tâche passée en échec).Valeurs : confirmedunconfirmedlostnull
└checkedAtpeut être null
string
└dueAtpeut être null
string
└updatedAt
string
└skipped
array<object>
└targetId
string
└reason
enum
other_product = un site candidat cité par l’IA qui appartient à un autre produit ; inactive = un canal désactivé ou ignoré ; locked = hors de la fenêtre de la bibliothèque de canaux de l’offre gratuite (les window premiers canaux par pertinence, tels que renvoyés par GET /v1/channels ; vos propres canaux, vos favoris et les sites cités par l’IA ne sont pas limités).Valeurs : not_foundbrokeninactiveother_productalready_openalready_submittedlocked
403missing_scope_publish — cette clé ne dispose pas du droit publish
404product_not_found — ce productId n’appartient pas à ce compte
409quota_exceeded — le corps contient dimension (active_campaigns / tasks_per_month / channels), limit, used, requested ; pour channels, également period (month / total, comme DistributionQuota.limits.channelsPeriod)
completed est calculé : toutes les tâches sont publiées, vérifiées, en échec ou ignorées.Valeurs : activecompletedarchived
└quota
integer
Nombre de canaux retenus à la création de la campagne.
└startsAt
string
└endsAtpeut être null
string
└counts
object
└total
integer
└submitted
integer
submitted + published + verified.
└live
integer
published + verified.
└blocked
integer
└done
integer
└byStatus
object
└createdAt
string
└tasks
array<Task>
└taskId
string
└campaignId
string
└productId
string
└status
enum
published correspond à ce que vous avez déclaré. verified correspond à ce que QueryWin a constaté sur la page de la fiche (un lien pour les annuaires et les annuaires d’outils IA, une mention ailleurs). Distinguez-les lorsque vous en rendez compte.Valeurs : plannedpreparedin_progressblockedsubmittedpublishedverifiedfailedskipped
Contenus obligatoires absents de la fiche. Complétez la fiche dans le tableau de bord : la tâche se prépare à nouveau d’elle-même.
└listingUrlpeut être null
string
└markedBy
enum
Auteur du dernier changement de statut : une personne (ou cette API), l’extension de navigateur ou QueryWin lui-même.Valeurs : userdevicesystem
└hasGenerated
boolean
Une version réécrite pour ce canal existe.
└reviewDueAtpeut être null
string
Date à laquelle revenir vérifier après la soumission (submittedAt + délai de validation du canal).
└submittedAtpeut être null
string
└publishedAtpeut être null
string
└verifiedAtpeut être null
string
└next
array<string>
Statuts que vous pouvez définir depuis le statut actuel via POST /v1/tasks/{id}/status.
└target
object
└targetId
string
└name
string
└url
string
└submitUrl
string
└kind
string
└source
enum
Valeurs : seeduserrivals
└language
string
└requiresBacklink
boolean
└checkpeut être null
object
La vérification que QueryWin effectue sur la fiche après sa mise en ligne. Vaut null tant que la tâche n’est pas publiée.
└kind
enum
Ce qui est recherché : un lien vers le produit (annuaires, annuaires d’outils IA) ou une mention de la marque (tous les autres types).Valeurs : link_livemention_seen
└statepeut être null
enum
confirmed = constaté. unconfirmed = introuvable lors d’une série de vérifications (statut inchangé ; vérifiez l’URL). lost = présent auparavant, disparu depuis (tâche passée en échec).Valeurs : confirmedunconfirmedlostnull
La bibliothèque de canaux (annuaires, plateformes de lancement, annuaires d’outils IA, communautés, plateformes de publication), les canaux que vous avez ajoutés et, si productId est fourni, les sites que les réponses des IA citent déjà sur les requêtes de ce produit (source: "rivals"). Avec productId, la liste est triée par pertinence et chaque canal porte taskStatus (non nul lorsque le produit a déjà une tâche sur ce canal). Gratuit.
**citedByAi signifie que des réponses d’IA ont cité ce site sur vos requêtes. Cela ne signifie pas que ce site référencera votre produit** : c’est justement pour le lui demander que la tâche existe.
Paramètres de requête
Champ
Type
Description
productId
string
Trie par pertinence pour ce produit, ajoute taskStatus et inclut ses sites candidats cités par l’IA.
kind
string
Type de canal.Valeurs : directorylaunchai_directorycommunitycontentother
source
string
seed = la bibliothèque, user = ajouté par vous, rivals = sites cités par l’IA pour ce produit.Valeurs : seeduserrivals
pricing
string
Coût de la soumission.Valeurs : freeconditionalpaidunknown
submitMethod
string
Mode de soumission : remplir un formulaire, publier dans une communauté ou envoyer un pitch par e-mail.Valeurs : formpostemail
q
string
Recherche dans le nom, le domaine et les thématiques.
hideSubmitted
boolean
Exclut les canaux sur lesquels ce produit a déjà une tâche en cours ou soumise. Nécessite productId.
page
integer
Par défaut : 1.
pageSize
integer
Par défaut : 30.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
ChannelList
└productIdpeut être null
string
└items
array<Channel>
└targetId
string
À transmettre dans targetIds à POST /v1/campaigns.
└name
string
└url
string
└submitUrl
string
Le formulaire de soumission ou la page de publication ; pour les sites cités par l’IA, la page la plus citée par les réponses des IA.
form = remplir son formulaire de soumission, post = publier vous-même dans la communauté, email = envoyer un pitch aux rédacteurs par e-mail (l’adresse est lue sur la page au moment où vous l’ouvrez ; elle n’est pas stockée).Valeurs : formpostemail
└source
enum
seed = la bibliothèque, user = ajouté par vous, rivals = un site que les réponses des IA citent sur les requêtes de ce produit.Valeurs : seeduserrivals
└pricingType
enum
Valeurs : freeconditionalpaidunknown
└priceNotepeut être null
string
└language
string
en, zh, multi ou, pour les sites cités par l’IA, un code de langue déduit des requêtes.
└topics
array<string>
└requiresAccount
boolean
└requiresBacklink
boolean
└reviewDayspeut être null
integer
Délai de validation habituel. La tâche vous rappelle de revenir vérifier une fois ce délai écoulé.
└siteRankpeut être null
integer
Rang mondial dans la liste publique Tranco (plus il est bas, plus le site est visité). null = hors du premier million. Ce n’est pas le Domain Rating.
└hasFormSpec
boolean
Les champs du formulaire de ce canal sont répertoriés : les contenus sont donc tronqués à ses limites exactes.
└relevancepeut être null
integer
Score de pertinence pour le produit indiqué dans l’appel. Sert uniquement au tri.
└taskStatuspeut être null
string
La tâche en cours ou terminée du produit sur ce canal, s’il y en a une. null = aucune pour l’instant.
└citedByAipeut être null
object
Uniquement pour source: "rivals". Des réponses d’IA ont cité ce site sur les requêtes listées. Ce n’est pas une promesse que ce site référencera votre produit : c’est justement pour le lui demander que la tâche existe.
└queries
integer
Nombre de requêtes distinctes sur lesquelles il a été cité.
└samples
integer
Nombre d’échantillons de réponses d’IA qui l’ont cité.
└searches
array<string>
└pages
array<string>
Les pages citées, les plus citées en premier. Vide pour les échantillons plus anciens, qui n’enregistraient que le domaine.
└total
integer
└page
integer
└pageSize
integer
└limited
boolean
Offre gratuite : seuls les window premiers canaux dans l’ordre par défaut (pertinence pour productId) sont renvoyés, et les paramètres de filtre, de recherche et de tri sont refusés avec 403 library_locked. total reste la taille réelle de la bibliothèque.
└windowpeut être null
integer
Taille de la fenêtre de l’offre gratuite : 20 canaux, plus 20 par personne inscrite avec votre lien de parrainage (et 20 de plus si votre propre inscription est passée par un tel lien). null lorsque la liste n’est pas limitée.
Point de départ du pipeline de diffusion : tous les autres endpoints de diffusion prennent un productId. completeness et missing proviennent de la fiche produit enregistrée : un champ vide dans la fiche est un champ vide dans chaque soumission, et un champ obligatoire manquant bloque la tâche en blocked / missing_material jusqu’à ce que la fiche soit complétée. Lisez-la avec GET /v1/products/{id} et remplissez-la avec PATCH /v1/products/{id}. Gratuit.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
ProductList
└products
array<Product>
└productId
string
└name
string
└url
string
└domain
string
└primaryLanguage
enum
Valeurs : enzhjakodefresptitrunlpltrarthviid
└topics
array<string>
└completeness
integer
Complétude de la fiche, de 0 à 100. Complétez les champs manquants dans le tableau de bord ou avec PATCH /v1/products/{id}.
└missing
array<string>
Champs vides de la fiche. Chacun se retrouve vide dans toutes les soumissions.
Nécessite le droit publish et une offre payante. Crée un produit à partir de l’URL publique de sa page d’accueil et d’un nom facultatif ; occupe une place de votre quota de produits, sans débiter de crédits. Renvoie la fiche complète enregistrée, à remplir ensuite avec PATCH /v1/products/{id}. N’explore pas le site et ne fait appel à aucune IA. Un domaine déjà enregistré renvoie 409 product_exists avec le productId existant ; réutilisez-le si la réponse s’est perdue. Les valeurs par défaut du produit sont modifiables : ce ne sont pas des faits vérifiés sur le site.
Corps de la requête
Champ
Type
Description
urlobligatoire
string
name
string
Réponse201
Champ
Type
Description
success
boolean
data
ProductDetail
└name
string
└url
string
└primaryLanguage
enum
Valeurs : enzhjakodefresptitrunlpltrarthviid
└businessType
enum
Valeurs : saastoolecommercecontentserviceother
└launchStatus
enum
Valeurs : livebeta
└pricingModel
enum
Valeurs : freefreemiumpaidtrial
└taglinepeut être null
object
└shortDescpeut être null
object
└longDescpeut être null
object
└firstCommentpeut être null
object
└topics
array<string>
└promoCodepeut être null
string
└videoUrlpeut être null
string
└demoUrlpeut être null
string
└linkspeut être null
object
└webApp
string
└appStore
string
└playStore
string
└chromeExtension
string
└macos
string
└windows
string
└socialspeut être null
object
└x
string
└linkedin
string
└github
string
└instagram
string
└youtube
string
└facebook
string
└contactNamepeut être null
string
└contactEmailpeut être null
string
└gallery
array<string>
└productId
string
└domain
string
└thumbnailUrlpeut être null
string
└completeness
integer
(0–100)
└missing
array<string>
└createdAt
string
└updatedAt
string
└sites
array<object>
└siteId
string
└domain
string
└syncedThroughpeut être null
string
Erreurs possibles
400invalid_product_input, invalid_url ou url_not_public
401Authentification refusée
403plan_required, ou missing_scope_publish pour les opérations d’écriture
409product_exists (avec le productId existant) ou product_limit_reached
429rate_limited — 120 requêtes par minute et par clé
Nécessite le droit publish. Enregistre immédiatement les seuls champs envoyés ; les objets (textes localisés compris) et les tableaux remplacent le champ entier. Lisez d’abord la fiche pour conserver les autres langues. Aucun crédit débité, aucune génération par IA. Les contenus de soumission en attente sont actualisés de manière asynchrone. N’utilisez que des faits connus : n’inventez pas les informations produit manquantes.
Corps de la requête
Champ
Type
Description
name
string
url
string
primaryLanguage
enum
Valeurs : enzhjakodefresptitrunlpltrarthviid
businessType
enum
Valeurs : saastoolecommercecontentserviceother
launchStatus
enum
Valeurs : livebeta
pricingModel
enum
Valeurs : freefreemiumpaidtrial
tagline
object
shortDesc
object
longDesc
object
firstComment
object
topics
array<string>
promoCode
string
videoUrl
string
demoUrl
string
links
object
└webApp
string
└appStore
string
└playStore
string
└chromeExtension
string
└macos
string
└windows
string
socials
object
└x
string
└linkedin
string
└github
string
└instagram
string
└youtube
string
└facebook
string
contactName
string
contactEmail
string
gallery
array<string>
Réponse200
Champ
Type
Description
success
boolean
data
ProductDetail
└name
string
└url
string
└primaryLanguage
enum
Valeurs : enzhjakodefresptitrunlpltrarthviid
└businessType
enum
Valeurs : saastoolecommercecontentserviceother
└launchStatus
enum
Valeurs : livebeta
└pricingModel
enum
Valeurs : freefreemiumpaidtrial
└taglinepeut être null
object
└shortDescpeut être null
object
└longDescpeut être null
object
└firstCommentpeut être null
object
└topics
array<string>
└promoCodepeut être null
string
└videoUrlpeut être null
string
└demoUrlpeut être null
string
└linkspeut être null
object
└webApp
string
└appStore
string
└playStore
string
└chromeExtension
string
└macos
string
└windows
string
└socialspeut être null
object
└x
string
└linkedin
string
└github
string
└instagram
string
└youtube
string
└facebook
string
└contactNamepeut être null
string
└contactEmailpeut être null
string
└gallery
array<string>
└productId
string
└domain
string
└thumbnailUrlpeut être null
string
└completeness
integer
(0–100)
└missing
array<string>
└createdAt
string
└updatedAt
string
└sites
array<object>
└siteId
string
└domain
string
└syncedThroughpeut être null
string
Erreurs possibles
400invalid_product_input, invalid_url, url_not_public, invalid_email ou invalid_gallery
401Authentification refusée
403plan_required, ou missing_scope_publish pour les opérations d’écriture
404product_not_found
409product_exists (avec le productId existant)
429rate_limited — 120 requêtes par minute et par clé
Renvoie les textes localisés enregistrés, les liens, les coordonnées, les images, la complétude et les champs manquants. Droit read ; aucun crédit débité. Un produit qui n’appartient pas à cet espace de travail renvoie lui aussi product_not_found.
Réponse200
Champ
Type
Description
success
boolean
data
ProductDetail
└name
string
└url
string
└primaryLanguage
enum
Valeurs : enzhjakodefresptitrunlpltrarthviid
└businessType
enum
Valeurs : saastoolecommercecontentserviceother
└launchStatus
enum
Valeurs : livebeta
└pricingModel
enum
Valeurs : freefreemiumpaidtrial
└taglinepeut être null
object
└shortDescpeut être null
object
└longDescpeut être null
object
└firstCommentpeut être null
object
└topics
array<string>
└promoCodepeut être null
string
└videoUrlpeut être null
string
└demoUrlpeut être null
string
└linkspeut être null
object
└webApp
string
└appStore
string
└playStore
string
└chromeExtension
string
└macos
string
└windows
string
└socialspeut être null
object
└x
string
└linkedin
string
└github
string
└instagram
string
└youtube
string
└facebook
string
└contactNamepeut être null
string
└contactEmailpeut être null
string
└gallery
array<string>
└productId
string
└domain
string
└thumbnailUrlpeut être null
string
└completeness
integer
(0–100)
└missing
array<string>
└createdAt
string
└updatedAt
string
└sites
array<object>
└siteId
string
└domain
string
└syncedThroughpeut être null
string
Erreurs possibles
401Authentification refusée
403plan_required, ou missing_scope_publish pour les opérations d’écriture
404product_not_found
429rate_limited — 120 requêtes par minute et par clé
Nécessite le droit publish. Récupère une image publique en HTTP(S) et en stocke une copie comme miniature (elle remplace l’actuelle) ou dans la galerie (ajoutée à la suite, six au maximum). JPEG, PNG, WebP et SVG, 4 Mo au maximum ; les SVG sont convertis en PNG. Les réseaux privés et les redirections non sûres sont bloqués par le module de récupération d’images existant. Aucun crédit débité. Des imports répétés dans la galerie peuvent créer des doublons : si la réponse s’est perdue, relisez le produit avec GET avant de réessayer.
Corps de la requête
Champ
Type
Description
urlobligatoire
string
kind
enum
Valeurs : thumbnailgalleryPar défaut gallery
Réponse200
Champ
Type
Description
success
boolean
data
ProductDetail
└name
string
└url
string
└primaryLanguage
enum
Valeurs : enzhjakodefresptitrunlpltrarthviid
└businessType
enum
Valeurs : saastoolecommercecontentserviceother
└launchStatus
enum
Valeurs : livebeta
└pricingModel
enum
Valeurs : freefreemiumpaidtrial
└taglinepeut être null
object
└shortDescpeut être null
object
└longDescpeut être null
object
└firstCommentpeut être null
object
└topics
array<string>
└promoCodepeut être null
string
└videoUrlpeut être null
string
└demoUrlpeut être null
string
└linkspeut être null
object
└webApp
string
└appStore
string
└playStore
string
└chromeExtension
string
└macos
string
└windows
string
└socialspeut être null
object
└x
string
└linkedin
string
└github
string
└instagram
string
└youtube
string
└facebook
string
└contactNamepeut être null
string
└contactEmailpeut être null
string
└gallery
array<string>
└productId
string
└domain
string
└thumbnailUrlpeut être null
string
└completeness
integer
(0–100)
└missing
array<string>
└createdAt
string
└updatedAt
string
└sites
array<object>
└siteId
string
└domain
string
└syncedThroughpeut être null
string
Erreurs possibles
400invalid_product_input ou invalid_url
401Authentification refusée
403plan_required, ou missing_scope_publish pour les opérations d’écriture
404product_not_found
409gallery_full
413image_too_large
415image_type
429rate_limited — 120 requêtes par minute et par clé
L’historique des soumissions, activité la plus récente en premier. Filtrez par produit, par campagne ou par une liste de statuts séparés par des virgules. byStatus compte toutes les tâches du périmètre avant application du filtre de statut. Gratuit.
Paramètres de requête
Champ
Type
Description
productId
string
Uniquement les tâches de ce produit.
campaignId
string
status
string
Séparés par des virgules, par ex. prepared,in_progress.
page
integer
Par défaut : 1.
pageSize
integer
Par défaut : 30.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
TaskList
└items
array<Task>
└taskId
string
└campaignId
string
└productId
string
└status
enum
published correspond à ce que vous avez déclaré. verified correspond à ce que QueryWin a constaté sur la page de la fiche (un lien pour les annuaires et les annuaires d’outils IA, une mention ailleurs). Distinguez-les lorsque vous en rendez compte.Valeurs : plannedpreparedin_progressblockedsubmittedpublishedverifiedfailedskipped
Contenus obligatoires absents de la fiche. Complétez la fiche dans le tableau de bord : la tâche se prépare à nouveau d’elle-même.
└listingUrlpeut être null
string
└markedBy
enum
Auteur du dernier changement de statut : une personne (ou cette API), l’extension de navigateur ou QueryWin lui-même.Valeurs : userdevicesystem
└hasGenerated
boolean
Une version réécrite pour ce canal existe.
└reviewDueAtpeut être null
string
Date à laquelle revenir vérifier après la soumission (submittedAt + délai de validation du canal).
└submittedAtpeut être null
string
└publishedAtpeut être null
string
└verifiedAtpeut être null
string
└next
array<string>
Statuts que vous pouvez définir depuis le statut actuel via POST /v1/tasks/{id}/status.
└target
object
└targetId
string
└name
string
└url
string
└submitUrl
string
└kind
string
└source
enum
Valeurs : seeduserrivals
└language
string
└requiresBacklink
boolean
└checkpeut être null
object
La vérification que QueryWin effectue sur la fiche après sa mise en ligne. Vaut null tant que la tâche n’est pas publiée.
└kind
enum
Ce qui est recherché : un lien vers le produit (annuaires, annuaires d’outils IA) ou une mention de la marque (tous les autres types).Valeurs : link_livemention_seen
└statepeut être null
enum
confirmed = constaté. unconfirmed = introuvable lors d’une série de vérifications (statut inchangé ; vérifiez l’URL). lost = présent auparavant, disparu depuis (tâche passée en échec).Valeurs : confirmedunconfirmedlostnull
Chaque champ demandé par le formulaire du canal, tiré de la fiche produit et tronqué aux limites du canal (source: "profile"), plus la version réécrite pour ce canal s’il en existe une (source: "ai") et les modifications faites dans le tableau de bord (source: "override"). source: "none" signifie que la fiche ne contient rien pour ce champ : ne l’inventez pas. Ne déclenche jamais de réécriture et ne coûte jamais rien.
Réécrire les contenus pour ce canal (consomme des crédits)
Un passage par l’IA qui adapte la fiche à ce canal précis : une description d’annuaire plus resserrée, le premier commentaire du créateur, une publication pour une communauté, un pitch pour un rédacteur ou, pour les sites cités par l’IA, un pitch accompagné d’un paragraphe que le responsable de la page pourrait ajouter. Synchrone, quelques secondes. N’utilise que les faits présents dans la fiche ; toute partie contenant un lien absent de la fiche est écartée et non facturée.
À entrées identiques, la version précédente est renvoyée sans débit (cached: true) ; force: true réécrit malgré tout et est facturé. Les contenus tirés de la fiche par GET /v1/tasks/{id} suffisent généralement pour les annuaires ; réécrivez lorsque le canal attend un autre ton.
Renvoie HTTP 200 avec ok: false et failure: "engine_failed" lorsque rien n’a passé la validation. Un solde de crédits insuffisant, lui, renvoie une vraie erreur 402.
Corps de la requête
Champ
Type
Description
confirmSpendobligatoire
integer
Plafond d’autorisation en crédits, même sémantique que pour les plans et les brouillons. Lisez le prix dans GET /v1/usage (materials.pricePerTask). Obligatoire même s’il vous reste des générations gratuites. (min 0)
force
boolean
Réécrit même si rien n’a changé depuis la dernière version. Facturé.
Réponse200
Champ
Type
Description
success
enum
Valeurs : true
data
WriteMaterialsOutcome
└ok
boolean
└failure
enum
Présent lorsque ok vaut false. Rien n’est débité.Valeurs : engine_failedengine_unavailable
└cached
boolean
Entrées inchangées : la version précédente a été renvoyée et rien n’a été débité.
└freeUsed
boolean
└creditsSpent
integer
└task
TaskDetail
Erreurs possibles
400confirm_spend_required ou confirm_spend_too_low (le corps contient le price actuel)
401Authentification refusée
402insufficient_credits — le corps contient requiredCredits, currentBalance, shortfall
403missing_scope_spend — cette clé ne dispose pas du droit spend
404task_not_found
429rate_limited ou daily_limit_reached (le corps contient resetAt)
Enregistrez l’issue d’une soumission que vous avez effectuée avec vos propres comptes. QueryWin ne soumet jamais rien de lui-même. Passez à submitted une fois le formulaire envoyé, puis à published avec l’URL de la fiche (la fiche ou la publication elle-même, pas la page d’accueil du site) une fois en ligne ; environ 72 heures plus tard, QueryWin revérifie cette page à la recherche d’un lien vers votre produit (annuaires, annuaires d’outils IA) ou d’une mention (tous les autres types), et passe lui-même la tâche en verified — vous ne pouvez pas définir ce statut.
blocked signifie « intervention humaine requise » : transmettez reason (login, captcha, payment, missing_material, other). failed / skipped clôturent la tâche ; prepared la remet en attente. Les transitions que la machine à états n’autorise pas renvoient **409 transition_not_allowed** ; le champ next de la tâche liste les statuts autorisés depuis le statut actuel.
Corps de la requête
Champ
Type
Description
statusobligatoire
enum
verified ne peut pas être défini : QueryWin l’attribue après avoir revérifié la fiche.Valeurs : preparedin_progressblockedsubmittedpublishedfailedskipped
listingUrl
string
Obligatoire pour published : la fiche ou la publication en ligne, pas la page d’accueil du site. http/https uniquement. Facultatif avec submitted si vous la connaissez déjà.
note
string
reason
enum
Obligatoire pour blocked.Valeurs : logincaptchapaymentmissing_materialother