AD, techniquement : comment ça marche et comment l'intégrer
Tout ce qu'une campagne exige fonctionne : comptes, campagnes, créations, zones, le moteur de diffusion, le panneau et les rapports. Cette page est générée à partir du code même qui diffuse les annonces — chaque limite, macro, événement et route ci-dessous est lu dans la source à chaque build, jamais saisi à la main.
Ce qu'est AD, et pour qui
AD est un serveur publicitaire direct : pas d'enchère, pas de boîte noire. Un éditeur vend l'espace publicitaire d'un site qu'il exploite déjà ; un annonceur choisit les zones exactes, règle le ciblage et lance. Un même compte peut jouer l'un ou l'autre rôle — ou les deux.
Annonceurs
Créez une campagne, ajoutez des créations, passez la revue, achetez un emplacement sur une zone de la vitrine et voyez impressions et clics arriver dans les rapports.
Éditeurs
Déclarez un site, définissez des zones avec une taille, un modèle de vente et un prix, collez une balise et gardez 80% de chaque vente. Diffuser vos propres annonces sur vos propres zones est gratuit.
Les deux à la fois
Un compte annonceur devient éditeur dès qu'il déclare un site ; rien n'est dupliqué. Le panneau affiche les onglets de chaque rôle que vous tenez.
Comment entrer
Connectez-vous sur forhosting.com et choisissez « Gérer mon AD » dans le menu de votre compte. Le panneau s'ouvre avec une session courte — un identifiant qui expire en quelques minutes (jamais plus de 60) et ne laisse aucune clé permanente dans le navigateur. Quand elle expire, rouvrez-le depuis le même menu.
Pour vos intégrations, créez une clé d'API depuis le panneau (Profil) ou avec POST /tenants/:id/keys. Deux portées : tenant (accès complet à votre propre compte) et read (lecture seule, pour tableaux de bord et robots). La clé n'est affichée qu'une fois ; si elle est perdue, créez-en une autre et révoquez l'ancienne.
Notre équipe peut ouvrir votre panneau « en tant que client » pour vous aider : cette session dure au plus 15 minutes et porte le nom de la personne qui l'a ouverte. La maison n'opère jamais votre compte avec une clé permanente.
Campagnes et ciblage
La campagne est le conteneur : nom, dates, budgets facultatifs et le ciblage partagé par ses créations. Elle naît en draft ; vous la passez active, la mettez en pause ou la terminez. Seules les créations actives d'une campagne active sont diffusées — mettre la campagne en pause arrête la diffusion aussitôt.
| Critère | Fonctionnement |
|---|---|
| Pays, région, ville | Une liste de pays ; facultativement une région et une ville. La ville exige sa région ; la région exige son pays. Si la position du visiteur est inconnue et que la campagne demande du géo, l'annonce n'est pas diffusée — jamais diffusée par accident. |
| Langue du navigateur | Une liste de codes de langue (jusqu'à 30) annoncés par le navigateur du visiteur — qui n'est pas forcément celle du site. Un visiteur dont la langue n'est pas listée n'est pas servi : laissez donc une campagne sans langues, elle récupère tous les autres. |
| Appareil | any, mobile ou desktop. |
| Système d'exploitation | Une liste parmi : iPhone, iPad, iPod, Windows, Android, BlackBerry, Ubuntu, Linux, CrOs, Mac OS X. |
| Referrer | La page d'où vient le visiteur doit contenir le texte que vous fixez (insensible à la casse). |
| Dates | Début et fin de la campagne. Chaque création peut aussi porter ses propres dates ; la fenêtre effective est l'intersection des deux. |
| Plafond de fréquence | Par création : au plus N impressions par visiteur, comptées dans un cookie first-party qui vit 3 jours. |
| Limites dures | Par création : impressions totales, impressions par jour et clics totaux. Quand une limite est atteinte, la création cesse d'être diffusée en moins de 5 minutes. |
Parmi les créations éligibles, le moteur tire au hasard, pondéré par le poids que vous donnez à chacune. Une création avec une limite de diffusion est lissée (pacing) : toutes les 5 minutes son poids est réajusté pour que le budget s'étale sur les jours de la campagne au lieu de brûler dès le matin. Le pacing ne fait que freiner — il n'invente jamais de trafic.
Une création n'est diffusée que sur une zone où elle a une commande payée (voir « Acheter des emplacements »). Campagne, création, zone et commande sont visibles dans le panneau (Campagnes, Créations, Acheter des emplacements).
Créations : six types, une balise
Chaque création a une URL de clic, une taille fixe facultative et un poids. Les limites de ce tableau sont celles que l'API applique à l'envoi — elles sont lues dans le code, pas écrites ici.
| Type | Ce que vous envoyez | Limites |
|---|---|---|
image · image | Un fichier : PNG, JPEG, GIF, WebP, AVIF. | Jusqu'à 2 Mo et 2000×1800 px. Si la création déclare une taille fixe, le fichier doit mesurer exactement cela. |
text · lien texte | Un titre et un corps facultatif, sans fichier. | Rendu comme un lien dans le style propre de la zone. |
html5 · HTML5 | Un ZIP avec index.html à la racine (ou dans un unique dossier), ou un seul fichier HTML. | ZIP jusqu'à 10 Mo. Diffusé dans une iframe avec une politique de contenu stricte : aucune requête vers d'autres origines. |
video · vidéo | Un fichier : MP4, WebM. Affiche et bouton son facultatifs. | Jusqu'à 30 Mo. Lecture muette en autoplay dans notre lecteur ; début et fin sont suivis. |
vignette · interstitiel | Une image (mêmes règles que image) ou une vidéo. | Affiché en surimpression plein écran quand le visiteur clique sur un lien du déclencheur de la zone ; l'impression compte à l'ouverture de la surimpression. |
script · script | Votre propre HTML/JS avec les macros ci-dessous, plus jusqu'à 5 images. | Uniquement sur les zones qui acceptent le format script. C'est du code tiers qui s'exécute sur la page de l'éditeur : la revue manuelle est la seule barrière — elle n'est jamais sautée. |
Le contrat HTML5
Votre index.html est chargé dans une iframe avec la destination du clic dans la query sous clickTag. Lisez-la et utilisez-la comme href de votre zone cliquable — cette URL est signée et compte le clic ; un lien écrit à la main ne compte pas.
// index.html — the click goes where the engine says
var clickTag = new URLSearchParams(location.search).get("clickTag");
document.getElementById("ad").href = clickTag;
Si votre création doit grandir, indiquez à la page sa hauteur réelle par postMessage. La balise indique aussi à la création la largeur de l'emplacement au chargement et à chaque redimensionnement, et envoie visible la première fois que l'emplacement entre dans la fenêtre — le bon moment pour lancer une animation. Les hauteurs jusqu'à 10000 px sont appliquées.
// creative → page: ask for the real height (applied up to 10000 px)
parent.postMessage({ fh: "resize", nh: document.documentElement.scrollHeight }, "*");
// page → creative: { fh: "size" | "visible" }
window.addEventListener("message", function (ev) {
if (ev.data && ev.data.fh === "visible") { /* start your animation */ }
});
Une création minimale qui fait les deux, prête à envoyer telle quelle : téléchargez le ZIP d'exemple
Macros des créations script
Dans une création script, le moteur remplace ces marqueurs à la publication de la zone. Un modèle du panneau est la même chose avec des marqueurs supplémentaires que vous remplissez dans un formulaire.
| Macro | Remplacée par |
|---|---|
[CLICKTAG] · [TRACKLINK] | L'URL de clic signée — utilisez-la comme href. Sans elle, le clic n'est pas compté. |
[LINK] | L'URL de destination brute, pour du code qui en a besoin sans le traqueur. |
[TARGET] | _blank ou _self, selon la création. |
[ID] | L'identifiant de la création. |
[TITLE] · [TITOLO] | Le titre de la création (échappé en HTML). |
[IMG0] … [IMG4] | L'URL de chaque image envoyée, dans l'ordre. |
[TIMESTAMP] · [RANDOM] | Un horodatage et un nombre aléatoire, fixés à la publication de la zone — pour casser le cache de vos propres pixels. |
Suivi tiers et consentement
Toute création peut porter un code de suivi (un pixel ou un script d'un fournisseur de mesure). Il est émis après l'annonce avec chaque src transformé en data-src, de sorte que rien ne charge tant que la balise ne l'autorise pas.
Si vous indiquez l'identifiant IAB TCF v2 du fournisseur, le code ne charge qu'après le consentement du visiteur pour ce fournisseur, avec ${GDPR} et ${GDPR_CONSENT_n} renseignés. La balise attend jusqu'à 10 secondes le gestionnaire de consentement du site ; sans identifiant de fournisseur, le code charge comme un élément ordinaire.
Revue manuelle
Toute création naît en_revision et est revue par une personne avant de pouvoir diffuser. Approuvée, vous la passez active ou paused ; refusée, vous voyez le motif et pouvez la corriger et la soumettre de nouveau. Rien d'une création non revue — ni le balisage, ni le script, ni le code de suivi — n'atteint jamais un visiteur.
Changer l'URL de clic, le contenu ou le fichier d'une création approuvée la renvoie en revue : ce qui a été approuvé est ce qui est diffusé, jamais autre chose.
Acheter des emplacements
La vitrine liste chaque zone en vente : site, taille, formats acceptés, modèle de vente et le prix fixé par l'éditeur. Vous choisissez une zone, une création d'un format que la zone accepte, un budget et une date de début. Le devis et le débit utilisent la même formule :
| Modèle | Vous payez par | Vous obtenez |
|---|---|---|
cpm | millier d'impressions | impressions = budget × 1000 / prix |
cpc | clic | clics = budget / prix |
cpd | jour | jours = budget / prix |
La commande minimale est de $5 ; le devis refuse tout montant inférieur. Une commande est un achat prépayé de volume — l'argent ne bouge qu'une fois, à l'achat. Envoyez une idempotencyKey et une requête réessayée renvoie la même commande au lieu d'en créer une seconde.
Comment vous payez
| Voie | Fonctionnement |
|---|---|
| Solde du compte | La commande est payée dans le même appel depuis votre solde For Hosting. Si le solde est insuffisant, la commande reste en attente et la réponse renvoie vers recharger ; vous pouvez retenter le paiement plus tard. |
| Manuel | La commande est créée en attente ; notre équipe la marque payée après avoir reçu le paiement hors du panneau. Elle ne diffuse pas avant. |
| Annonces maison | Votre propre création sur votre propre zone : la commande naît payée à coût nul. Même enregistrement, pas d'argent. |
Quand une commande est marquée payée, 80% de son prix final est crédité à l'éditeur de la zone — sur la commande entière, sans prorata de diffusion. La zone est republiée immédiatement et votre création commence à diffuser dans la minute.
Sites, zones, balise et versements
Sites
Déclarez un site par son domaine (Devenir éditeur). Il naît en attente et une personne le vérifie avant que ses zones puissent vendre — un domaine non vérifié ne peut pas toucher de part. Retirer un site lance un refroidissement de 90 jours sur le domaine : personne d'autre ne peut le déclarer entre-temps et hériter de son historique.
Zones
La zone est l'emplacement vendable : un nom, une taille en pixels (ou -1 pour une largeur adaptative), les formats qu'elle accepte, un modèle de vente avec son prix, et si elle est en vente dans la vitrine. Vous pouvez fixer une création de repli à vous qui diffuse quand rien d'autre n'est éligible — elle ignore ciblage et plafonds.
Deux comportements facultatifs s'exécutent dans le navigateur du visiteur : le rafraîchissement automatique (une nouvelle requête toutes les N secondes, minimum 5 ; un onglet masqué ne rafraîchit jamais, et un emplacement qui revient vide garde l'annonce précédente) et le report des paramètres (la query de la page voyage avec le clic jusqu'à la destination de l'annonceur). Une zone interstitielle déclare aussi quels liens déclenchent la surimpression — par défaut p a, nav a, h2 a — et les secondes avant de pouvoir la fermer.
La balise
Collez-la là où l'annonce doit apparaître. L'identifiant de zone vient du panneau (Sites et zones). La même balise diffuse tous les formats que la zone accepte ; une zone interstitielle utilise aussi la balise standard.
Standard (un div et un script, asynchrone) :
<div data-fh-ad="zon_XXXXXXXXXXXXXXXXXXXXXXXX"></div>
<script src="https://api.ad.forhosting.com/ad-tag.js" async></script>
Legacy, pour les CMS qui n'exécutent pas de scripts asynchrones :
<script src="https://api.ad.forhosting.com/ad-serve?zone=zon_XXXXXXXXXXXXXXXXXXXXXXXX&mode=js"></script>
Lien texte : une URL qui compte l'impression et redirige vers l'annonceur :
https://api.ad.forhosting.com/ad-serve?zone=zon_XXXXXXXXXXXXXXXXXXXXXXXX&mode=link
La balise se met à jour toute seule : son URL ne porte pas de version et ne change jamais, donc une amélioration de notre côté atteint tous les sites en environ undefined minutes et personne ne modifie de gabarit (elle sert v6 aujourd'hui, dans l'en-tête x-tag-version). Elle attend que votre page finisse de charger avant de demander quoi que ce soit : les annonces ne concurrencent jamais votre contenu. Ses seules marques dans votre page sont l'attribut data-fh-ad et l'id de l'overlay — vérifiés contre les listes de blocage courantes, sans aucune correspondance. Les plafonds de fréquence utilisent un cookie propriétaire.
Versements
Votre part de 80% sur chaque commande payée s'accumule dans le panneau (Versements). Quand le cumul atteint $10, demandez le versement avec la méthode de votre profil (paypal, bank, other) ; notre équipe paie hors du panneau et enregistre la référence.
États : accrued → requested → processing → paid ; un versement échoué vous revient avec le motif pour que vous le redemandiez avec des coordonnées corrigées.
Rapports
Impressions, clics et début/fin de vidéo sont comptés en bordure, à chaque requête. Avant de compter, le trafic est filtré : robots connus par leur user agent, réseaux de centres de données, requêtes avec un score de bot très bas, et toute IP répétant la même requête en moins de 2 secondes. Une requête filtrée reçoit quand même son annonce ou sa redirection — seul le compteur est protégé.
Toutes les 5 minutes, les comptages sont consolidés en lignes journalières par création, zone et hôte du referrer. Le jour en cours peut avoir jusqu'à ce retard ; les jours clos ne changent jamais.
Le panneau (Rapports) montre les totaux et une série journalière, le CTR (clics ÷ impressions × 100) et l'eCPM (valeur délivrée × 1000 ÷ impressions), côté annonceur ou côté éditeur, et un classement par création, zone, campagne, site ou hôte du referrer. Seul l'hôte du referrer est conservé, jamais l'URL.
Référence de l'API
URL de base https://api.ad.forhosting.com. Envoyez votre clé en jeton Bearer ; corps et réponses sont en JSON. Chaque réponse a la forme {"success":true,"data":…} ou {"success":false,"error":{"code","message"}} avec le statut HTTP correspondant.
curl https://api.ad.forhosting.com/me \
-H "Authorization: Bearer ads_ten_…"
Portées des identifiants
| Portée | Ce qu'elle peut faire |
|---|---|
session | Ce que le panneau utilise : votre propre compte, accès complet, expire en quelques minutes. Émise par le portail à l'ouverture du panneau. |
tenant | Votre propre compte, accès complet, permanente. Pour vos intégrations. |
read | Votre propre compte, lecture seule. Pour les tableaux de bord et robots qui ne doivent rien modifier. |
system | La maison : n'importe quel compte (avec un tenantId explicite), revues, vérification des sites, paiements manuels et versements. L'équipe utilise une session system qui expire aussi. |
Un identifiant tenant, read ou session opère toujours son propre compte — un tenantId envoyé par le client est ignoré. Un identifiant qui appartient à quelqu'un d'autre renvoie 404, pas 403 : l'API ne confirme jamais qu'il existe.
Routes
Toutes les routes que le service annonce, avec la portée que le routeur exige — dérivée du routeur lui-même à chaque build.
| Méthode | Route | Portée |
|---|---|---|
| GET | / | publique |
| GET | /ad-serve | publique |
| GET | /ad-click | publique |
| GET | /ad-video-event | publique |
| GET | /ad-a/* | publique |
| GET | /ad-p/* | publique |
| GET | /ad-preview/* | publique |
| GET | /ad-tag.js | publique |
| POST | /tenants | system |
| GET | /tenants | system |
| GET | /tenants/:id | n'importe laquelle |
| PATCH | /tenants/:id | écriture |
| POST | /tenants/:id/sessions | system |
| POST | /sessions/staff | system |
| DELETE | /sessions/self | n'importe laquelle |
| DELETE | /sessions/:id | system |
| GET | /me | n'importe laquelle |
| POST | /tenants/:id/keys | écriture / system |
| GET | /tenants/:id/keys | lecture / system |
| DELETE | /tenants/:id/keys/:keyId | écriture / system |
| GET | /me/payout-profile | lecture |
| PUT | /me/payout-profile | écriture |
| POST | /campaigns | écriture |
| GET | /campaigns | lecture |
| GET | /campaigns/:id | lecture |
| PATCH | /campaigns/:id | écriture |
| DELETE | /campaigns/:id | écriture |
| POST | /campaigns/:id/duplicate | écriture |
| POST | /creatives | écriture |
| GET | /creatives | lecture |
| GET | /creatives/:id | lecture |
| PATCH | /creatives/:id | écriture |
| DELETE | /creatives/:id | écriture |
| PUT | /creatives/:id/asset | écriture |
| POST | /creatives/:id/duplicate | écriture |
| POST | /creatives/bulk | écriture |
| GET | /moderation/queue | system |
| GET | /moderation/preview-url/:id | n'importe laquelle |
| POST | /creatives/:id/approve | system |
| POST | /creatives/:id/reject | system |
| POST | /creatives/:id/emergency-block | system |
| POST | /sites | écriture |
| GET | /sites | lecture |
| GET | /sites/pending | system |
| GET | /sites/:id | lecture |
| PATCH | /sites/:id | écriture |
| DELETE | /sites/:id | écriture |
| POST | /zones | écriture |
| GET | /zones | lecture |
| GET | /zones/:id | lecture |
| PATCH | /zones/:id | écriture |
| DELETE | /zones/:id | écriture |
| GET | /zones/:id/tag | lecture |
| GET | /zones/:id/quote | n'importe laquelle |
| POST | /zones/:id/publish | system |
| GET | /marketplace | n'importe laquelle |
| POST | /checkout | écriture |
| GET | /orders | lecture |
| GET | /orders/:id | lecture |
| GET | /orders/pending | system |
| POST | /orders/:id/pay | écriture |
| POST | /orders/:id/mark-paid | system |
| GET | /payouts | lecture |
| GET | /payouts/pending | system |
| POST | /payouts/:id/request | écriture |
| POST | /payouts/:id/status | system |
| POST | /payouts/:id/mark-paid | system |
| GET | /stats | lecture |
| GET | /stats/top | lecture |
| GET | /settings | n'importe laquelle |
| PUT | /settings | system |
| GET | /templates | n'importe laquelle |
| POST | /templates | écriture |
| PATCH | /templates/:id | écriture |
| DELETE | /templates/:id | écriture |
| POST | /templates/:id/render | n'importe laquelle |
| GET | /geo/countries | n'importe laquelle |
| GET | /geo/regions | n'importe laquelle |
publique: sans identifiant — le chemin de diffusion · n'importe laquelle: tout identifiant valide, sur son propre compte · lecture: tenant, session ou read · écriture: tenant ou session (read est refusé) · system: la maison seulement
Erreurs à connaître : 401 unauthorized (identifiant absent ou expiré), 403 forbidden (la portée ne peut pas faire cela), 404 not_found, 400 bad_request avec le motif dans le message, 409 conflict (une transition d'état non permise), 402 insufficient_balance au paiement d'une commande, et 503 payments_disabled si les ventes sont en pause.
Ouvrez votre panneau
Connectez-vous sur forhosting.com et choisissez « Gérer mon AD » dans le menu de votre compte. Les éditeurs ajoutent un site et récupèrent leur balise ; les annonceurs créent une campagne et achètent un emplacement.
Questions techniques
Puis-je lancer une vraie campagne aujourd'hui ?
Oui — de bout en bout : créez la campagne et la création dans le panneau, passez la revue, achetez un emplacement, et la balise diffuse avec son suivi. Sur vos propres sites, activation instantanée et gratuite.
Où trouver la balise ?
Panneau → Sites et zones → obtenir la balise. Chaque zone a la sienne ; la variante standard est un div plus un script.
Pourquoi ma création n'a-t-elle pas diffusé tout de suite ?
Chaque création passe une courte revue manuelle avant de diffuser — cela protège les sites où votre annonce apparaît. Rotation et plafonds s'appliquent aussi : une création plafonnée ou lissée saute des requêtes à dessein, et une zone modifiée met jusqu'à une minute à se rafraîchir en bordure.