Documentation
API REST
Lisez vos leads, lancez des scrapes et ingérez depuis vos outils existants. L'API tourne sur la même infrastructure que le dashboard, avec la même quota mensuelle.
Authentification
Toutes les requêtes nécessitent un header Authorization: Bearer sa_live_…. Générez une clé depuis Paramètres → API.
Chaque clé porte un ou plusieurs scopes : leads:read · jobs:read · jobs:write. Une requête sans le bon scope renvoie 403 Forbidden.
curl https://crawlswarm.com/api/v1/leads \ -H "Authorization: Bearer sa_live_<48hex>" \ -H "Content-Type: application/json"
GET /api/v1/leads
Liste paginée des leads de l'utilisateur, du plus récent au plus ancien. Scope requis : leads:read.
limit | 1–100, défaut 50. |
cursor | Timestamp ISO 8601 d'un lead précédemment renvoyé (next_cursor). Renvoie les leads scrapés strictement avant. |
status | Filtre exact : new · contacted · no_reply · won · lost · disqualified. |
{
"data": [
{
"id": "lead_abc123",
"name": "Boulangerie Émile",
"city": "Rouen",
"phone": "0235038884",
"email": "contact@emile.fr",
"score": 78,
"status": "new",
"tags": [],
"credits_total": 1.5,
"scraped_at": "2026-05-10T08:30:00.000Z"
}
],
"pagination": { "next_cursor": "2026-05-10T08:29:43.000Z", "limit": 50 }
}POST /api/v1/leads
Ingère un ou plusieurs leads sans passer par un scrape Maps. Chaque lead consomme 1 crédit de base. Scope : jobs:write. Maximum 100 leads par requête.
lead | Objet unique : { name, city, … } |
leads | Tableau d'objets, max 100. |
Champs obligatoires par lead : name et city. Optionnels :address, phone, email, website, postal_code, tags.
curl -X POST https://crawlswarm.com/api/v1/leads \
-H "Authorization: Bearer sa_live_<48hex>" \
-H "Content-Type: application/json" \
-d '{
"leads": [
{ "name": "Boulang. X", "city": "Rouen", "email": "contact@x.fr" },
{ "name": "Plomberie Y", "city": "Lille", "phone": "0612345678" }
]
}'{
"ingested": 2,
"job_id": "job_d3f8a1",
"leads": [
{ "id": "lead_abc", "name": "Boulang. X" },
{ "id": "lead_def", "name": "Plomberie Y" }
]
}GET /api/v1/jobs
Historique des tâches (Maps + imports + ingest API). Mêmes paramètres que /api/v1/leads. Scope : jobs:read.
POST /api/v1/jobs
Lance un scrape Maps. Renvoie immédiatement { id, status: "queued" } — un worker prend le job dans les secondes qui suivent. Scope : jobs:write.
curl -X POST https://crawlswarm.com/api/v1/jobs \
-H "Authorization: Bearer sa_live_<48hex>" \
-H "Content-Type: application/json" \
-d '{
"query": "boulangeries",
"city": "Rouen",
"max_leads": 30,
"enrichment_options": {
"siren": true,
"social": true,
"emailPerso": true
},
"require_filters": { "social": true }
}'Webhooks (sortants)
Configurés depuis Paramètres → Webhooks. Trois événements :
lead.created— un lead vient d'être inséré (scrape ou import).job.completed— une tâche se termine avec succès.job.failed— une tâche tombe en erreur.
Chaque envoi inclut une signature HMAC-SHA256 dans le header X-Crawlswarm-Signature: t=<ts>,v1=<hex> calculée sur $`${ts}.${rawBody}` avec le secret du webhook.
// Vérification côté receveur (Node)
import { createHmac, timingSafeEqual } from "node:crypto";
function isValid(rawBody, header, secret) {
const m = /t=(\d+),v1=([a-f0-9]+)/.exec(header);
if (!m) return false;
const [, ts, sig] = m;
// Reject older than 5 min to prevent replay attacks.
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = createHmac("sha256", secret)
.update(`${ts}.${rawBody}`)
.digest("hex");
return timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}Quotas & rate limits
Le quota mensuel est partagé entre dashboard et API. Une requête qui ferait dépasser le quota renvoie 402 Payment Required avec quota_remaining dans le corps.
Pas de rate limit dur en V0, mais le serveur se réserve le droit de 429en cas d'abus. Recommandé : ≤ 5 requêtes / seconde.
Codes d'erreur
400 | Body invalide ou champs requis manquants. |
401 | Header Bearer absent ou clé inconnue. |
403 | La clé n'a pas le scope requis. |
402 | Quota mensuel atteint. |
429 | Rate limit (rare en V0). |
5xx | Erreur serveur — retry exponentiel recommandé. |
Dernière mise à jour : 10 mai 2026 · Questions : contact@initial-infrastructures.com