# Basile API > Base de données B2B française. Sociétés : 26 758 354 au registre légal, dont 12 878 867 au statut > ACTIF — c'est ce dernier chiffre qui compte pour un ciblage ; s'y ajoutent 5 458 086 fiches Google > My Business et 5 276 024 pages LinkedIn d'entreprises. Contacts : 20 825 880 dirigeants au registre > et 28 916 355 profils LinkedIn de personnes. Une recherche interroge les sources concernées puis > réunit les résultats, donc un total peut dépasser le volume d'une source prise seule. > API REST sur https://api.basile.cc. > Auth : header `Authorization` avec la clé API brute (PAS de préfixe `Bearer`), `Content-Type: application/json`. ## Ressources machine-readable - [Spécification OpenAPI (YAML)](/openapi.yaml) : tous les endpoints, filtres, schémas de requête/réponse. - [Skill Claude (ZIP)](/basile-skill.zip) : skill prête à l'emploi (recherche, comptage, export, enrichissement). - [Référence skill (JSON)](/skill-reference.json) : métadonnées de la skill. ## Endpoints clés - `POST /people/find` — chercher/compter des personnes (body `{ filters, limit, countOnly, paginationToken }`). `total` = nombre de résultats. **Compter est gratuit ; récupérer les enregistrements est décompté de votre forfait** (voir Facturation). - `POST /companies/find` — chercher des entreprises. Renvoie `total` (sociétés dédupliquées) et `establishmentsTotal` (points de vente / fiches Google). - `POST /people/export` · `POST /companies/export` — export CSV (companies : param `mode` = `"companies"` | `"locations"`). Consomme du quota. - `GET /companies/activity-suggest?q=` — IDs de concept unifiés pour le filtre `activity` (métier/secteur, people ET companies). ## find vs export : ce que chacun renvoie (IMPORTANT) Les deux acceptent exactement les mêmes `filters`. La différence est la **richesse des données**. - **PERSONNES — `/people/find` renvoie la personne, PAS sa société.** Vous obtenez son identité, sa localisation, son poste, son URL LinkedIn, plus le **nom** et l'**identifiant interne** de son employeur. Vous n'obtenez **pas** les données de cette société : ni SIREN/NAF/forme juridique (Legal), ni effectif/secteur/description (LinkedIn), ni note/avis/adresse (Google Maps). - **PERSONNES — `/people/export` renvoie la ligne complète : 79 colonnes.** 22 sur la personne, **18 sur sa société LinkedIn**, **18 sur sa société au registre légal**, **11 Google Maps**, 6 drapeaux de présence. Pour UNE fiche, `GET /people/{id}/full` rend le même modèle sans passer par un export. - **ENTREPRISES — `/companies/find` croise DÉJÀ les trois sources.** Chaque résultat porte sa fiche plus, quand la correspondance existe, les données des deux autres sources sous `x_legal` / `x_lki` / `x_gmb`. Contrairement aux personnes, il n'est pas nécessaire d'exporter pour voir les trois sources. - **ENTREPRISES — `/companies/export` renvoie 57 colonnes** : les mêmes données mises à plat en CSV (18 Legal, 11 Google Maps, le reste LinkedIn + identité + drapeaux). **Règle pratique** : pour des contacts avec le contexte de leur entreprise, `/find` sert à cibler et à compter, puis **c'est `/export` qui produit la donnée exploitable**. ## Facturation - **Compter est gratuit, sans limite.** Envoyez `{ "countOnly": true }` (ou `limit: 0`) : la réponse contient `total` et un tableau `leads` vide. **Aucun débit.** - **Récupérer des enregistrements coûte 1 crédit par enregistrement renvoyé** — sur `/find` (hors mode count-only), sur `/people/{id}` et `/companies/{id}`, et sur `/export`. Le débit a lieu **à chaque appel** : redemander les mêmes enregistrements est **re-facturé** (la donnée a pu être rafraîchie entre-temps ; il n'y a pas de registre « déjà payé »). - ⚠️ `limit: 1` n'est **pas** un mode de comptage : il renvoie 1 enregistrement, donc 1 crédit. Pour compter, utilisez `countOnly: true`. - Quota épuisé → **402** `quota_exhausted`, renvoyé **avant** les enregistrements (rien n'est livré, rien n'est débité). - **Gratuit et non concerné** : la navigation web (session) et l'extension Basile. Seules les clés API externes sont facturées — la skill Claude passant par une clé API, elle est facturée. - **Le serveur MCP est facturé comme une clé API.** Il exige un plan avec accès API (sinon `403 api_plan_required`) et consomme 1 crédit par enregistrement rendu, exactement comme un appel REST. Seul `basile_count` reste gratuit. - Méthode recommandée : `countOnly` pour cadrer le volume, puis un `/export` ciblé. ## MCP (serveur distant) - URL : `https://mcp.basile.cc/mcp` (endpoint `POST /mcp`), authentification **OAuth** avec un compte Basile ; aucune clé n'est stockée. - Outils exposés : `basile_count`, `basile_search_people`, `basile_search_companies`, `basile_activity_suggest`, `basile_suggest`, `basile_get_entity`, `basile_export`, `basile_export_status`. - `basile_export` a deux chemins, choisis automatiquement selon le volume. Jusqu'à **500 lignes**, le CSV est renvoyé INLINE dans la conversation. Au-delà, l'outil lance un export FICHIER (construit hors requête, déposé sur S3) et renvoie un `jobId` ; `basile_export_status` rend ensuite un **lien de téléchargement direct valable ~1 h**, avec `truncated` / `quotaReached` s'il y a lieu. Le plafond n'est donc pas 500 lignes mais celui du plan (20 000 lignes par export en plan API, 50 000 en Agence). Le fichier reste récupérable dans l'application web, onglet Exports. - Mêmes filtres, mêmes quotas et même facturation que l'API REST (voir Facturation) : **un plan avec accès API est requis**. ## Règles d'appel qui font échouer une intégration si on les ignore - **Au moins un filtre EFFECTIF est obligatoire** avec une clé d'API, sinon `400 {"error":"At least one filter is required."}`. Ne comptent pas : `filters` vide, `{"include":[]}`, `null`, `""`, une clé inconnue, et `source` seul. La garde s'applique à `/people/find`, `/companies/find`, aux deux `/export` et à `/companies/identifiers`. - **`total` est plafonné à 100 000** sur un `/find` par clé d'API qui renvoie des enregistrements : c'est un PLANCHER, pas le compte réel, et `meta.countCapNotice` le signale. Seul `countOnly: true` rend le compte non plafonné. - **La pagination s'arrête à 250 000 enregistrements par recherche.** Au-delà, `pagination.nextToken` DISPARAÎT sans erreur : une boucle « tant que nextToken » se termine normalement en ayant tronqué l'extraction. Pour un volume supérieur, découpez la recherche (par département, par tranche d'effectif…). - **Codes d'erreur** : `400` aucun filtre effectif · `401` clé absente ou invalide · `402` trois causes distinguées par le champ `error` (`quota_exhausted` = crédits mensuels épuisés, `export_quota_exhausted` = quota d'export épuisé, `subscription_required` = abonnement requis pour les pages > 1) · `403` plan API requis · `429` rate limit, avec `Retry-After` · `503` moteur de recherche saturé, avec `Retry-After`. Les 402 de quota ne sont PAS des rate limits : rien à attendre avant le mois suivant. ## Notes de filtrage - Filtre texte = `{ "include": [...], "exclude": [...] }` (include = OR, exclude = NOT) ; plusieurs filtres = ET. - `activity` fonctionne directement sur `/people/find` (secteur de l'entreprise de la personne). - `company_headcount` (plage) fonctionne lui aussi directement sur `/people/find` : c'est la TAILLE de l'entreprise actuelle du contact, multi-source (effectif exact du registre légal + bande déclarée LinkedIn). **N'enchaînez pas `/companies/find` puis `/people/find` pour filtrer par secteur ou par taille** : `activity` et `company_headcount` font les deux en une seule requête. Le détour par les entreprises n'est utile que pour partir d'une liste d'entreprises nommées ou de fiches Google. - ⚠️ Demander `limit: 500` et n'en recevoir que 20 ne coûte rien : la facturation porte sur les enregistrements **renvoyés**, pas demandés. - France : `result_country_code` (people) / `headquarters_country_code` (companies) = `{ "include": ["FR"] }`. - Géographie : `region` prend le NOM canonique (« Auvergne-Rhône-Alpes ») et fonctionne sur les trois sources. `headquarters_department_code` prend le numéro (« 69 ») mais n'existe que sur la source Legal : l'utiliser restreint la recherche au registre. `headquarters_region_code` est IGNORÉ (no-op, aucun résolveur) — ne l'utilisez pas. - Un filtre mono-source ne restreint la recherche à sa source que si TOUS vos filtres mono-source viennent de la même. En combiner de deux sources donne une UNION, pas une intersection : chaque source ne porte que ses propres filtres. Regardez `meta.noticeCode` : `sources_split`, ou `gmb_filter_dropped` quand le filtre Google (note, avis, ouvert le dimanche) a dû être abandonné et n'a donc rien filtré. - ⚠️ `/people/find` dont `siren` est le SEUL filtre emprunte un raccourci de lecture directe et ne renvoie que les dirigeants du REGISTRE, pas les salariés LinkedIn — alors que le même appel en `countOnly` compte les deux sources. Ajoutez un second filtre pour obtenir les deux. - ⚠️ Piège de vocabulaire : sur `/people/find`, `with_legal_data` et `with_linkedin_profile` **restreignent la source** (équivalents à `source`). Sur `/companies/find`, `with_legal_data`, `with_linkedin_page`, `with_email` et `with_phone` sont des **filtres ET** : ils gardent les entreprises qui ont AUSSI cette donnée, sans changer les sources interrogées. Même vocabulaire, comportement opposé. - `with_phone` (companies) désigne un numéro d'ENTREPRISE (standard Google Maps ou numéro du site), jamais le mobile d'une personne. La source LinkedIn n'y répond pas encore et renvoie 0.