L’API de geoscope

Une API JSON pour piloter un compte d’agence depuis vos propres programmes : le portefeuille, les ajouts, les questions, les documents. Tout ce qui coûte se fait en deux temps.

Mis à jour le 29 septembre 2026

Conventions

  • Base : https://geo.greeneris.io. Le service tourne derrière le site, sous le nom de la marque. Il n’y a qu’un environnement : la production.
  • Barre finale : chaque adresse se termine par /. Sans elle, le site répond par une redirection 308 que certains clients HTTP ne suivent pas sur un POST.
  • Format : JSON UTF-8, en entrée (Content-Type: application/json) comme en sortie. Une exception, en formulaire : /lead/.
  • Verbes : GET et POST seulement. Ce qui modifie est en POST, même une résiliation.
  • Erreurs : un objet {"erreur": "…"} dont la phrase, en français, se montre telle quelle à l’agence. Une route qui n’existe pas, ou dont l’interrupteur est éteint, répond 404 {"detail": "Not Found"}.
  • Dates : des horodatages Unix en secondes pour les champs *_ts, des jours écrits JJ/MM/AAAA pour ce qui se lit.
  • Version : /agence/v1/. Les champs décrits ici sont ceux du code au 28 septembre 2026 ; un champ peut s’ajouter à une réponse sans changer de version.

Les codes

200
La réponse, y compris une proposition qui n’a rien lancé (confirme: false).
401
Aucune clé dans l’en-tête.
403
Clé inconnue, révoquée ou faite pour une autre porte (les trois cas ne se distinguent pas), ou compte suspendu (en pause, échu) : la réponse porte alors statut.
404
Ce client n’est pas sur ce compte.
409
Une règle métier refuse le geste : déjà retiré, plus de place, une seule correction, un audit par jour…
422
Corps illisible ou champ manquant.
429
Plus de 600 appels en une heure pour une clé, ou plus de 30 clés refusées en une heure depuis une adresse IP.

Authentification

La clé de compte, dans l’en-tête x-api-key de chaque appel. Elle est liée à un compte d’agence et ne s’obtient que par lui : « ma clé », par email ou dans la console, et une personne la remet après vérification. Le compte est relu en base à chaque appel : une agence mise en pause le matin ne commande plus l’après-midi, même avec une clé accordée la veille.

Une clé prouve qui appelle, pas ce qu’il veut. Un programme branché sur cette API agit au nom de l’agence, et personne ne relit ce qu’il envoie. C’est pourquoi tout ce qui coûte se fait en deux temps : sans confirmer, la réponse dit ce qui se passerait et rien n’est écrit ; avec "confirmer": true, le geste est fait. La réponse porte toujours confirme.

Les refus, tels qu’ils arrivent
HTTP/1.1 401 Unauthorized
{"erreur": "clé requise dans l'en-tête x-api-key — c'est la clé de votre compte d'agence ; pour en obtenir une, écrivez à hello@greeneris.io"}

HTTP/1.1 403 Forbidden
{"erreur": "clé inconnue ou pas encore accordée"}

HTTP/1.1 409 Conflict
{"erreur": "déjà retiré"}

Sans clé

GET/health/

Le service répond. Aucune authentification, aucun effet de bord. C’est l’adresse à surveiller.

Vérifier que le service répond
curl https://geo.greeneris.io/health/
# {"ok": true}

POST/lead/

Ce que le formulaire du site envoie pour demander un diagnostic gratuit. Un formulaire (multipart/form-data ou application/x-www-form-urlencoded), des champs entreprise et email obligatoires, ville, site_web, metier, concurrents, message et objet facultatifs, une page HTML en retour. Les longueurs maximales sont dans la spécification. Réponses : 200, 422 si le nom ou l’adresse manquent, 429 au-delà de vingt demandes acceptées par heure depuis la même adresse IP.

Ce n’est pas une API de lecture : chaque demande acceptée déclenche une alerte et une mesure réelle, qui interroge des modèles payants et lit le site indiqué. Aucun exemple d’appel automatisé n’est publié ici, volontairement.

L’API des agences

Vingt routes sous /agence/v1/, pour une agence qui fait mesurer ses clients finaux et reçoit leurs documents à ses couleurs. Les mêmes fonctions servent l’email, la console et l’API : mêmes limites, mêmes refus, mêmes mots. {id} est l’identifiant que rend GET /agence/v1/clients/.

Ce que le compte couvre (clients, questions et IA par client, diagnostics de prospects par mois) dépend de la formule : GET /agence/v1/aide/ le rend pour votre compte, et la page agences et freelances le publie.

Lire. Rien ne change, rien ne se paie.
RouteCe qu’elle faitCorps JSONRend (200)Refus
GET/agence/v1/compte/Le compte : formule, plafond, places, décompte des diagnostics de prospects du mois, état du paiement.—slug, nom, plan, statut, servi, plafond, clients[], places_restantes, places_tenues[], leads{quota, utilises, restants}, paiement{etat, paye_jusqu_au…}401 · 403 · 429
GET/agence/v1/clients/Le portefeuille : chaque client final, sa dernière mesure, combien de documents existent pour lui.—clients[{id, entreprise, site, ville, derniere_mesure, mesure, livrables, actif}], plafond, places_restantes, places_tenues[]401 · 403 · 429
GET/agence/v1/clients/{id}/livrables/Ses rapports et ses pages, par liens. Des pages HTML autonomes hébergées chez nous : remettez le document, pas le lien.—client, livrables[{genre, periode, titre, etat, cree, lien}]404 client hors du compte
GET/agence/v1/clients/{id}/questions/Les questions posées aux IA, mot pour mot, et où il en est sur chacune : conquerir (jamais cité), consolider (cité derrière un concurrent), acquise (cité en tête) ; son rang (1 = où il perd le plus) ; la page qui l’a déjà visée ; la question notée pour sa prochaine page.—client, entreprise, questions[], etats[{n, question, etat, rang, page}], mesure, prochaine_page{numero, question, choisi}404
GET/agence/v1/diagnostics/Les diagnostics de prospects des trente derniers jours, avec leur lien dès qu’ils sont prêts, et le décompte du mois.—leads{quota, utilises, restants, mois, repart_le}, diagnostics[{entreprise, site, ville, metier, demande_ts, etat, lien}]401 · 403 · 429
GET/agence/v1/aide/Le mode d’emploi rendu par l’API elle-même : ce que l’agence reçoit, ses limites, chaque route en une phrase, ce qu’il faut savoir.—compte, ce_que_vous_recevez[], vos_limites{clients, questions_par_client, ias_par_client, leads_par_mois}, routes{}, a_savoir[]401 · 403 · 429
Agir en deux temps. Sans « confirmer », la proposition ; avec, le geste. La réponse porte toujours « confirme ».
RouteCe qu’elle faitCorps JSONRend (200)Refus
POST/agence/v1/clients/Ajouter des clients, cinquante au plus par appel. Sans confirmer : ce qui passerait, ce qui ne passerait pas et pourquoi. Avec : les clients sont posés, leurs questions se préparent et attendent une validation (24 h, puis la mesure part seule).clients[{entreprise*, site_web*, ville, metier, concurrents, contexte}], confirmeracceptes[], refuses[{quoi, pourquoi}], places_restantes, confirme, suite — puis poses[] une fois confirmé409 compte non servi · 422 corps
POST/agence/v1/clients/{id}/retirer/Retirer un client. Sa place reste tenue trente jours après son premier diagnostic. La fiche est fermée, jamais effacée : le client peut être repris.confirmerretirerait | retire, entreprise, place_libre_le, note, confirme404 · 409 déjà retiré
POST/agence/v1/clients/{id}/corriger/Corriger le nom, le site, la ville ou le métier. Une correction refait la configuration et le premier rapport : une seule par client.entreprise, site_web, ville, metier, confirmerclient, entreprise, avant{}, apres{}, note, confirme404 · 409 rien à corriger, site invalide, déjà corrigé
POST/agence/v1/diagnostics/Le diagnostic d’un prospect, aux couleurs de l’agence, sans offre de notre part ; le prospect n’est jamais contacté. Trois par client couvert et par mois. Refusé sans lancer s’il est déjà client, déjà diagnostiqué depuis moins de trente jours, ou si le mois est épuisé.entreprise*, site_web*, ville, metier, confirmercompris{}, leads{}, confirme, lance, raison?, lien?, suite | note409 nom ou site manquant
POST/agence/v1/marque/Le nom, la couleur et le contact imprimés sur les prochains documents. Ceux déjà remis sont gelés.nom, couleur (#rrggbb), contact, confirmerchangerait{}, actuelle{}, confirme — puis marque{} une fois confirmé422 rien à changer, couleur invalide
POST/agence/v1/resilier/Résilier à la fin de la période déjà réglée. Les clients sont mesurés jusqu’à cette date. Par carte, la réponse renvoie à l’espace Stripe, qui arrête les prélèvements.confirmerfin_le, fin_le_ts, mode_paiement, note, confirme, espace_de_paiement?409 déjà enregistrée
POST/agence/v1/badge/Changer l’adresse de commande par email. L’ancienne cesse de fonctionner à l’instant ; les sessions de la console sont fermées.confirmerconfirme, note — puis badge401 · 403 · 429
Agir tout de suite, ou transmettre. Un geste sans coût s’applique à l’instant ; ce qui change qui reçoit les documents ou ce qui est facturé attend une personne.
RouteCe qu’elle faitCorps JSONRend (200)Refus
POST/agence/v1/clients/{id}/questions/Le second temps de l’ajout : ajuster les questions d’un client ajouté, puis lancer sa mesure. Possible seulement avant la première mesure.retirer[n…], remplacer{"n": "texte"}, lancerclient, entreprise, questions[], mesure_lancee, note404 · 409 mesure déjà lancée
POST/agence/v1/clients/{id}/page/Choisir la question de sa prochaine page. Sans coût ; se change jusqu’à ce que la page soit écrite. Sans choix, la machine prend la question où il perd le plus.numeroclient, entreprise, numero, question, etat, note404 · 409 pas encore mesuré, hors liste, déjà visée
POST/agence/v1/clients/{id}/audit/Refaire l’audit technique du site : un document neuf, sans appel d’IA, envoyé aussi par email. Un par client et par jour.—client, entreprise, lien, email_envoye404 · 409 déjà refait aujourd’hui, pas de première mesure
POST/agence/v1/adresses/Demander d’autoriser ou de retirer une adresse email du compte. Transmise, jamais appliquée d’ici : une personne vérifie, et toutes les adresses du compte sont prévenues.ajouter | retirer (une adresse)action, adresse, meme_domaine, etat: "transmise", adresses[], note409 adresse invalide, déjà autorisée, absente
POST/agence/v1/formule/Demander un changement de formule ; prend effet au paiement. Par carte, renvoie à l’espace de paiement. Une descente est refusée tant que les places occupées dépassent le nouveau plafond.formule : agence5 | agence15 | agence30de, vers, label, plafond, sens, etat, note | espace_de_paiement409 formule inconnue, déjà en place, descente impossible
POST/agence/v1/virement/Annoncer un virement. La date « payé jusqu’au » n’avance que lorsqu’il est constaté.—etat: "noté", note401 · 403 · 429
POST/agence/v1/cles/revoquer/Couper toutes les clés du compte, tout de suite, celle qui appelle comprise, et déconnecter les assistants IA qui y étaient branchés. Sans confirmation : une clé qui a fui se coupe d’abord.—coupees, assistants_coupes, note401 · 403 · 429

Exemples

Le compte
curl https://geo.greeneris.io/agence/v1/compte/ \
  -H "x-api-key: VOTRE_CLE"
Ajouter un client, en deux temps, puis valider ses questions
# 1. La proposition : rien n'est écrit, rien n'est lancé
curl -X POST https://geo.greeneris.io/agence/v1/clients/ \
  -H "x-api-key: VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"clients": [{"entreprise": "Garage Dupont",
                    "site_web": "https://garage-dupont.fr",
                    "ville": "Lyon", "metier": "garage automobile"}]}'

# 2. La même demande, confirmée : le client est posé, ses questions se préparent
curl -X POST https://geo.greeneris.io/agence/v1/clients/ \
  -H "x-api-key: VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"clients": [{"entreprise": "Garage Dupont",
                    "site_web": "https://garage-dupont.fr",
                    "ville": "Lyon", "metier": "garage automobile"}],
       "confirmer": true}'

# 3. Relire ses questions, en retirer une, en remplacer une, lancer la mesure
curl https://geo.greeneris.io/agence/v1/clients/ID/questions/ -H "x-api-key: VOTRE_CLE"
curl -X POST https://geo.greeneris.io/agence/v1/clients/ID/questions/ \
  -H "x-api-key: VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"retirer": [3], "remplacer": {"7": "Quel garage pour une révision à Lyon ?"},
       "lancer": true}'
Le portefeuille et les livrables, en Python
import requests

BASE = "https://geo.greeneris.io/agence/v1/"
ENTETES = {"x-api-key": "VOTRE_CLE"}

r = requests.get(BASE + "clients/", headers=ENTETES, timeout=30)
r.raise_for_status()
for c in r.json()["clients"]:
    print(c["id"], c["entreprise"], c["mesure"], c["livrables"], "document(s)")

# Les livrables d'un client : des liens à ouvrir dans un navigateur
r = requests.get(BASE + f"clients/{c['id']}/livrables/", headers=ENTETES, timeout=30)
for liv in r.json()["livrables"]:
    print(liv["genre"], liv["periode"], liv["lien"])

Ce qui n’y est pas

  • Un client direct n’a pas d’API. Ses rapports et ses briefs de page lui arrivent par email, et ses gestes (retirer une question, la remplacer, choisir sa prochaine page) se font en répondant à ces emails. L’API est réservée aux comptes d’agence.
  • Votre assistant IA ne passe pas par ici. Claude, ChatGPT ou Claude Code se branchent sur le compte par le connecteur MCP, qui a sa page, avec son protocole et sa connexion pour vos développeurs.
  • Le scan éclair a sa propre API, sur doesmybrandexist : deux routes et une clé accordée à la main, décrites sur doesmybrandexist.io/api-publique/. Une clé de scan n’ouvre pas un compte d’agence, et inversement.
  • Le reste du service est privé : les tâches de l’horloge interne, le webhook Stripe, les liens signés des rapports et des briefs. Fermés par secret ou par signature, ils ne sont pas documentés : la carte d’un bâtiment n’est pas une page d’accueil.

Questions fréquentes

Comment obtenir une clé d’API ?

Il faut un compte d’agence (voir /agences/). La clé se demande d’un mot, « ma clé », par email ou dans la console de l’agence ; elle est remise après vérification, par une personne, à l’adresse du compte. Si elle fuit, POST /agence/v1/cles/revoquer/ ou « révoque ma clé » la coupe à l’instant, avec toutes les autres.

Existe-t-il une API pour un client direct, sans agence ?

Non. Un client direct (Diagnostic complet, La Forge) reçoit ses rapports et ses briefs par email et pilote son suivi par email. L’API est réservée aux comptes d’agence. Si vous êtes un client direct et que vous en avez besoin, écrivez-nous.

Y a-t-il un bac à sable ?

Non. Chaque appel confirmé lance de vraies mesures sur de vrais modèles. C’est pour cela que tout ce qui coûte se fait en deux temps : l’appel sans « confirmer » est votre essai à blanc. Il rend exactement ce que l’appel confirmé ferait, et n’écrit rien.

Pourquoi une barre finale sur chaque adresse ?

Le site redirige en 308 toute adresse qui n’en a pas, et certains clients HTTP ne suivent pas une redirection sur un POST. Écrivez /agence/v1/clients/ et non /agence/v1/clients.

Puis-je appeler /lead/ depuis un programme ?

Techniquement oui, mais ce n’est pas prévu pour, et c’est pour cela qu’aucun exemple d’appel n’est publié. Chaque demande acceptée déclenche une alerte et une mesure réelle. Vingt demandes acceptées par heure et par adresse IP ; au-delà, 429. Si vous avez besoin d’un accès programmatique, c’est l’API des agences.

Une question qui demande un humain : hello@greeneris.io