Free100Leads
API
Dernière mise à jour 19 August 2026
Obtenir une clé
Les clés se créent dans votre compte et s’affichent une seule fois. Nous stockons un hachage, donc personne ne peut la retrouver ensuite, nous compris. Perdue, vous en créez une autre. La révocation est immédiate.
Une clé ressemble à f100_live_…. Ce préfixe est fixe pour que les scanners de secrets la reconnaissent si elle atteint un dépôt public. Traitez-la comme un mot de passe : côté serveur uniquement, jamais dans un navigateur, jamais dans une app mobile.
Faire une requête
Tout vit sous https://api.free100leads.com/v1. Envoyez la clé comme jeton bearer.
curl "https://api.free100leads.com/v1/search?country=DE&industry_id=4&limit=100" \ -H "Authorization: Bearer f100_live_..."
Chercher
GET /v1/search demande au moins un parmi country, industry_id ou size_bucket. C’est le même plancher que le site : impossible de tout demander.
| Parameter | Meaning |
|---|---|
| country | ISO-3166 alpha-2, e.g. DE |
| region | US state name, lowercase. Only meaningful with country=US |
| industry_id | From /v1/facets |
| size_bucket | 1 (1-10) through 8 (10001+) |
| contact | email or phone, to require that channel |
| title | Job title contains this text |
| limit | Up to 500 a page |
| cursor | From the previous response |
{
"data": [
{
"name": "…",
"job_title": "…",
"company": "…",
"email": "…",
"phone": "…",
"city": "…",
"region": null,
"country": "DE",
"industry": "computer software",
"company_size": "51-200"
}
],
"next_cursor": "c_…",
"exhausted": false,
"usage": { "records_used": 4210, "records_included": 100000, "period_end": "…" }
}La pagination, et pourquoi il n’y a pas de numéro de page
Gardez le next_cursor et renvoyez-le pour continuer. Vous ne recevez jamais deux fois le même enregistrement dans une recherche, jusqu’à ce que exhausted revienne à true.
Le curseur est signé et lié à votre compte et aux filtres exacts utilisés. Un curseur émis pour une recherche allemande sera refusé pour une française, et un émis pour un autre compte sera refusé pour le vôtre. Omettez-le pour démarrer une nouvelle recherche.
Il n’y a délibérément aucun moyen de demander un enregistrement par id, ni de paramètre offset. Les deux permettraient de parcourir toute la base en parallèle, ce que ce design existe pour empêcher.
Les autres endpoints
| Endpoint | What it gives you |
|---|---|
| GET /v1/facets | Every country, industry and size you can filter on, with counts |
| GET /v1/usage | Records used and left this period, and today |
| GET /v1/me | Which key this is, which plan, and its limits |
Ne pas acheter deux fois le même contact
Deux choses distinctes empêchent un enregistrement de vous parvenir deux fois.
Dans une recherche, le curseur est la garantie. Le parcours n’avance que vers l’avant : paginer une recherche ne peut pas rendre un enregistrement déjà donné, quel que soit le nombre de pages. Il ne demande rien d’autre que de renvoyer next_cursor .
Entre exports, un registre est la garantie. Chaque ligne sortie en CSV est inscrite à votre compte. Les exports suivants la sautent, et /v1/search cesse de la renvoyer : un contact déjà emporté ne réapparaît pas dans une recherche deux mois après, et n’atterrit pas deux fois dans votre CRM.
Les enregistrements comptent sur votre plan à la livraison : à l’écran, dans une réponse API ou dans un fichier en masse. Le registre de suppression se remplit par les exports, pas par les recherches. L’endpoint en masse saute toujours les enregistrements déjà inscrits.
Un enregistrement entre au registre quand il sort en fichier, pas quand il apparaît dans une réponse de recherche. Dans une recherche, le curseur garantit l’absence de doublons. Entre deux recherches aux filtres qui se recouvrent, un enregistrement vu mais jamais exporté peut revenir. exhausted marque la fin d’une recherche.
Le registre appartient au compte et non à une clé : toutes les clés et l’app web lisent et écrivent le même, et il n’expire pas. Un enregistrement exporté en mars reste supprimé en décembre. Pour retrouver une liste perdue, le téléchargement CSV du tableau de bord accepte include_exported=true, et cela ne vous facture pas de nouveau. Ces enregistrements ont été comptés à leur première livraison.
Limites
Ces chiffres sont publiés ici pour que vous ne les découvriez jamais en production.
| Limit | Growth | Scale |
|---|---|---|
| Records a month | 100,000 | 1,500,000 |
| Records a day | 10,000 | 50,000 |
| Records an hour | 5,000 | 25,000 |
| Requests a minute | 25 | 60 |
| Requests in flight | 2 | 4 |
| Keys | 3 | 10 |
Chaque réponse porte RateLimit-Limit, RateLimit-Remaining et RateLimit-Reset. Un 429 porte aussi Retry-After en secondes. L’usage compte les enregistrements réellement reçus, jamais ceux demandés.
Les limites quotidiennes montent au plein rythme du plan pendant votre première semaine. Les totaux mensuels ne sont jamais réduits.
Erreurs
{
"error": {
"type": "rate_limited",
"message": "60 requests a minute is the limit on this plan.",
"retry_after": 12,
"docs": "https://free100leads.com/docs/api#rate_limited"
}
}| Type | Status | What to do |
|---|---|---|
| invalid_request | 400 | Fix the parameters. Retrying unchanged will not help |
| unauthorized | 401 | The key is wrong, revoked or missing |
| quota_exhausted | 402 | Out of records. Deliberately not a 429, because backing off will not fix a billing state. Wait for the reset or upgrade |
| forbidden | 403 | The plan or the key does not carry this |
| not_found | 404 | No such endpoint or resource. Check the path |
| rate_limited | 429 | Slow down. Honour Retry-After |
| server_error | 500 | Ours. Retry with backoff, and tell us if it persists |
Ce que vous pouvez faire des données
Les enregistrements sont licenciés pour votre propre prospection. Ne les revendez pas, ne les republiez pas, ne les intégrez pas à un produit que vous vendez. Les enregistrements livrés portent des marqueurs traçables liés à la clé qui les a obtenus : une liste qui refait surface ailleurs peut être remontée jusqu’au compte d’origine. Les conditions le disent en entier.
MCP
Pointez Claude, Codex ou tout autre agent compatible MCP vers https://api.free100leads.com/v1/mcp avec la même clé. Il parle JSON-RPC sur HTTP et offre trois outils : search_leads, get_facets et get_usage. Ils exécutent le même code que les endpoints ci-dessus : un agent a le même quota, les mêmes limites et les mêmes règles de curseur. Aucun quota séparé à surveiller.
La plupart des clients MCP utilisent un bloc de configuration comme celui-ci, avec votre propre clé à la place du texte de remplacement :
{
"mcpServers": {
"free100leads": {
"url": "https://api.free100leads.com/v1/mcp",
"headers": { "Authorization": "Bearer f100_live_..." }
}
}
}Webhooks
Enregistrez une recherche, attachez un endpoint, et les nouveaux résultats y sont postés à mesure. Chaque livraison porte x-f100-timestamp et x-f100-signature. Vérifiez la signature avec le secret montré à la création de l’endpoint, et rejetez tout ce qui a plus de cinq minutes. Un récepteur qui ne distingue pas notre POST d’un autre a un endpoint ouvert.
Les échecs reculent et réessaient. Dix échecs consécutifs éteignent l’endpoint et l’erreur apparaît sur votre page de compte : une URL morte cesse d’être réessayée pour toujours.
Ce qui manque volontairement
L’enrichissement, c’est-à-dire chercher une personne par son email, n’est pas proposé. La consultation directe d’un individu déferait le design anti-abus de toute l’API.
Il vous manque quelque chose ? Le formulaire de contact arrive à une personne.