Documentation e-sotop Market API
Référence complète pour intégrer les données financières africaines et mondiales dans vos applications.
Introduction
e-sotop API est une interface REST unifiée qui réunit, sous une seule base URL et une seule clé, deux capacités complémentaires : la consultation des marchés financiers (BRVM, crypto, forex, actions, matières premières, OPCVM) et le placement d'ordres avec suivi de portefeuille.
Toutes les routes partagent le préfixe /api/v1 et se répartissent en trois familles : /markets (prix), /orders (exécution) et /accounts (portefeuille). Une même clé API, dotée de scopes et d'une granularité par marché, gouverne l'accès à l'ensemble.
Les données de marché reposent sur un cache intelligent pré-chargé en arrière-plan, garantissant des temps de réponse inférieurs à 50 ms dans la grande majorité des cas.
https://malaw-preprod.online/api/v1
/markets, /orders, /accounts. Votre clé API vous est communiquée après validation. Demander un accès →Démarrage rapide
Voici le chemin le plus court pour effectuer votre premier appel en moins de 2 minutes.
Étape 1 — Obtenir une clé API
Contactez-nous via le formulaire de contact pour recevoir votre clé API. Elle se présente sous cette forme :
es_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
Étape 2 — Premier appel
curl -X GET \ "https://malaw-preprod.online/api/v1/markets/brvm/SNTS" \ -H "X-API-Key: es_live_votre_cle_ici"
Étape 3 — Lire la réponse
{
"status": "success",
"request": {
"type": "brvm",
"asset": "SNTS",
"category": "equities"
},
"meta": {
"source": "brvm.org",
"updated_at": "2026-04-07T08:00:00Z",
"currency": "XOF"
},
"cache": { "hit": true, "age_sec": 187 },
"data": {
"ticker": "SNTS",
"name": "Sonatel",
"last_price": 18500,
"change_pct": 1.65,
"volume": 4320,
"prev_close": 18200
}
}
Authentification
Toutes les requêtes doivent inclure une clé API valide. Deux méthodes sont acceptées :
Via le header HTTP (recommandé)
X-API-Key: es_live_votre_cle_ici
Scopes & granularité par marché
Chaque clé porte deux niveaux de permission qui se combinent : des scopes (quelles opérations) et une liste de marchés autorisés (sur quels marchés).
| Scope | Autorise |
|---|---|
market:read | Lire les prix (/markets) |
orders:read | Consulter comptes & portefeuilles (/accounts) |
orders:trade | Placer des ordres (/orders) |
Exemple : une clé avec market:read et les marchés ["brvm","opcvm"] peut lire les prix BRVM et OPCVM, mais une requête sur crypto renverra 403. Votre périmètre exact (scopes et marchés) vous est communiqué avec votre clé.
X-API-Key plutôt que dans l'URL, qui peut apparaître dans les logs.
Conventions de format
Ces règles s'appliquent à tous les endpoints. Les tableaux de paramètres de chaque endpoint s'y réfèrent.
| Élément | Convention |
|---|---|
| Corps des requêtes | JSON, en-tête Content-Type: application/json obligatoire sur POST |
| Authentification | en-tête X-API-Key obligatoire sur toutes les requêtes |
| Montants | entiers, en XOF (pas de décimales) |
| Dates | chaîne au format AAAA-MM-JJ (ex. 1990-01-01) |
| Téléphone | phone : numéro local sans indicatif ; phone_code : indicatif avec + (ex. +225) |
| Documents | fichiers encodés en Base64 dans content_base64 |
| Booléens KYC | exprimés en chaîne ("Oui" / "Non") selon le courtier |
| Colonne « Requis » | Oui = rejet si absent · Cond. = requis sous condition · Non = optionnel |
Gestion des erreurs
L'API retourne toujours un JSON avec un champ status. En cas d'erreur, un champ message décrit le problème.
| Code HTTP | Status | Cause |
|---|---|---|
| 200 | success | Requête traitée avec succès. |
| 400 | error | Paramètre manquant ou invalide (type, asset). |
| 401 | error | Clé API absente ou invalide. |
| 403 | error | Compte suspendu ou type non autorisé par votre plan. |
| 404 | error | Asset introuvable. |
| 429 | error | Rate limit atteint. Attendez la prochaine fenêtre horaire. |
| 502 | error | Échec de récupération côté source externe. |
{
"status": "error",
"code": 401,
"message": "Clé API invalide."
}
Rate limiting
Chaque clé API est soumise à une limite de requêtes par heure, définie par votre plan. L'état du rate limit est transmis dans les headers de chaque réponse :
X-RateLimit-Limit: 500 X-RateLimit-Remaining: 487 X-RateLimit-Reset: 1712345678 X-RateLimit-Window: 3600
| Header | Description |
|---|---|
X-RateLimit-Limit | Nombre maximum de requêtes autorisées par heure. |
X-RateLimit-Remaining | Nombre de requêtes restantes dans la fenêtre courante. |
X-RateLimit-Reset | Timestamp UNIX de réinitialisation du compteur. |
Endpoint unique
Retourne les données d'un asset financier selon son type et son identifiant.
Paramètres de requête
| Paramètre | Type | Requis | Description |
|---|---|---|---|
type | string | Requis | Type de marché : brvm, crypto, forex, stocks, commodities |
asset | string | Requis | Identifiant de l'asset (ex: SNTS, BTC, EURUSD) ou ALL pour la liste complète. |
category | string | Optionnel | Sous-catégorie BRVM uniquement : equities (défaut), bonds, indices |
BRVM — Bourse Régionale des Valeurs Mobilières
Couvre l'ensemble des titres cotés à la BRVM : actions, obligations et indices. Les données sont rafraîchies toutes les heures aux horaires d'ouverture du marché.
Actions (equities)
# Action spécifique GET /api/v1/markets/brvm/SNTS # Toutes les actions cotées GET /api/v1/markets/brvm/ALL
| Champ | Type | Description |
|---|---|---|
ticker | string | Symbole boursier (ex: SNTS, BOAB) |
name | string | Nom de la société |
last_price | number | Dernier cours en XOF |
prev_close | number | Cours de clôture de la veille |
open | number | Cours d'ouverture |
change | number | Variation absolue en XOF |
change_pct | number | Variation en pourcentage |
volume | integer | Volume de titres échangés |
Obligations (bonds)
GET /api/v1/markets/brvm/ALL/bonds
Indices
GET /api/v1/markets/brvm/ALL/indices
Retourne les trois indices BRVM : BRVM Composite, BRVM 30, BRVM Prestige.
Cryptomonnaies
Données issues de CoinGecko. Couvre le top 500 par capitalisation boursière. Rafraîchissement toutes les 5 minutes.
# Crypto spécifique GET /api/v1/markets/crypto/BTC GET /api/v1/markets/crypto/ETH # Top 500 complet GET /api/v1/markets/crypto/ALL
| Champ | Type | Description |
|---|---|---|
ticker | string | Symbole (BTC, ETH, SOL...) |
name | string | Nom complet |
last_price | number | Prix en USD |
high_24h | number | Plus haut sur 24h |
low_24h | number | Plus bas sur 24h |
change_pct_24h | number | Variation 24h en % |
volume_24h | number | Volume 24h en USD |
market_cap | number | Capitalisation boursière USD |
rank | integer | Rang par capitalisation |
Forex
160+ paires de devises dont XOF, XAF, GHS, NGN et toutes les devises africaines majeures. Rafraîchissement toutes les 5 minutes.
# Dollar → Franc CFA GET /api/v1/markets/forex/USDXOF # Euro → Dirham marocain GET /api/v1/markets/forex/EURMAD # Toutes les devises (base USD) GET /api/v1/markets/forex/ALL
USDXOF = 1 USD exprimé en XOF.
| Champ | Type | Description |
|---|---|---|
pair | string | Paire (ex: USD/XOF) |
base | string | Devise de base |
quote | string | Devise de cotation |
rate | number | Taux de conversion |
quote_name | string | Nom complet de la devise de cotation |
Stocks
Actions mondiales via Yahoo Finance (NYSE, NASDAQ, LSE, Euronext...). Le screener couvre dynamiquement les 300+ titres les plus actifs. Tout ticker Yahoo Finance est accepté.
# Actions américaines GET /api/v1/markets/stocks/AAPL GET /api/v1/markets/stocks/TSLA # ADR africain GET /api/v1/markets/stocks/MTN # Top 300 actifs du moment GET /api/v1/markets/stocks/ALL
| Champ | Type | Description |
|---|---|---|
ticker | string | Symbole Yahoo Finance |
name | string | Nom de la société |
last_price | number | Dernier cours |
change_pct | number | Variation journalière en % |
volume | number | Volume journalier |
market_cap | number | Capitalisation boursière |
exchange | string | Place boursière |
Matières premières
16 contrats futures couvrant métaux précieux, énergie, céréales et soft commodities. Le cacao, le café et le coton sont inclus en priorité pour leur importance en Afrique de l'Ouest.
# Or GET /api/v1/markets/commodities/GOLD # Cacao (pertinent CI, Ghana) GET /api/v1/markets/commodities/COCOA # Toutes les matières premières GET /api/v1/markets/commodities/ALL
| Ticker | Nom | Unité | Secteur |
|---|---|---|---|
GOLD | Or | troy_oz | Métaux précieux |
SILVER | Argent | troy_oz | Métaux précieux |
BRENT | Brent Crude Oil | barrel | Énergie |
WTI | WTI Crude Oil | barrel | Énergie |
GAS | Natural Gas | MMBtu | Énergie |
COPPER | Cuivre | lb | Métaux industriels |
COCOA | Cacao | metric_ton | Softs |
COFFEE | Café | lb | Softs |
SUGAR | Sucre | lb | Softs |
COTTON | Coton | lb | Softs |
CORN | Maïs | bushel | Céréales |
WHEAT | Blé | bushel | Céréales |
OPCVM — Fonds NSIA Invest
Valeurs liquidatives des fonds OPCVM gérés par NSIA Invest (SGO agréée UEMOA). Les VL sont publiées une fois par jour ouvré et servies depuis un cache rafraîchi automatiquement — l'API ne sollicite jamais NSIA sur une requête client, garantissant une réponse rapide et stable.
# Un fonds précis (par identifiant produit) GET /api/v1/markets/opcvm/45 # Tous les fonds OPCVM GET /api/v1/markets/opcvm
| Champ | Type | Description |
|---|---|---|
ticker | string | Identifiant normalisé du fonds |
nav | number | Valeur liquidative (VL) courante |
last_price | number | Alias de la VL (cohérence multi-marchés) |
nav_date | string | Date de la VL (AAAA-MM-JJ) |
prev_nav | number | VL précédente (calcul de variation) |
currency | string | Devise (XOF) |
market:read avec le marché opcvm autorisé sur votre clé.
API d'ordres — Vue d'ensemble
Au-delà des données de marché, l'API permet de placer des ordres et de consulter les portefeuilles de vos clients finaux. Ces opérations partagent la même base URL /api/v1 et la même clé que les données de marché — seuls les scopes diffèrent.
Deux familles d'opérations distinctes :
| Famille | Préfixe | Nature | Scope |
|---|---|---|---|
| Données de marché | /markets | Lecture des prix | market:read |
| Placement d'ordres | /orders | Exécution (écriture) | orders:trade |
| Consultation de compte | /accounts | Portefeuille, historique | orders:read |
Devis (quote)
Obtenez un devis avant d'engager un ordre : frais du courtier et référence de prix. Le devis n'engage pas. Requiert le scope orders:read.
| Champ | Type | Requis | Description |
|---|---|---|---|
asset_type | string | Oui | marché — ex. opcvm |
asset_ref | string | Oui | identifiant de l'actif |
side | string | Oui | BUY ou SELL |
amount | number | Oui | montant en XOF, entier > 0 |
# Devis pour une souscription OPCVM de 100 000 XOF
POST /api/v1/quotes
Content-Type: application/json
{
"asset_type": "opcvm",
"asset_ref": "45",
"side": "BUY",
"amount": 100000
}
Ouverture de compte
Certains marchés exigent qu'un compte client soit créé chez le courtier avant tout ordre (KYC réglementaire). C'est le cas de l'OPCVM. Requiert le scope orders:trade. Le profil est transmis dans un vocabulaire neutre ; l'API le traduit vers le format du courtier.
Corps — niveau racine
| Champ | Type | Requis | Description |
|---|---|---|---|
asset_type | string | Oui | marché — ex. opcvm |
profile | object | Oui | profil du client (détaillé ci-dessous) |
profile — identité
| Champ | Type | Requis | Description / format |
|---|---|---|---|
first_name · last_name | string | Oui | prénom · nom (≤ 100 car.) |
email | string | Oui | adresse e-mail (≤ 100) |
phone | string | Oui | numéro local sans indicatif (≤ 10) |
phone_code | string | Oui | indicatif avec + — ex. +225 |
title | string | Oui | civilité — M / Mme |
gender | string | Oui | sexe — M / F |
birth_date | string | Oui | date de naissance — AAAA-MM-JJ |
birth_place | string | Oui | lieu de naissance |
nationality | string | Oui | nationalité |
residence_country · city | string | Oui | pays de résidence · ville |
address | string | Oui | adresse géographique |
profession | string | Oui | profession |
profile.kyc — conformité
| Champ | Type | Requis | Description |
|---|---|---|---|
marital_status | string | Oui | situation matrimoniale |
marital_regime | string | Non | régime matrimonial |
politically_exposed | string | Oui | personne politiquement exposée — Oui/Non |
professional_status | string | Oui | situation professionnelle |
activity_sector | string | Oui | secteur d'activité |
funds_origin | string | Oui | origine des fonds |
judicial_record | string | Oui | antécédents (anti-blanchiment) |
us_resident | string | Oui | résident américain — Oui/Non |
tax_obligation | string | Oui | obligations fiscales |
main_objective | string | Oui | objectif principal du placement |
investment_horizon | string | Oui | horizon de placement |
profile.documents[] — pièces justificatives
| Champ | Type | Requis | Description |
|---|---|---|---|
type | string | Oui | type — ex. CNI RECTO, CNI VERSO, PASSEPORT, JUSTIFICATIF DE DOMICILE, SELFIE, SIGNATURE 1 CLIENT |
content_base64 | string | Oui | fichier encodé en Base64 |
extension | string | Oui | extension — ex. jpg, png, pdf |
number | string | Non | numéro du document |
POST /api/v1/accounts
X-API-Key: es_live_votre_cle
Content-Type: application/json
{
"asset_type": "opcvm",
"profile": {
"first_name": "Landry",
"last_name": "Fofana",
"email": "landry@example.com",
"phone": "0757534697",
"phone_code": "+225",
"title": "M",
"gender": "M",
"birth_date": "1990-01-01",
"birth_place": "Abidjan",
"nationality": "Ivoirienne",
"residence_country": "Côte d'ivoire",
"city": "Abidjan",
"address": "Marcory Rue 22",
"profession": "Ingénieur",
"kyc": {
"marital_status": "Célibataire",
"funds_origin": "Salaire",
"politically_exposed": "Non",
"us_resident": "Non",
"investment_horizon": "Long terme",
"main_objective": "Épargne"
},
"documents": [
{ "type": "CNI RECTO", "extension": "jpg", "number": "C-123", "content_base64": "..." },
{ "type": "CNI VERSO", "extension": "jpg", "number": "C-123", "content_base64": "..." }
]
}
}
{
"status": "success",
"account": {
"account_ref": "1691",
"status": "PENDING"
}
}
Le champ account_ref renvoyé est l'identifiant à réutiliser comme end_user_ref lors du placement d'ordres. Statuts possibles : ACTIVE, PENDING, BLOCKED, UNKNOWN.
documents[] porte le fichier encodé en Base64 dans content_base64. Types attendus selon le courtier : justificatif de domicile, CNI recto/verso ou passeport, selfie, signatures.
Placer un ordre
Crée et soumet un ordre au courtier. Requiert le scope orders:trade et le header Idempotency-Key — une même clé d'idempotence ne crée jamais deux ordres (garantie anti-double-souscription).
ACTIVE chez le courtier. Créez-le d'abord via Ouverture de compte. Un ordre pour un compte inexistant ou non actif est refusé.
En-têtes
| En-tête | Requis | Description |
|---|---|---|
X-API-Key | Oui | votre clé API |
Idempotency-Key | Oui | identifiant unique de la requête ; rejouer la même clé ne recrée pas d'ordre |
Content-Type | Oui | application/json |
Paramètres du corps
| Champ | Type | Requis | Description / format |
|---|---|---|---|
asset_type | string | Oui | marché ciblé — ex. opcvm |
asset_ref | string | Oui | identifiant de l'actif (pour OPCVM : l'id du fonds) |
side | string | Oui | BUY (souscription) ou SELL (rachat) |
amount | number | Oui | montant en XOF, entier > 0 |
end_user_ref | string | Cond. | référence du compte client — obligatoire si le marché exige un compte |
meta.type_rachat | string | Non | SELL uniquement — PARTIEL (défaut) ou TOTAL |
payment | object | Oui | détails du paiement déjà encaissé (voir ci-dessous) |
payment.moyenPaiement | string | Oui | opérateur — ex. mtn, orange, moov, wave |
payment.montantAPayer | number | Cond. | BUY — montant + frais (souvent ≥ amount) |
payment.telephone | string | Cond. | BUY — téléphone du payeur |
payment.numeroCompte | string | Cond. | SELL — numéro de compte à créditer |
payment.reference | string | Oui | référence partenaire (traçabilité / rapprochement) |
# Le partenaire a déjà encaissé : il fournit les détails de paiement
POST /api/v1/orders
X-API-Key: es_live_votre_cle
Idempotency-Key: cmd-2026-0042
Content-Type: application/json
{
"asset_type": "opcvm",
"asset_ref": "45",
"side": "BUY",
"amount": 100000,
"end_user_ref": "1188",
"payment": {
"moyenPaiement": "mtn",
"montantAPayer": 101500,
"telephone": "0757534697",
"reference": "cmd-2026-0042"
}
}
{
"status": "success",
"order": {
"id": "ord_a1b2c3d4e5",
"asset_type": "opcvm",
"side": "BUY",
"amount": 100000,
"state": "SUBMITTED",
"provider": "opcvm",
"provider_ref": "SUB-99871"
}
}
Les états d'un ordre suivent un cycle universel, quel que soit le marché :
| État | Signification |
|---|---|
RECEIVED | Reçu et validé, pas encore soumis |
SUBMITTED | Transmis au courtier |
EXECUTING | En cours de traitement |
SETTLED | Exécuté avec succès |
REJECTED / FAILED | Refusé / échoué |
CANCELLED | Annulé avant soumission |
Suivre & annuler un ordre
Deux mécanismes de suivi : interrogation directe (polling) et webhooks (poussés vers votre webhook_url à chaque changement d'état).
# État d'un ordre (rafraîchi depuis le courtier) GET /api/v1/orders/ord_a1b2c3d4e5 # Annuler (si le courtier et l'état le permettent) POST /api/v1/orders/ord_a1b2c3d4e5/cancel
Comptes & portefeuille
Consultez le compte, l'historique et le portefeuille d'un client final. Requiert le scope orders:read. Les données sont exposées dans un vocabulaire neutre commun à tous les courtiers : votre application affiche un portefeuille sans connaître le courtier sous-jacent.
Paramètres de requête (query)
| Paramètre | Type | Requis | Description |
|---|---|---|---|
asset_type | string | Oui | marché ciblé — ex. opcvm |
page | number | Non | historique uniquement — numéro de page |
limit | number | Non | historique uniquement — éléments par page |
Le segment {ref} de l'URL est la référence du compte client (l'account_ref obtenu à l'ouverture de compte).
# Rechercher un compte GET /api/v1/accounts/1188?asset_type=opcvm # Historique des ordres du client GET /api/v1/accounts/1188/history?asset_type=opcvm # Portefeuille détaillé (positions, valorisation, plus-value) GET /api/v1/accounts/1188/portfolio?asset_type=opcvm # Portefeuille global (performance + courbe d'évolution) GET /api/v1/accounts/1188/summary?asset_type=opcvm
Chaque position du portefeuille est décrite avec des champs neutres :
| Champ | Description |
|---|---|
asset_ref | Référence de l'actif détenu |
asset_name | Nom affichable |
quantity | Quantité détenue (parts, unités…) |
avg_price | Prix moyen d'acquisition |
current_price | Prix courant unitaire |
invested_amount | Montant investi |
current_value | Valeur actuelle |
pnl | Plus/moins-value |
currency | Devise |
Le portefeuille global (/summary) agrège l'ensemble et fournit la performance et la courbe d'évolution, prête à tracer :
| Champ | Description |
|---|---|
total_value | Valeur nette totale du portefeuille |
performance | Performance globale |
percentage | Pourcentage d'évolution |
pnl | Plus-value totale |
chart | Série de valeurs (évolution, 90 j par défaut) |
chart_data | Série datée : [{ "value", "date" }] pour un graphe |
currency | Devise |
Format de réponse
Toutes les réponses suivent la même enveloppe JSON, quel que soit le type d'asset demandé.
{
"status": "success", // "success" ou "error"
"message": "OK",
"request": { // Echo des paramètres envoyés
"type": "brvm",
"asset": "SNTS",
"category": "equities"
},
"meta": { // Informations sur la source
"source": "brvm.org",
"updated_at": "2026-04-07T08:00:00Z",
"currency": "XOF",
"category": "equities"
},
"cache": { // État du cache
"hit": true, // true = servi depuis le cache
"age_sec": 312 // Âge du cache en secondes
},
"data": { /* ... données de l'asset ... */ }
}
Système de cache
L'API utilise un système de cache fichier JSON côté serveur. Les données sont précachées par un processus cron en arrière-plan, ce qui garantit des réponses rapides même pour les assets très demandés.
| Type | TTL du cache | Rafraîchissement |
|---|---|---|
| BRVM | 60 minutes | Aux heures de marché (Lu–Ve) |
| Crypto | 5 minutes | Continu |
| Forex | 5 minutes | Continu |
| Stocks | 15 minutes | Aux heures de marché |
| Commodities | 15 minutes | Continu |
cache.hit: true indique une réponse servie depuis le cache (temps de réponse < 50 ms). Un cache.hit: false indique un fetch en direct depuis la source (~500 ms–2 s).
Plans & limites
| Fonctionnalité | Starter | Pro | Enterprise |
|---|---|---|---|
| BRVM | ✅ | ✅ | ✅ |
| Crypto | ❌ | ✅ | ✅ |
| Forex | ❌ | ✅ | ✅ |
| Stocks | ❌ | ❌ | ✅ |
| Commodities | ❌ | ❌ | ✅ |
| Rate limit | 100 req/h | 500 req/h | 2 000 req/h |
| Historique SQL | ❌ | 90 jours | Illimité |
| Whitelist IP | ❌ | ❌ | ✅ |
| Support | Prioritaire | Dédié + SLA |
Demander une clé API
Remplissez le formulaire ci-dessous. Vous recevrez votre clé API ainsi que l'endpoint d'accès sous 24h ouvrées.
© 2026 e-sotop services · Dakar, Sénégal · Retour à l'accueil