Idlen Logo
API annonceurs

Écriture

Créer et modifier des campagnes et des annonces, et ouvrir un lien Checkout de dépôt

Écriture

POST et PATCH exigent le droit write. Les montants sont en centimes d'euro. Envoyez Content-Type: application/json.

https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api

POST accepte Idempotency-Key. Voir Vue d'ensemble. Pause et reprise n'acceptent pas de corps JSON. Un corps non vide sur ces routes renvoie 400.

/creatives est la même ressource que /ads.

Créer une campagne

POST /campaigns crée la campagne et son ensemble d'annonces dans cette organisation, avec created_via à api. status vaut draft par défaut. objective vaut traffic par défaut. budget_type vaut daily par défaut.

name (1 à 120 caractères) et budget_cents sont obligatoires.

ObjectifFacturationEnchère
awarenessCPMcpm_bid_cents, 10 € à 100 € pour 1 000 impressions
traffic, conversionCPCcpc_bid_cents, 0,50 € à 10 € par clic

bid_cents est un alias de l'enchère du modèle de facturation. Le budget quotidien va de 10 € à 1 000 € (1000 à 100000 centimes). Le budget à vie va de 50 € à 10 000 € (5000 à 1000000 centimes). daily_budget_cents est un plafond quotidien optionnel quand budget_type vaut lifetime (10 € à 1 000 €), ou null pour l'effacer.

curl -X POST 'https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api/campaigns' \
  -H 'Authorization: Bearer idl_adv_xxx' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: campaign-2026-11-04' \
  -d '{
    "name": "Spring launch",
    "objective": "traffic",
    "budget_type": "daily",
    "budget_cents": 2000,
    "cpc_bid_cents": 100,
    "targeting": {
      "placements": ["inline", "chat_sponsored_recommendation"],
      "countries": ["FR", "DE"],
      "tech_stack": { "include": ["react"], "exclude": ["vue"] }
    }
  }'

Une création réussie renvoie 201 et { "data": { ...campaign } }.

Autres champs d'écriture :

ChampRègle
statusdraft, active ou paused. active est refusé pour la première campagne API
start_date, end_dateISO-8601, ou null pour effacer. end_date doit être le même jour ou après start_date
conversion_eventChaîne de 80 caractères au plus, ou null
conversion_window_daysEntier, 1 à 90
targeting.placementsAu moins un des emplacements ci-dessous
targeting.countriesCodes pays ISO. [] ou null signifie monde entier
targeting.tech_stackListes include et exclude. Une technologie ne peut pas être dans les deux

Emplacements : browser_overlay, browser_toast, chat_sponsored_recommendation, chat_cta_card, chat_contextual_link, chat_sponsored_answer, inline, toast, sidebar, popup.

Un champ JSON inconnu renvoie 400.

Modifier, mettre en pause, relancer

PATCH /campaigns/{id} ne change que les champs envoyés. Le ciblage, l'enchère et le budget mettent à jour le premier ensemble d'annonces de la campagne.

curl -X PATCH 'https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api/campaigns/CAMPAIGN_UUID' \
  -H 'Authorization: Bearer idl_adv_xxx' \
  -H 'Content-Type: application/json' \
  -d '{ "cpc_bid_cents": 150 }'
curl -X POST 'https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api/campaigns/CAMPAIGN_UUID/pause' \
  -H 'Authorization: Bearer idl_adv_xxx' \
  -H 'Idempotency-Key: pause-campaign-1'

La pause passe la campagne et ses ensembles d'annonces à paused.

curl -X POST 'https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api/campaigns/CAMPAIGN_UUID/resume' \
  -H 'Authorization: Bearer idl_adv_xxx' \
  -H 'Idempotency-Key: resume-campaign-1'

La reprise passe la campagne et ses ensembles d'annonces à active quand le portefeuille a un solde et qu'au moins une annonce est approuvée.

Première campagne

La première campagne de l'organisation ne peut pas être activée depuis cette API si elle a été créée par l'API (created_via vaut api). POST /campaigns avec "status": "active", un PATCH qui met status à active, et POST /campaigns/{id}/resume renvoient 409. La campagne reste un brouillon.

{
  "error": {
    "code": "first_campaign_requires_dashboard_validation",
    "message": "This organization's first campaign was created through the API. Activate it in the adsmanager before the API can turn a campaign on.",
    "campaign_id": "CAMPAIGN_UUID",
    "dashboard_url": "https://adsmanager.idlen.io/campaigns/CAMPAIGN_UUID"
  }
}

Ouvrez dashboard_url et activez cette campagne dans Ads Manager. Une campagne suivante n'est pas bloquée par cette règle. Elle ne peut passer active que si le portefeuille a des fonds et qu'au moins une annonce est approuvée. Sinon le statut est 409 et error.code vaut insufficient_balance, ads_pending_moderation, ad_required ou no_active_ad_set.

Créer une annonce

POST /ads exige campaign_id (UUID dans cette organisation), title (1 à 60 caractères) et cta_url (une URL https://). body est vide par défaut et fait 150 caractères au plus. cta_text fait 1 à 40 caractères. image_url est une URL https:// ou null.

curl -X POST 'https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api/ads' \
  -H 'Authorization: Bearer idl_adv_xxx' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: ad-2026-11-04' \
  -d '{
    "campaign_id": "CAMPAIGN_UUID",
    "title": "Ship the integration",
    "body": "Native ads in your AI product.",
    "cta_text": "Get started",
    "cta_url": "https://example.com/signup",
    "format": "inline"
  }'

La réponse est 201 et { "data": { ...ad } }. format et chaque entrée de formats doivent être un des emplacements listés plus haut.

Modération

Une nouvelle annonce est insérée avec la modération. Pour un appelant non staff, is_approved reste null et is_active reste false tant qu'une personne ne l'a pas approuvée. Elle n'est pas diffusée avant.

La règle site-creative peut auto-approuver à l'insertion quand le titre, le texte, le bouton, le lien et l'image correspondent à une création récente générée par le serveur, que l'image a été copiée par l'extracteur, et que le domaine du lien correspond au site de l'organisation.

Changer le titre, le texte, le bouton, le lien, l'image, la vidéo ou le type de média remet l'annonce en attente (is_approved null, is_active false) jusqu'à une nouvelle approbation.

PATCH /ads/{id} (et PATCH /creatives/{id}) ne change que les champs envoyés.

curl -X PATCH 'https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api/ads/AD_UUID' \
  -H 'Authorization: Bearer idl_adv_xxx' \
  -H 'Content-Type: application/json' \
  -d '{ "title": "Updated headline" }'

Annonce depuis une URL

POST /ads/from-url utilise le même extracteur de page que Ads Manager, enregistre la preuve, puis crée l'annonce. La modération s'applique toujours. Cet appel partage la limite de 10 requêtes par organisation et par heure.

curl -X POST 'https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api/ads/from-url' \
  -H 'Authorization: Bearer idl_adv_xxx' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: ad-from-url-1' \
  -d '{ "campaign_id": "CAMPAIGN_UUID", "url": "https://example.com" }'

campaign_id et url sont obligatoires. url fait 2048 caractères au plus. Une page illisible renvoie 422. Au-delà de la limite horaire, la réponse est 429 avec rate_limited. POST /creatives/from-url est le même appel.

Checkout de dépôt

POST /wallet/checkout renvoie une URL Stripe Checkout. Il ne débite pas une carte. Le webhook crédite le portefeuille après le paiement. La devise de la session est EUR, comme le portefeuille. Cette réponse n'a pas de champ devise.

amount_cents est obligatoire, de 1000 (10 €) à 1000000 (10 000 €), hors taxe.

success_url et cancel_url doivent être sur https://adsmanager.idlen.io, https://ads.idlen.io ou http://localhost:3002. Toute autre valeur est remplacée par la page de facturation.

campaign_id est optionnel. Si cette campagne est un brouillon non archivé de cette organisation, le dépôt lui est rattaché.

La prime de premier dépôt est la même règle que la page de facturation. Le match par défaut est 50 € une fois : payez au moins 50 € hors taxe et la prime est 50 € de crédit. Le webhook décide la prime à partir du montant payé, hors taxe et après un éventuel code promo.

curl -X POST 'https://tyfrhxfejrawgdlhryfu.supabase.co/functions/v1/advertiser-api/wallet/checkout' \
  -H 'Authorization: Bearer idl_adv_xxx' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: deposit-5000' \
  -d '{ "amount_cents": 5000 }'
{
  "data": {
    "url": "https://checkout.stripe.com/c/pay/cs_example",
    "session_id": "cs_example"
  }
}

url peut valoir null si Stripe n'en renvoie pas. Une organisation sans propriétaire renvoie 400.

Copyright © 2026