Skip to content

Analytics

Récupérez les mêmes KPIs et top questions groupées que votre dashboard B2B affiche : pour un outil BI, un export planifié, ou un agent IA qui doit répondre à "comment on se porte" sans ouvrir le dashboard.

Les deux endpoints ici sont en lecture seule et délèguent aux mêmes moteurs que le dashboard (le KPI board et la page Top Questions), donc les chiffres que vous récupérez via l'API ne divergent jamais de ce que vous voyez dans l'app.

Récupérer les KPIs

GET /analytics/kpis renvoie les métriques clés pour une période, chacune avec sa tendance par rapport à la période équivalente précédente.

Scope requis : analytics:read

Paramètre de requêteTypeDescription
periodstringtoday, 7_days, 30_days, 90_days, year, total ou custom. Défaut 30_days.
start_dateISO 8601Requis quand period=custom.
end_dateISO 8601Requis quand period=custom.
kpisstringIds de KPI séparés par des virgules. Défaut conversations,visitor_messages,add_to_cart,conversion_rate,revenue_generated,csat. Un id inconnu rejette toute la requête ; l'erreur liste tous les ids valides.

Ids de KPI disponibles

conversations, visitor_messages, add_to_cart, conversion_rate, revenue_generated, csat, csat_ai, csat_human, interaction_rate, support_conversations, website_visits, appointments_booked, new_contacts, tickets_created, tickets_resolved, product_page_views, conversations_offensive. Cette liste peut évoluer ; traitez error.details.available sur un 400 comme la source de vérité si vous la hardcodez.

website_visits et interaction_rate sur les longues périodes

Jusqu'à 90_days (et sa tendance sur la période précédente), website_visits compte les visiteurs distincts sur toute la fenêtre. Pour year, total et les plages personnalisées qui remontent à plus de 180 jours, ces deux KPI (et leur tendance) sont calculés à partir d'un agrégat quotidien : un visiteur revenu plusieurs jours compte une fois par jour, la valeur est donc légèrement supérieure à un décompte distinct sur toute la fenêtre. Sessions et conversations ne sont pas concernées.

Requête

bash
curl "https://api.thehumind.com/public/v1/analytics/kpis?period=30_days&kpis=conversations,revenue_generated,csat" \
  -H "Authorization: Bearer hmd_live_..."

Réponse 200 OK

json
{
  "data": {
    "conversations": { "total": 842, "change_percent": 12.4, "format": "number" },
    "revenue_generated": { "total": 15420.5, "change_percent": -3.1, "format": "currency" },
    "csat": { "total": 87.5, "change_percent": 2.0, "format": "percent", "sample": 96 }
  },
  "period": {
    "id": "30_days",
    "start": "2026-05-08T00:00:00.000Z",
    "end": "2026-06-07T23:59:59.999Z"
  }
}
ChampTypeDescription
data.<kpi_id>.totalnumberValeur de la métrique pour la période.
data.<kpi_id>.change_percentnumber | nullVariation en % vs. la période équivalente précédente. null quand il n'y a pas de période précédente comparable (ex. period=total).
data.<kpi_id>.formatstringnumber, percent ou currency : comment afficher total.
data.<kpi_id>.sampleintegerNombre d'observations sous-jacentes. Présent uniquement sur les KPIs basés sur un échantillon (csat, csat_ai, csat_human) : affichez un tiret cadratin en guise de placeholder plutôt que la valeur quand sample vaut 0, car un CSAT à 0% avec zéro note serait trompeur.

Une fenêtre custom :

bash
curl "https://api.thehumind.com/public/v1/analytics/kpis?period=custom&start_date=2026-01-01&end_date=2026-03-31" \
  -H "Authorization: Bearer hmd_live_..."

Récupérer les top questions

GET /analytics/top-questions renvoie les questions visiteur groupées sur une plage de dates : volume, tendance, une sparkline temporelle, taux de non-réponse, et questions échantillon par groupe, la vue "qu'est-ce que mes clients demandent, et à quoi je réponds mal".

Scope requis : analytics:read

Paramètre de requêteTypeDescription
start_dateISO 8601Requis. Début de la fenêtre.
end_dateISO 8601Requis. Fin de la fenêtre.
languagesstringCodes ISO 639-1 séparés par des virgules (ex. fr,en).
entry_pointsstringSéparés par des virgules : launcher, product_page, gift_generator, shop_banner, quiz.
searchstringFiltrage texte libre sur les groupes de questions (2 caractères min).
answeredtrue | falsetrue = groupes répondus uniquement ; false = coverage gaps uniquement.
categorystringFiltrer sur une seule catégorie de question.
sort_bystringcount (défaut), recency ou opportunity : trier par les plus gros gaps de non-réponse en premier.
pageintegerIndex de page, base 0. Défaut 0.
limitintegerGroupes par page (1 à 50). Défaut 20.
include_statstrue | falseAjouter des stats niveau période à la réponse (plus lent). Défaut false.

Trouver les coverage gaps à corriger en premier

sort_by=opportunity&answered=false remonte les clusters de questions sans réponse avec le plus gros volume, le moyen le plus rapide de prioriser ce qu'il faut ajouter à votre base de connaissances.

Requête

bash
curl "https://api.thehumind.com/public/v1/analytics/top-questions?start_date=2026-05-01&end_date=2026-06-01&sort_by=opportunity&answered=false&limit=10" \
  -H "Authorization: Bearer hmd_live_..."

Réponse 200 OK

json
{
  "data": [
    {
      "_id": "65f1ab9c8e7d4a2b1c3d4e90",
      "title": "Do you ship to Canada?",
      "label": "shipping_canada",
      "title_is_thematic": false,
      "category": "shipping",
      "count": 34,
      "trend": { "direction": "growing", "change_percent": 41.2 },
      "timeline": [
        { "date": "2026-05-01T00:00:00.000Z", "count": 3 },
        { "date": "2026-05-02T00:00:00.000Z", "count": 5 }
      ],
      "timeline_unit": "day",
      "unanswered_count": 22,
      "actionable_unanswered_count": 20,
      "unanswered_percentage": 64.7,
      "sample_questions": [
        "Do you ship to Canada?",
        "Is international shipping to Canada available?"
      ],
      "conversation_ids": ["65f1ab9c8e7d4a2b1c3d4e5f", "65f1ab9c8e7d4a2b1c3d4e61"]
    }
  ],
  "pagination": { "page": 0, "limit": 10, "total": 27 }
}
ChampTypeDescription
_idstringId interne du groupe.
titlestringTitre d'affichage : un label généré par l'IA quand disponible, sinon le texte représentatif brut.
labelstring | nullLabel canonique IA. null tant que la passe de labeling n'a pas traité le groupe.
title_is_thematicbooleantrue quand title est une reformulation thématique générée par l'IA d'un cluster divers, plutôt qu'une question canonique unique.
categorystringCatégorie de la question.
countintegerOccurrences sur la fenêtre.
languagesobject[]Distribution des langues : { code, count, percentage }.
entry_pointsobject[]Distribution des entry points : { action, count, percentage }.
trendobject{ direction: "growing" | "stable" | "declining" | "new", change_percent }. change_percent vaut null quand direction est new (aucune occurrence sur la période précédente).
timelineobject[]Occurrences par bucket sur toute la fenêtre, zero-filled : { date, count }.
timeline_unitstringday, week ou month : la taille de bucket de la timeline.
unanswered_countintegerOccurrences que le classifieur de qualité a signalées comme coverage gap.
actionable_unanswered_countintegerSous-ensemble de unanswered_count avec une raison de gap actionnable.
unanswered_percentagenumber | nullunanswered_count / évalué, 0-100. null quand rien n'a été évalué.
unanswered_reasonsobject[]Pourquoi les réponses ont échoué, du plus fréquent au moins fréquent : { reason, count }.
avg_satisfactionnumber | nullCSAT moyen sur les threads derrière ce groupe, quand disponible.
avg_conversion_intentnumber | nullIntention de conversion moyenne estimée par l'IA.
cart_ratenumber | nullPart des occurrences ayant mené à un ajout au panier.
handoff_ratenumber | nullPart des occurrences ayant mené à un handoff humain.
first_seen_at / last_seen_atISO 8601Première et dernière occurrence sur la fenêtre.
sample_questionsstring[]Jusqu'à 5 textes de questions échantillon distincts de ce groupe.
conversation_idsstring[]Échantillon de jusqu'à 10 humind_id de conversation derrière ce groupe ; à passer à GET /conversations/{id}.

Avec include_stats=true, un objet stats est ajouté à côté de data :

json
{
  "stats": {
    "total_questions": 512,
    "total_groups": 27,
    "grouped_percentage": 91.2,
    "product_linked_percentage": 38.4,
    "unanswered_count": 96,
    "unanswered_percentage": 18.8,
    "evaluated_count": 512,
    "evaluated_questions": 512,
    "previous_period": {
      "total_questions": 470,
      "total_groups": 24,
      "product_linked_percentage": 35.1,
      "unanswered_percentage": 21.3
    }
  }
}

previous_period vaut null quand le scan de la fenêtre précédente a échoué ou timeout ; traitez ça comme inconnu, pas comme un vrai zéro.

Erreurs courantes

StatutCodeQuandCorrection
400validation_failedDates manquantes/invalides, period=custom sans start_date/end_date, ou valeur kpis / entry_points inconnue. details liste ce qui est valide.Corrigez le paramètre et renvoyez.
401missing_credentials, invalid_key, revokedHeader d'auth manquant, malformé, ou clé inactive.Voir Authentication.
403insufficient_scopeLa clé n'a pas analytics:read.Créez une clé avec le scope analytics:read.
429rate_limitedTrop de requêtes pour cette clé.Temporisez via le header Retry-After. Voir Rate limits.

Suite

  • Authentication : générer une clé analytics:read.
  • Conversations : récupérez la transcription complète derrière une entrée conversation_ids.
  • Settings : lisez et mettez à jour la configuration de votre boutique via l'API.
  • Serveur MCP : laissez un agent IA interroger les KPIs et top questions directement.

Released under the proprietary Humind license.