API GeoPulse — référence v1

Base : https://geo-pulse.app/api/v1

L'API donne accès en lecture seule à ce que GeoPulse produit chaque jour : prix de 48 actifs, événements géopolitiques scorés par IA, signaux ouverts, indice composite et corrélations. Aucun endpoint n'écrit, ne modifie un compte ni n'expose de donnée personnelle.

Elle est réservée au plan API. Pour y accéder aujourd'hui, contactez-nous — le plan n'est pas encore ouvert en libre-service.


Authentification

Chaque requête porte votre clé, au choix :

curl -H "X-API-Key: gp_live_votrecle" https://geo-pulse.app/api/v1/prices
curl -H "Authorization: Bearer gp_live_votrecle" https://geo-pulse.app/api/v1/prices

Les clés se créent et se révoquent depuis votre compte → onglet API. Une clé n'est affichée qu'une seule fois, à sa création : nous n'en stockons que l'empreinte (SHA-256), et nous sommes donc incapables de vous la rappeler. Perdue, elle se remplace — révoquez-la et créez-en une autre.

Jusqu'à 5 clés actives simultanément : une par environnement, ce qui permet d'en révoquer une sans interrompre les autres.


Limites

valeur
Débit 60 requêtes/minute, par clé
Quota 50 000 requêtes/jour, par clé, remis à zéro à 00:00 UTC

Chaque réponse porte l'état de vos compteurs :

X-RateLimit-Limit: 50000            X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining: 49987        X-RateLimit-Remaining-Minute: 58

Un dépassement de débit renvoie 429 avec un en-tête Retry-After en secondes — et ne consomme pas de quota journalier : une rafale mal réglée ne peut pas vider votre abonnement sans vous avoir rien rendu. Un dépassement de quota renvoie également 429, jusqu'à la remise à zéro.

À quelle fréquence appeler ?

Nos données ne changent pas plus vite que nous ne les collectons. Appeler au-delà de ces cadences renvoie la même réponse :

donnée rafraîchissement
Prix des 16 actifs du moteur 30 s en crise, 2 min sinon
Prix des 32 actifs observés 5 min en crise, 15 min sinon
Événements 1 min en crise, 5 min sinon
Signaux toutes les 2 h, plus immédiat sur événement de sévérité ≥ 7
Indice composite toutes les heures
Corrélations toutes les 15 min

Un client qui interroge l'ensemble du produit une fois par minute consomme environ 1 440 requêtes par jour, soit 3 % du quota.


Endpoints

GET / — documentation exécutable

Public, sans clé. Renvoie la liste des endpoints, les limites en vigueur et les cadences de rafraîchissement. Utile pour vérifier une version sans lire cette page.

GET /assets — registre des actifs

{ "count": 48,
  "assets": [ { "symbol": "XAU", "name": "Or", "category": "commodity", "unit": "$",
                "tier": "signals", "covered_by_rules": true, "family": null } ] }

tier vaut signals (16 actifs, couverts par les règles de signaux, collecte rapide) ou observed (32 actifs, suivis et affichés, hors moteur). covered_by_rules dit explicitement lesquels peuvent produire un signal.

GET /prices — dernier prix de tous les actifs

Renvoie prix, variation 24 h et horodatage pour les 48 actifs. Réponse mise en cache 10 secondes (donc toujours plus fraîche que la collecte).

GET /prices/:asset — historique d'un actif

Paramètre days (1-365, défaut 30).

curl -H "X-API-Key: $KEY" "https://geo-pulse.app/api/v1/prices/XAU?days=90"

Un symbole inconnu renvoie 404 avec la liste des symboles connus — pas besoin d'aller la chercher ailleurs.

GET /events — événements géopolitiques scorés

Paramètre limit (1-200, défaut 20). Chaque événement porte son score de sévérité (0-10, issu du scoring IA), sa catégorie, sa région et sa source.

GET /signals — signaux ouverts

Les décisions non encore résolues : règle, actif, direction, magnitude attendue, horizon, confiance, prix à l'émission, date de résolution prévue.

Ce sont des signaux algorithmiques, pas des conseils en investissement. La méthode, les abstentions et le track record scellé sont publics sur geo-pulse.app/scoreboard.

GET /index — indice composite GeoPulse

Score 0-100 et ses cinq sous-scores (géopolitique, sentiment, stress, momentum, volatilité). Paramètre history (1-500) pour la série.

{ "index": { "score": 62, "classification": "elevated",
             "components": { "geo": 71, "sentiment": 48, "stress": 55,
                             "momentum": 75, "volatility": 60 },
             "calculated_at": 1784800000000 } }

GET /correlations — corrélations entre actifs

Pearson sur 30 jours glissants, recalculé toutes les 15 minutes.

GET /usage — votre consommation

Paramètre days (1-90, défaut 30). Renvoie la consommation du jour et l'historique quotidien de la clé utilisée pour l'appel.


Codes de réponse

code signification que faire
200 Succès
401 api_key_required Aucune clé fournie Ajoutez l'en-tête
401 api_key_invalid Clé inconnue Vérifiez la clé ; elle a peut-être été régénérée
401 api_key_revoked Clé révoquée Créez-en une nouvelle depuis votre compte
403 api_plan_required Le compte n'est plus sur le plan API Réactivez l'abonnement
404 unknown_asset Symbole inconnu La réponse liste les symboles valides
429 rate_limit_exceeded Débit dépassé Attendez Retry-After secondes
429 quota_exceeded Quota journalier atteint Attendez 00:00 UTC

Le tier du compte est relu à chaque requête : une résiliation coupe l'accès immédiatement, sans qu'il faille révoquer les clés une par une.


Exemple complet

export KEY="gp_live_votrecle"
BASE="https://geo-pulse.app/api/v1"

# Indice composite et ses composantes
curl -s -H "X-API-Key: $KEY" "$BASE/index" | jq '.index'

# Les 5 événements les plus récents, avec leur score de sévérité
curl -s -H "X-API-Key: $KEY" "$BASE/events?limit=5" | jq '.events[] | {title, score}'

# Historique de l'or sur 90 jours
curl -s -H "X-API-Key: $KEY" "$BASE/prices/XAU?days=90" | jq '.count'

# Consommation restante
curl -sD- -o/dev/null -H "X-API-Key: $KEY" "$BASE/prices" | grep -i ratelimit

Stabilité et versionnage

La v1 est additive : de nouveaux champs peuvent apparaître, aucun champ existant ne sera retiré ni renommé sans une v2. Écrivez vos clients en ignorant les champs inconnus.

Les réponses sont normalisées et ne reflètent pas le schéma interne de la base : nos tables peuvent évoluer sans casser votre intégration.

Nous ne publions pas d'engagement de disponibilité (SLA). L'infrastructure est un serveur unique ; annoncer 99,9 % serait un chiffre que nous ne pouvons pas encore tenir.


Webhooks

Plutôt que d'interroger l'API en boucle, faites-vous prévenir. Les endpoints se configurent depuis votre compte → onglet API.

Événements disponibles : signal.created, signal.resolved, event.high_severity, index.updated.

Ce que vous recevez

POST https://votre-domaine/hook
Content-Type: application/json
X-GeoPulse-Event: signal.created
X-GeoPulse-Timestamp: 1784800000
X-GeoPulse-Signature: sha256=<hmac>
X-GeoPulse-Delivery: 4213

{ "type": "signal.created", "created_at": 1784800000000, "data": { … } }

Vérifier la signature — à faire systématiquement

La signature est un HMAC-SHA256 de <timestamp>.<corps exact reçu>, avec le secret affiché à la création de l'endpoint.

import crypto from 'node:crypto';

function verify(rawBody, headers, secret) {
  const ts = headers['x-geopulse-timestamp'];
  const expected = crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
  const got = (headers['x-geopulse-signature'] || '').replace('sha256=', '');
  // Comparaison à temps constant : une comparaison naïve fuit la signature.
  const ok = got.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected));
  // L'horodatage fait partie de la signature : refusez ce qui est trop vieux,
  // sinon un appel intercepté peut être rejoué indéfiniment.
  return ok && Math.abs(Date.now() / 1000 - Number(ts)) < 300;
}

⚠️ Signez le corps brut, avant tout JSON.parse. Une re-sérialisation change les espaces et invalide la signature.

Livraison et nouvelles tentatives

Une réponse 2xx vaut accusé de réception. Tout le reste — code d'erreur, délai dépassé (10 s), connexion refusée — déclenche une nouvelle tentative selon un délai croissant : 1 min, 5 min, 15 min, 1 h, 6 h, 24 h, puis abandon de cet événement.

Après 10 échecs consécutifs, l'endpoint est désactivé et cesse de recevoir. Le journal reste consultable, et vous pouvez le réactiver après correction.

Répondez vite (< 10 s) : mettez le traitement en file de votre côté plutôt que de le faire pendant la requête.

Contraintes

HTTPS obligatoire, adresses internes refusées, 5 endpoints actifs maximum. Le secret n'est affiché qu'à la création — il se régénère, il ne se relit pas. Le journal des livraisons est conservé 30 jours.