La référence de l’API.
Une clé par outil, des droits choisis un à un : lire votre compte, modifier le CRM, envoyer et dépenser des crédits. Chaque appel ci-dessous reflète exactement ce que répond le serveur.
Référence API
Base : https://api.fantomhunt.com/v1 · Authentification : Authorization: Bearer fh_live_… · Quota : 120 requêtes par minute et par clé (en-têtes RateLimit-* sur chaque réponse). Une limite par adresse s’ajoute : 600 requêtes par minute. Les prospects et les contacts se paginent : la réponse est { donnees, curseur_suivant }, repassez curseur pour la page suivante (limite : 50 par défaut, 200 maximum ; curseur_suivant vaut null à la dernière page). Les autres listes renvoient { donnees } en une fois. Les dates sont en ISO 8601 (UTC), les montants des affaires en centimes.
| Appel | Ce qu’il rend |
|---|---|
| GET /v1/moi | Le compte derrière la clé : ses droits, les crédits IA et contact restants, les invitations LinkedIn du mois. L’appel de vérification de toute intégration. |
| GET /v1/etat | Ce que la machine fait pour vous : prospection en pause ou non, frein LinkedIn, prochaine action prévue, canaux connectés, usage du jour et de la semaine face aux limites. |
| GET /v1/prospects | Vos prospects LinkedIn : liste filtrable et paginée, ou UNE fiche retrouvée par son email, son lien LinkedIn ou son téléphone. |
| GET /v1/prospects/:id | Une fiche complète : coordonnées, statut, score, offre, étiquettes, campagnes en cours, dates clés. |
| GET /v1/prospects/:id/journal | Le journal : le type d’événement et sa date ; avec le droit « messages », le contenu (note, compte rendu, texte du message). |
| GET /v1/prospects/:id/conversation | Droit « messages » : le fil de la personne, LinkedIn, WhatsApp et email réunis, du plus récent au plus ancien ({ donnees, avant_suivant }). |
| GET /v1/contacts-whatsapp | Le répertoire WhatsApp (filtres : statut, q, telephone, cree_depuis, repondu_depuis). |
| GET /v1/contacts-whatsapp/:id | La fiche d’un contact WhatsApp : offre, étiquettes, campagnes (celles de sa fiche LinkedIn liée), dates. |
| GET /v1/contacts-whatsapp/:id/conversation | Droit « messages » : la conversation WhatsApp du contact. |
| GET /v1/contacts-email | Le répertoire email (filtres : statut, q, email, cree_depuis, repondu_depuis). |
| GET /v1/contacts-email/:id | La fiche d’un contact email. |
| GET /v1/contacts-email/:id/conversation | Droit « messages » : les emails échangés avec le contact, objet compris. |
| GET /v1/taches | Vos tâches et la personne concernée (statut=a_faire, faites ou toutes ; en_retard=1 ; prospect ; echeance_avant, echeance_apres). |
| GET /v1/affaires | Vos affaires (vue Opérations) : montant, colonne, échéance ; statut=en_cours, gagnee ou perdue avec le motif. |
| GET /v1/affaires/:id | Une affaire et ses personnes, avec leur importance. |
| GET /v1/affaires-colonnes | Les colonnes de votre tableau d’affaires, dans l’ordre. |
| GET /v1/campagnes | Vos campagnes et leurs compteurs (inscrits, traités, actifs, stoppés, réponses). |
| GET /v1/campagnes/:id | Le détail d’une campagne : canal, planning, étapes (types, délais, textes prévus) et compteurs. |
| GET /v1/campagnes/:id/prospects | Où en sont ses prospects : étape en cours, raison de sortie, prochaine action. |
| GET /v1/offres | Vos offres. |
| GET /v1/offres/:id | Le contenu d’une offre, celui que lit l’IA : promesse, prix, objectif, ton, personas, angles, preuves, objections, consignes, et ce qui reste à confirmer. |
| GET /v1/offres/:id/messages-types | Les modèles de messages de l’offre. |
| GET /v1/stats | Les totaux par canal, filtrables par date avec depuis. |
| GET /v1/stats/canaux | Par canal : envois, personnes contactées, réponses, taux et délai médian de réponse, et la période précédente pour comparer (jours, défaut 30). |
| GET /v1/stats/quotidien | Envois et réponses jour par jour (jours : 7 à 90). |
| GET /v1/stats/etapes | Envois, réponses et taux par étape de campagne. |
| GET /v1/stats/ab | Les tests A/B en cours : versions, taux, probabilité d’être la meilleure et verdict (trop_tot, tendance, gagnante, egalite). |
| GET /v1/stats/horaires | Les réponses par jour de la semaine (lundi en premier) et par heure, heure de Paris. |
| GET /v1/stats/segments | Les taux de réponse par offre, par étiquette et par recherche. |
| GET /v1/stats/pipeline | Le stock de prospects par étape et l’état des parcours de campagne. |
| GET /v1/stats/resultats-commerciaux | Affaires gagnées et perdues, montants, taux de réussite, durée d’une affaire, motifs de perte, et la période précédente (jours, 0 = depuis toujours). |
| GET /v1/rdv | Les rendez-vous des trois canaux (periode=a_venir ou passes). |
| GET /v1/recherches | Vos recherches et leur récolte. |
| GET /v1/recherches/:id | Le détail d’une recherche : paramètres, progression, erreur éventuelle. |
| GET /v1/recherches-automatiques | Vos recherches programmées. |
| GET /v1/changements-poste | Les prospects suivis qui ont changé de poste ou ont été promus (non_vus=1). |
| GET /v1/audiences | Vos audiences. |
| GET /v1/equipe | Votre équipe et les performances de ses membres, avec les mêmes règles de visibilité que l’application. |
| GET /v1/etiquettes | Vos étiquettes (pour donner leur sens aux filtres). |
Les prospects, filtrés
statut (voir le tableau ci-dessous), etiquette, recherche, campagne, offre (identifiants), score_min, q (nom, entreprise ou poste), les dates cree_depuis, contacte_depuis, repondu_depuis, et modifie_depuis (date ISO) pour ne tirer que ce qui a bougé — le mécanisme idéal pour une synchronisation périodique. Plusieurs statuts à la fois : statut=replied,rdv. Pour retrouver la fiche d’une personne que votre CRM connaît : email, url_linkedin (avec ou sans https://) ou telephone (06…, +33 6… : même numéro).
| Statut d’un prospect LinkedIn | Ce qu’il veut dire |
|---|---|
| nouveau | Pas encore démarché. |
| pending_connection | Invitation envoyée, en attente. |
| contacted | Message envoyé. |
| connected | Invitation acceptée. |
| replied | A répondu. |
| rdv | Rendez-vous pris. |
| snoozed | Relance programmée (mis en veille jusqu’à une date). |
| client | Devenu client. |
| not_interested | Pas intéressé. |
| off_topic | Hors cible. |
| ecarte | Écarté. |
| archived | Archivé. |
Un contact WhatsApp ou email a son propre statut dans son canal : actif tant qu’il n’en est pas sorti, puis rdv, client, not_interested, off_topic, ecarte, archived, et pour l’email bounced (adresse qui rejette les messages).
curl -H "Authorization: Bearer fh_live_VOTRE_CLE" \ "https://api.fantomhunt.com/v1/prospects?statut=replied,rdv&repondu_depuis=2026-09-01&limite=50" curl -H "Authorization: Bearer fh_live_VOTRE_CLE" \ "https://api.fantomhunt.com/v1/prospects?email=martin@acme.fr"
{
"donnees": [{
"id": "6f2b…", "nom": "Martin Dupont", "entreprise": "Acme",
"poste": "Directeur commercial", "url_linkedin": "https://www.linkedin.com/in/…",
"localisation": "Lyon", "email": "martin@acme.fr", "email_score": 95,
"telephone": "+33612345678", "statut": "replied", "score": 82,
"source": "extension", "recherche_id": "…", "offre_id": "…",
"offre": { "id": "…", "nom": "Paie externalisée" },
"etiquettes": [{ "id": "…", "nom": "Chaud", "couleur": "#ff5555" }],
"campagnes": [{ "id": "…", "nom": "Relance DAF" }],
"cree_le": "…", "modifie_le": "…", "contacte_le": "…",
"connecte_le": "…", "repondu_le": "…", "rdv_le": null
}],
"curseur_suivant": "eyJ0Ijoi…"
}Les conversations
Avec une clé qui a le droit messages. Chaque message dit son canal, son sens (envoye ou recu), son texte et sa date ; un email porte aussi son objet, et deux marques : réponse automatique, expéditeur non authentifié. limite : 100 par défaut, 200 maximum ; pour remonter plus loin, repassez avant_suivant dans avant.
{
"donnees": [
{ "canal": "email", "id": "…", "sens": "recu", "objet": "Re: votre offre",
"texte": "Oui, appelons-nous jeudi.", "date": "2026-09-24T09:12:00.000Z",
"media": null, "reponse_automatique": false, "non_verifie": false },
{ "canal": "linkedin", "id": "…", "sens": "envoye", "objet": null,
"texte": "Bonjour Martin, …", "date": "2026-09-22T08:30:00.000Z",
"media": null, "reponse_automatique": false, "non_verifie": false }
],
"avant_suivant": null
}Modifier le CRM
Avec une clé qui a le droit crm (« Modifier le CRM », décoché par défaut). Chaque modification passe par le même chemin que l’application : la personne est une (note, offre, étiquettes et statut client suivent sur ses autres canaux), le rendez-vous arrive dans votre agenda connecté, le journal et les webhooks suivent. Tout est vérifié avant d’écrire : une requête refusée ne laisse rien à moitié fait. Rien ne part vers un prospect et aucun crédit n’est dépensé.
| Appel | Ce qu’il fait |
|---|---|
| POST /v1/prospects | Ajouter un prospect par url_linkedin (plus offre_id, etiquettes_ajouter, note). La fiche entre « en lecture » et se complète quand l’extension lit le profil ; elle compte dans votre quota. Déjà présent : 200 et deja_present, rien n’est modifié. |
| PATCH /v1/prospects/:id | Modifier une fiche : statut, rdv_le et rdv_duree_min, rdv_debriefe, note, offre_id (null pour détacher), etiquettes_ajouter, etiquettes_retirer. Rend la fiche à jour. |
| POST /v1/prospects/:id/journal | Ajouter une note datée au journal (texte) : un appel, un échange hors FantomHunt. |
| POST /v1/contacts-whatsapp | Ajouter un contact WhatsApp (telephone, nom, et les mêmes extras). Déjà présent : 200 et deja_present. |
| POST /v1/contacts-email | Ajouter un contact email (email, nom, et les mêmes extras). |
| PATCH /v1/contacts-whatsapp/:id | Les mêmes champs qu’un prospect ; statut : actif, rdv, client, not_interested, off_topic, archived, ecarte. |
| PATCH /v1/contacts-email/:id | Idem pour un contact email. |
| POST /v1/contacts-whatsapp/:id/journal | Une note au journal du contact (idem pour contacts-email). |
| POST /v1/taches | Créer une tâche : titre, echeance_le, et une personne au plus (prospect_id, contact_whatsapp_id ou contact_email_id), canal. |
| PATCH /v1/taches/:id | titre, echeance_le, faite (true ou false), canal. |
| DELETE /v1/taches/:id | Supprimer une tâche. |
| POST /v1/affaires | Créer une affaire : nom, montant_centimes, debut_le et echeance_le (AAAA-MM-JJ), colonne_id, personnes ([{ "prospect_id": "…" }]). |
| PATCH /v1/affaires/:id | nom, montant, dates, colonne_id, et statut : gagnee, perdue (avec motif_de_perte) ou en_cours (rouvre une affaire close). |
| POST /v1/affaires/:id/personnes | Rattacher une personne à une affaire. |
| POST /v1/etiquettes | Créer une étiquette (nom, couleur). Une étiquette inconnue passée dans etiquettes_ajouter est aussi créée. |
curl -X PATCH https://api.fantomhunt.com/v1/prospects/6f2b… \
-H "Authorization: Bearer fh_live_VOTRE_CLE" -H "Content-Type: application/json" \
-d '{ "statut": "rdv", "rdv_le": "2026-10-02T09:30:00Z", "rdv_duree_min": 30,
"etiquettes_ajouter": ["Chaud"], "note": "Budget validé en comité" }'Les statuts d’un prospect : nouveau, pending_connection, contacted, connected, replied, rdv, snoozed, client, not_interested, off_topic, archived, ecarte. Les gardes de l’application s’appliquent aussi aux intégrations : un parcours ne recule pas, une fiche close (client, pas intéressé, archivée…) n’est pas rouverte. Dans ce cas la réponse reste 200, la fiche est rendue telle quelle et un champ avertissements l’explique. Un champ inconnu est refusé (400) plutôt qu’ignoré : une faute de frappe ne passe pas en silence.
Rejouer sans doublon : ajoutez l’en-tête Idempotency-Key (une valeur unique par action, 200 caractères au plus) à vos créations. Si Zapier ou votre script renvoie la même requête, la première réponse est rendue telle quelle (en-tête Idempotent-Replayed: true) au lieu de créer une seconde tâche. La clé vaut 24 heures, pour une seule requête.
Envoyer
Avec une clé qui a le droit envoyer (décoché par défaut). Ça part tout de suite, sans relecture dans l’application, exactement comme un envoi fait à la main : mêmes plafonds (invitations LinkedIn 100 par jour et 300 par semaine, vos limites WhatsApp et, pour l’email, celles de chaque boîte), même frein LinkedIn, même conversation. Donnez ce droit seulement à un outil de confiance.
| Appel | Ce qu’il fait |
|---|---|
| POST /v1/prospects/:id/message | Un message LinkedIn (texte), ou programmé (programme_le, date à venir). Il entre dans la file de l’extension : 202, avec envoi_id et statut_envoi (en_file ou programme). |
| POST /v1/prospects/:id/invitation | Une invitation LinkedIn, avec une note facultative (300 caractères). Refusée (409) si le prospect est déjà connecté ou plus loin dans le parcours. |
| POST /v1/contacts-whatsapp/:id/message | Un message WhatsApp (texte), envoyé immédiatement par votre session : 201. |
| POST /v1/contacts-email/:id/message | Un email (objet, texte), envoyé immédiatement par la boîte du fil ou celle de boite_id, avec votre signature (signature: false pour l’enlever) : 201. |
| POST /v1/campagnes/:id/prospects | Inscrire des prospects (prospect_ids, 500 au plus) dans une campagne à liste manuelle. La réponse compte inscrits, ecartes_equipe et ignores (déjà dans une campagne en cours ou déjà passés par celle-ci). |
| PATCH /v1/campagnes/:id | statut : active (lancer ou reprendre) ou paused (mettre en pause). |
| POST /v1/recherches | Lancer une recherche de prospects LinkedIn, exécutée par l’extension : source (mots_cles par défaut, avec cible et pays ; sales_navigator, groupe, evenement, engagement_post avec url ; reseau ; visiteurs_profil), volume (1 à 500), offre_id. Une à la fois ; compte dans la limite des profils trouvés (1 000 par jour, 3 000 par semaine). |
| POST /v1/recherches/:id/annuler | Annuler une recherche en attente ou en cours. |
Un message ou une invitation LinkedIn part quand l’extension peut l’envoyer. La réponse dit, dans attentes, ce qui le ferait patienter : prospection en pause, LinkedIn freiné après des refus, hors de vos horaires d’envoi, plafond du jour atteint. Le webhook message.envoye (ou invitation.envoyee) vous prévient quand il est réellement parti. Une campagne dont les étapes rédigent avec l’IA consomme ses crédits comme dans l’application.
{
"canal": "linkedin", "prospect_id": "6f2b…", "envoi_id": "a41c…",
"statut_envoi": "en_file",
"attentes": ["Hors de vos horaires d’envoi : l’envoi partira à la prochaine plage."]
}Dépenser des crédits
Avec une clé qui a le droit credits. Cette clé porte deux plafonds mensuels obligatoires, en crédits IA et en crédits contact (100 et 20 proposés à la création, modifiables dans Réglages sans changer de clé). Chaque action est d’abord estimée par le même calcul que la fenêtre de confirmation de l’application, puis comptée sur la clé à son coût réellement débité. Au-delà du plafond, rien n’est lancé (402 plafond_atteint). Le solde du compte reste la seconde barrière.
| Appel | Ce qu’il fait |
|---|---|
| POST /v1/ia/estimer | Gratuit, pour toute clé : le coût d’une action avant de la lancer (action : rediger_message, scorer, modeles_offre, sequence_campagne, trouver_email, trouver_telephone, avec ses paramètres). |
| POST /v1/ia/message | Rédiger avec l’IA un message pour un prospect (prospect_id ; mode : premier_message ou reponse à la conversation en cours ; offre_id, par défaut celle de la fiche ; contexte). Rend message, conseils et stade : le texte n’est pas envoyé. |
| POST /v1/ia/scorer | Scorer des prospects rattachés à une offre (offre_id, prospect_ids), toujours au niveau rapide : classement, synthèse, profil idéal. |
| POST /v1/ia/modeles-offre | Générer les modèles de messages d’une offre, enregistrés dans l’offre. |
| POST /v1/ia/sequence-campagne | Rédiger les textes des étapes d’une campagne (campagne_id). Proposés, pas appliqués. |
| POST /v1/prospects/:id/trouver-email | Trouver l’email professionnel : 1 crédit contact, rendu si introuvable. Rend trouve et valeur. |
| POST /v1/prospects/:id/trouver-telephone | Trouver le téléphone mobile : 10 crédits contact, rendus si introuvable. |
Chaque réponse porte un bloc credits : ce qui était estimé, ce qui a été débité, et où en est la clé ce mois-ci. GET /v1/moi donne aussi les plafonds de la clé et sa dépense du mois.
{
"prospect_id": "6f2b…", "mode": "premier_message",
"message": "Bonjour Martin, j’ai vu votre parcours chez Acme…",
"conseils": "Si réponse positive : proposer un créneau…",
"credits": { "type": "ia", "estimes": 4, "debites": 4,
"cle_ce_mois": { "depenses": 12, "plafond": 100 } }
}Les erreurs, normalisées
Toujours { "error": code_stable, "message": explication } — le code se teste en machine, le message se lit.
| HTTP | Code | Quand |
|---|---|---|
| 401 | cle_manquante | Aucune clé dans Authorization. |
| 401 | cle_invalide | Clé inconnue ou révoquée. |
| 403 | plan_requis | Le compte n’est plus sur un plan payant. |
| 403 | compte_desactive | Le compte a été désactivé. |
| 403 | compte_en_suppression | La suppression du compte est demandée : l’API est fermée. |
| 403 | droit_manquant | La clé n’a pas le droit demandé (le champ droit dit lequel) : créez une clé qui l’a. |
| 403 | quota_atteint | Ajout d’un prospect au-delà du quota de votre plan. |
| 402 | plafond_atteint | Le plafond du mois de la clé ne couvre pas cette action : rien n’est lancé (plafond, depense et estimation sont joints). |
| 402 | credits_insuffisants | Le compte n’a plus assez de crédits. |
| 422 | hors_cadre | L’IA a jugé la demande hors du cadre de la prospection. |
| 503 | indisponible | Le service (IA ou recherche de coordonnées) ne répond pas : rien n’est débité. |
| 400 | parametre_invalide | Un filtre, une date, un curseur ou un champ illisible ; en écriture, aussi un champ inconnu. |
| 404 | introuvable | Identifiant inconnu sur ce compte. |
| 409 | conflit | L’action contredit l’état de la fiche (ex. personne déjà rattachée à l’affaire, invitation à un prospect déjà connecté, recherche déjà en cours). |
| 409 | canal_deconnecte | WhatsApp ou la boîte email n’est pas connecté : rien n’est parti. |
| 429 | limite_atteinte | Un plafond d’envoi est atteint (invitations, WhatsApp, email) : rien n’est parti. |
| 409 | requete_en_cours | Une requête avec la même Idempotency-Key n’est pas encore terminée. |
| 422 | cle_reutilisee | Cette Idempotency-Key a déjà servi pour une autre requête. |
| 429 | trop_de_requetes | Quota dépassé — réessayez dans une minute. |