Aller au contenu principal
9 min de lecture

POST /query/:websiteId

Posez des questions sur vos données analytiques en langage naturel. Le moteur IA interprète votre question, interroge les données pertinentes et retourne des résultats structurés avec un résumé lisible par l'utilisateur. Idéal pour construire des interfaces analytiques conversationnelles ou des rapports automatisés.

POST/api/external/v1/query/:websiteId

Requête analytique en langage naturel

Authentification

Toutes les demandes nécessitent une clé API transmise via l'en-tête X-API-Key. Vous pouvez également utiliser l'en-tête Authorization: Bearer YOUR_API_KEY.

AuthentificationBash
curl -X POST 'https://api.zenovay.com/api/external/v1/query/a1b2c3d4-e5f6-7890-abcd-ef1234567890' \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"question": "What are my top traffic sources this week?"}'

Ce point de terminaison nécessite un plan Scale ou supérieur. Les clés API des plans Pro et Free recevront une réponse 403 Interdit.

Chaque demande coûte 3 crédits API en raison du traitement par IA. Tenez compte de cela dans votre planification d'utilisation.

Corps de la demande

ChampTypeRequisDescription
questionchaîneOuiVotre question analytique en langage naturel (max 500 caractères)
contextobjetNonContexte supplémentaire pour affiner la requête
context.time_rangechaîneNonRemplacer la plage horaire : 24h, 7d, 30d, 90d
context.compare_tochaîneNonPériode de comparaison : previous_period, previous_year
Corps de la demandeJSON
{
"question": "What are my top traffic sources this week?",
"context": {
  "time_range": "7d",
  "compare_to": "previous_period"
}
}

Réponse

Réponse (200 OK)JSON
{
"success": true,
"data": {
  "question": "What are my top traffic sources this week?",
  "intent": "traffic_sources_breakdown",
  "confidence": 0.95,
  "time_range": "7d",
  "results": {
    "type": "table",
    "columns": ["source", "visitors", "percentage", "change"],
    "rows": [
      ["Google Organic", 4521, 38.2, 12.5],
      ["Direct", 3102, 26.2, -3.1],
      ["Twitter", 1845, 15.6, 45.2],
      ["GitHub", 982, 8.3, 8.7],
      ["Hacker News", 651, 5.5, 128.3],
      ["LinkedIn", 432, 3.6, -12.4],
      ["Other", 305, 2.6, 1.2]
    ]
  },
  "summary": "Your top traffic source this week is Google Organic with 4,521 visitors (38.2% of total). Twitter saw the largest relative growth at +45.2%, while Hacker News traffic surged +128.3% compared to last week, likely driven by a front-page post.",
  "suggestions": [
    "Which pages are Hacker News visitors landing on?",
    "What is the bounce rate for Twitter traffic?",
    "How does my organic search traffic compare to last month?"
  ]
},
"timestamp": "2026-03-16T15:00:00.000Z"
}

Champs de réponse

ChampTypeDescription
data.questionchaîneLa question originale telle que soumise
data.intentchaîneLa catégorie d'intention détectée par l'IA
data.confidencenombreScore de confiance pour la détection d'intention (0-1)
data.time_rangechaîneLa plage horaire utilisée pour la requête
data.resultsobjetRésultats structurés de la requête
data.results.typechaîneFormat des résultats : table, number, timeseries, list
data.results.columnstableauEn-têtes de colonnes (pour le type table)
data.results.rowstableauLignes de données (pour le type table)
data.summarychaîneRésumé généré par l'IA en langage naturel des résultats
data.suggestionstableauQuestions de suivi que l'utilisateur pourrait vouloir poser

Types de résultats

Le champ results.type indique comment les données sont structurées :

TypeDescriptionChamps
tableDonnées tabulaires avec colonnes et lignescolumns, rows
numberValeur d'une métrique uniquevalue, label, change
timeseriesPoints de données dans le tempspoints (tableau de {date, value})
listListe ordonnée d'élémentsitems (tableau de chaînes)

Exemples de questions et réponses

Exemple 1 : Requête de métrique unique

DemandeJSON
{
"question": "How many unique visitors did I get yesterday?"
}
RéponseJSON
{
"success": true,
"data": {
  "question": "How many unique visitors did I get yesterday?",
  "intent": "unique_visitors_count",
  "confidence": 0.98,
  "time_range": "24h",
  "results": {
    "type": "number",
    "value": 2847,
    "label": "Unique Visitors",
    "change": 15.3
  },
  "summary": "You received 2,847 unique visitors yesterday, which is 15.3% higher than the previous day (2,469 visitors). This is above your 7-day average of 2,412 unique daily visitors.",
  "suggestions": [
    "Where did yesterday's visitors come from?",
    "What pages were most popular yesterday?",
    "How does yesterday compare to last week?"
  ]
},
"timestamp": "2026-03-16T15:00:00.000Z"
}

Exemple 2 : Requête de série chronologique

DemandeJSON
{
"question": "Show me my daily page views trend for the past 2 weeks"
}
RéponseJSON
{
"success": true,
"data": {
  "question": "Show me my daily page views trend for the past 2 weeks",
  "intent": "pageviews_timeseries",
  "confidence": 0.92,
  "time_range": "14d",
  "results": {
    "type": "timeseries",
    "points": [
      {"date": "2026-03-03", "value": 8234},
      {"date": "2026-03-04", "value": 9102},
      {"date": "2026-03-05", "value": 8876},
      {"date": "2026-03-06", "value": 9543},
      {"date": "2026-03-07", "value": 7234},
      {"date": "2026-03-08", "value": 5102},
      {"date": "2026-03-09", "value": 5897},
      {"date": "2026-03-10", "value": 9012},
      {"date": "2026-03-11", "value": 9456},
      {"date": "2026-03-12", "value": 9234},
      {"date": "2026-03-13", "value": 10102},
      {"date": "2026-03-14", "value": 7654},
      {"date": "2026-03-15", "value": 5432},
      {"date": "2026-03-16", "value": 6123}
    ]
  },
  "summary": "Your daily page views over the past 2 weeks average 7,857. There is a clear weekly pattern with dips on weekends (Saturday-Sunday). The highest traffic day was March 13 with 10,102 page views, and overall the trend is slightly upward at +4.2% week-over-week.",
  "suggestions": [
    "Why did traffic dip on March 7?",
    "What drove the spike on March 13?",
    "How do weekday vs weekend patterns compare?"
  ]
},
"timestamp": "2026-03-16T15:00:00.000Z"
}

Exemple 3 : Requête comparative

DemandeJSON
{
"question": "Compare my mobile vs desktop conversion rates this month",
"context": {
  "time_range": "30d",
  "compare_to": "previous_period"
}
}
RéponseJSON
{
"success": true,
"data": {
  "question": "Compare my mobile vs desktop conversion rates this month",
  "intent": "device_conversion_comparison",
  "confidence": 0.91,
  "time_range": "30d",
  "results": {
    "type": "table",
    "columns": ["device", "conversion_rate", "previous_rate", "change"],
    "rows": [
      ["Desktop", 3.8, 3.5, 8.6],
      ["Mobile", 1.9, 2.1, -9.5],
      ["Tablet", 2.4, 2.3, 4.3]
    ]
  },
  "summary": "Desktop has the highest conversion rate at 3.8% (+8.6% vs last month), while mobile conversion dropped to 1.9% (-9.5%). The gap between desktop and mobile widened this month, suggesting mobile checkout or landing page experience may need attention.",
  "suggestions": [
    "Which mobile pages have the highest drop-off?",
    "What is the average page load time on mobile?",
    "Show me the mobile conversion funnel breakdown"
  ]
},
"timestamp": "2026-03-16T15:00:00.000Z"
}

Interface TypeScript

QueryResponseTypeScript
interface TableResults {
type: 'table';
columns: string[];
rows: (string | number)[][];
}

interface NumberResults {
type: 'number';
value: number;
label: string;
change: number;
}

interface TimeseriesResults {
type: 'timeseries';
points: { date: string; value: number }[];
}

interface ListResults {
type: 'list';
items: string[];
}

type QueryResults = TableResults | NumberResults | TimeseriesResults | ListResults;

interface QueryResponse {
success: true;
data: {
  question: string;
  intent: string;
  confidence: number;
  time_range: string;
  results: QueryResults;
  summary: string;
  suggestions: string[];
};
timestamp: string;
}

Codes de statut HTTP

Code de statutDescription
200Succès
400Mauvaise demande - Question manquante ou invalide
401Non autorisé - Clé API invalide ou manquante
403Interdit - Plan Scale ou supérieur requis
404Non trouvé - Site web non trouvé
422Entité non traitable - La question n'a pas pu être interprétée
429Trop de demandes - Limite de débit dépassée
500Erreur interne du serveur

Exemples de code

cURLBash
curl -X POST 'https://api.zenovay.com/api/external/v1/query/a1b2c3d4-e5f6-7890-abcd-ef1234567890' \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
  "question": "What are my top traffic sources this week?",
  "context": {
    "time_range": "7d",
    "compare_to": "previous_period"
  }
}'

Gestion des erreurs

Réponse d'erreur (403 Interdit)JSON
{
"success": false,
"error": {
  "message": "This endpoint requires a Scale plan or higher",
  "code": "PLAN_REQUIRED",
  "timestamp": "2026-03-16T15:00:00.000Z"
}
}
Réponse d'erreur (422 Non traitable)JSON
{
"success": false,
"error": {
  "message": "Unable to interpret the question. Please rephrase or be more specific.",
  "code": "QUERY_UNPROCESSABLE",
  "timestamp": "2026-03-16T15:00:00.000Z"
}
}
Cette page vous a-t-elle été utile ?