RÉFÉRENCE

Compte & clés API

Gestion de session, clés API et récupération par email. La quasi-totalité de ces routes appartient à l'interface /compte/ du site — une seule est une vraie route d'intégration.

Route authentifiée par cookie de session, pas par clé API — elle sert l'interface de compte du site Atlas, pas une intégration externe.

Deux exceptions : GET /api/account/key-tier, authentifiée par X-API-Key et réellement publique, et POST /api/auth/recover, qui ne requiert pas de session (anti-énumération) mais n'utilise pas non plus de clé API — voir sa propre note ci-dessous.

GET/api/account/key-tier

Palier effectif d'une clé API, sans passer par une session — utilisée par l'extension Chrome, qui ne détient qu'une clé.

Seule route de ce groupe appelable par une clé API externe (X-API-Key). Toutes les autres routes de cette page utilisent le cookie de session /compte/.

Aucun paramètre. L'identité de l'appelant vient de l'en-tête X-API-Key.

Code
Clé
Description
401
invalid_api_key
Clé absente ou invalide (corps {"error": "invalid_api_key"}, pas le format detail i18n habituel).
CURL
curl -H "X-API-Key: $ATLAS_KEY" \
  "https://atlasfeed.fr/api/account/key-tier"
PYTHON
import requests

r = requests.get(
    "https://atlasfeed.fr/api/account/key-tier",
    headers={"X-API-Key": ATLAS_KEY},
)
print(r.json())
JAVASCRIPT
const r = await fetch("https://atlasfeed.fr/api/account/key-tier", {
  headers: { "X-API-Key": ATLAS_KEY },
});
const data = await r.json();
RÉPONSE
{"tier": "pro"}
POST/api/auth/recover

Renvoie par email les clés API actives d'un compte, sans jamais révéler si l'email correspond à un compte existant (réponse 202 identique dans tous les cas).

Ne requiert pas de session ni de cookie — c'est volontaire, pour rester joignable par n'importe qui sans exposer si un compte existe. Ce n'est pour autant pas une route d'intégration API : elle n'accepte pas X-API-Key, elle sert uniquement le lien « Clé API perdue ? » du site, protégée par un plafond de requêtes strict.
Nom
Type
Requis
Défaut
Description
email
str
oui
Corps JSON, champ email.
Code
Clé
Description
429
too_many_attempts_minute
Plus de 5 tentatives/minute pour cette IP.
429
too_many_requests_for_email
Plus de 3 tentatives/heure pour cet email.
CURL
curl -X POST "https://atlasfeed.fr/api/auth/recover" \
  -H "Content-Type: application/json" \
  -d '{"email": "vous@exemple.com"}'
PYTHON
import requests

r = requests.post(
    "https://atlasfeed.fr/api/auth/recover",
    json={"email": "vous@exemple.com"},
)
print(r.json())
JAVASCRIPT
const r = await fetch("https://atlasfeed.fr/api/auth/recover", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ email: "vous@exemple.com" }),
});
const data = await r.json();
RÉPONSE (202)
{"message": "Si cet email correspond à des clés API actives, elles viennent de lui être envoyées."}
POST/api/account/login

Envoie un lien de connexion par email — crée le compte s'il n'existe pas, avec une réponse strictement identique dans les deux cas.

Mécanisme interne à /compte/ : cookie de session posé après consultation du lien reçu par email, jeton CSRF requis sur cet appel. Non appelable par une clé API externe.
Nom
Type
Requis
Défaut
Description
email
str
oui
Corps JSON.
intent
str
non
"account"
"account" ou "extension" ; toute autre valeur retombe sur "account" sans erreur.
Code
Clé
Description
403
account_csrf_required
En-tête X-Atlas-CSRF absent — seule sa présence compte, jamais sa valeur.
429
too_many_attempts_minute
Plus de 5 tentatives/minute pour cette IP.
429
too_many_requests_for_email
Plus de 3 tentatives/heure pour cet email.
CURL
curl -X POST "https://atlasfeed.fr/api/account/login" \
  -H "Content-Type: application/json" \
  -H "X-Atlas-CSRF: 1" \
  -d '{"email": "vous@exemple.com"}'
PYTHON
# Réservé au front /compte/ : jeton CSRF et cookie de session
# gérés par le navigateur, non reproductibles simplement hors browser.
import requests

r = requests.post(
    "https://atlasfeed.fr/api/account/login",
    json={"email": "vous@exemple.com"},
    headers={"X-Atlas-CSRF": "1"},
)
print(r.json())
JAVASCRIPT
// Exécuté depuis /compte/ : le cookie CSRF et le cookie de session
// sont déjà présents dans le navigateur.
const r = await fetch("/api/account/login", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-Atlas-CSRF": "1" },
  credentials: "same-origin",
  body: JSON.stringify({ email: "vous@exemple.com" }),
});
const data = await r.json();
RÉPONSE (202)
{"message": "Si cet email est valide, un lien de connexion vient de lui être envoyé (valable 15 minutes, à usage unique)."}
GET/api/account/me

État du compte connecté : clés masquées (4 derniers caractères), quota en lecture seule, sessions actives. Aucune clé en clair, aucun appel réseau Stripe.

Cookie de session interne à /compte/. Non appelable par une clé API externe — ce cookie n'est jamais émis pour un usage tiers.

Aucun paramètre. L'identité de l'appelant vient de la session.

Code
Clé
Description
401
account_session_required
Session absente ou invalide.
CURL
# Le cookie atlas_session ne s'obtient QUE via le flux /compte/
# (lien de connexion reçu par email) — jamais émis pour un usage API tiers.
curl "https://atlasfeed.fr/api/account/me" \
  -H "Cookie: atlas_session=..."
PYTHON
# Réservé au front /compte/ : cookie de session non obtenable
# hors du navigateur.
import requests

r = requests.get(
    "https://atlasfeed.fr/api/account/me",
    cookies={"atlas_session": "..."},
)
print(r.json())
JAVASCRIPT
// Exécuté depuis /compte/ : le cookie de session est déjà présent.
const r = await fetch("/api/account/me", { credentials: "same-origin" });
const data = await r.json();
RÉPONSE
{
  "email": "test4@example.com", "tier": "free", "rpm": 5, "monthly": 1000,
  "keys": [{"masked": "atlas_…bwO4", "createdAt": "2026-09-09T12:03:34.599796+00:00", "expiresAt": null, "label": "test doc"}],
  "usage": {"count": 0, "limit": 1000, "resetsAt": "2026-10-01T00:00:00+00:00"},
  "sessions": [{"createdAt": "2026-09-09T12:03:01.007839+00:00", "lastSeenAt": "2026-09-09T12:03:34.612959+00:00", "userAgent": "curl/8.18.0", "current": true}]
}
GET/api/account/captures

Captures rattachées au compte connecté, pour la page /compte/.

Cookie de session interne à /compte/. Non appelable par une clé API externe.

Aucun paramètre. L'identité de l'appelant vient de la session.

Code
Clé
Description
401
account_session_required
Session absente ou invalide.
CURL
curl "https://atlasfeed.fr/api/account/captures" \
  -H "Cookie: atlas_session=..."
PYTHON
import requests

r = requests.get(
    "https://atlasfeed.fr/api/account/captures",
    cookies={"atlas_session": "..."},
)
print(r.json())
JAVASCRIPT
const r = await fetch("/api/account/captures", { credentials: "same-origin" });
const data = await r.json();
RÉPONSE
{"captures": []}

// Forme d'un élément si des captures sont rattachées au compte :
{
  "id": "...", "createdAt": "...",
  "countries": "FRA, DEU", "indicators": "NY.GDP.MKTP.CD",
  "countriesLabel": "France, Allemagne", "indicatorsLabel": "PIB"
}
POST/api/account/keys

Émet une clé API au palier du compte connecté (jamais un palier choisi par l'appelant). La clé en clair n'est renvoyée qu'une seule fois, ici.

Cookie de session interne à /compte/, jeton CSRF requis. Non appelable par une clé API externe.
Nom
Type
Requis
Défaut
Description
label
str | null
non
null
Corps JSON optionnel — un appel sans corps est accepté.
Code
Clé
Description
401
account_session_required
Session absente, invalide, ou compte introuvable.
403
(CSRF)
En-tête X-Atlas-CSRF absent.
CURL
curl -X POST "https://atlasfeed.fr/api/account/keys" \
  -H "Cookie: atlas_session=..." \
  -H "X-Atlas-CSRF: 1" \
  -H "Content-Type: application/json" \
  -d '{"label": "mon script"}'
PYTHON
import requests

r = requests.post(
    "https://atlasfeed.fr/api/account/keys",
    json={"label": "mon script"},
    cookies={"atlas_session": "..."},
    headers={"X-Atlas-CSRF": "1"},
)
print(r.json())
JAVASCRIPT
const r = await fetch("/api/account/keys", {
  method: "POST",
  credentials: "same-origin",
  headers: { "Content-Type": "application/json", "X-Atlas-CSRF": "1" },
  body: JSON.stringify({ label: "mon script" }),
});
const data = await r.json();
RÉPONSE (201)
{
  "key": "atlas_JRmlMfsiZS4QDnzqj-RDN9JgR-C5tcU0NL28hjCbwO4",
  "warning": "Cette clé ne sera plus jamais affichée en clair — enregistrez-la maintenant."
}
DELETE/api/account/keys/{masked_or_id}

Révoque une clé du compte connecté (idempotent). Accepte la forme masquée (atlas_…XXXX) ou la clé en clair.

Cookie de session interne à /compte/, jeton CSRF requis. Non appelable par une clé API externe.
Nom
Type
Requis
Défaut
Description
masked_or_id
str
oui
Segment de chemin — forme masquée ou clé en clair.
Code
Clé
Description
404
account_key_not_found
Aucune clé du compte ne correspond.
403
(CSRF)
En-tête X-Atlas-CSRF absent.
401
account_session_required
Session absente ou invalide.
CURL
curl -X DELETE "https://atlasfeed.fr/api/account/keys/atlas_...bwO4" \
  -H "Cookie: atlas_session=..." \
  -H "X-Atlas-CSRF: 1"
PYTHON
import requests

r = requests.delete(
    "https://atlasfeed.fr/api/account/keys/atlas_...bwO4",
    cookies={"atlas_session": "..."},
    headers={"X-Atlas-CSRF": "1"},
)
print(r.json())
JAVASCRIPT
const r = await fetch("/api/account/keys/atlas_...bwO4", {
  method: "DELETE",
  credentials: "same-origin",
  headers: { "X-Atlas-CSRF": "1" },
});
const data = await r.json();
RÉPONSE
{"ok": true}
POST/api/account/logout

Révoque la session courante et efface le cookie.

Cookie de session interne à /compte/, jeton CSRF requis. Non appelable par une clé API externe.

Aucun paramètre. L'identité de l'appelant vient de la session.

Code
Clé
Description
401
account_session_required
Session absente ou invalide.
403
(CSRF)
En-tête X-Atlas-CSRF absent.
CURL
curl -X POST "https://atlasfeed.fr/api/account/logout" \
  -H "Cookie: atlas_session=..." \
  -H "X-Atlas-CSRF: 1"
PYTHON
import requests

r = requests.post(
    "https://atlasfeed.fr/api/account/logout",
    cookies={"atlas_session": "..."},
    headers={"X-Atlas-CSRF": "1"},
)
print(r.json())
JAVASCRIPT
const r = await fetch("/api/account/logout", {
  method: "POST",
  credentials: "same-origin",
  headers: { "X-Atlas-CSRF": "1" },
});
const data = await r.json();
RÉPONSE
{"ok": true}

// Avec l'en-tête : Set-Cookie: atlas_session=""; Max-Age=0
POST/api/account/logout-all

Révoque TOUTES les sessions du compte, pas seulement la courante.

Cookie de session interne à /compte/, jeton CSRF requis. Non appelable par une clé API externe.

Aucun paramètre. L'identité de l'appelant vient de la session.

Code
Clé
Description
401
account_session_required
Session absente ou invalide.
403
(CSRF)
En-tête X-Atlas-CSRF absent.
CURL
curl -X POST "https://atlasfeed.fr/api/account/logout-all" \
  -H "Cookie: atlas_session=..." \
  -H "X-Atlas-CSRF: 1"
PYTHON
import requests

r = requests.post(
    "https://atlasfeed.fr/api/account/logout-all",
    cookies={"atlas_session": "..."},
    headers={"X-Atlas-CSRF": "1"},
)
print(r.json())
JAVASCRIPT
const r = await fetch("/api/account/logout-all", {
  method: "POST",
  credentials: "same-origin",
  headers: { "X-Atlas-CSRF": "1" },
});
const data = await r.json();
RÉPONSE
{"ok": true}
GET/api/account/session/{token}

Mention seule, hors détail : mécanisme de redirection interne consommant un jeton de connexion à usage unique pour poser le cookie atlas_session — appelé par le navigateur en cliquant le lien reçu par email, jamais par un client API. 404 générique dans tous les cas d'échec.