> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qwairy.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Tableau de bord sur mesure

> Construisez un tableau de bord à partir des données de performance, de concurrents, de sources, de réponses et de Query Fan-Out.

Construisez un tableau de bord qui garde visible le périmètre de chaque indicateur de l’API. Ce guide utilise le client réutilisable du [Démarrage rapide](/fr/developers/guides/index#api-client).

## Récupérer la vue d’ensemble

Demandez la performance, les concurrents et les domaines sources sur la même période. Gardez la méthodologie renvoyée à côté des scores affichés pour que les lecteurs voient le périmètre de réponses et de fournisseurs.

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function fetchDashboardData(client, brandId, period = 30) {
    const [performance, competitorData, sourceData] = await Promise.all([
      client.getPerformance(brandId, { period }),
      client.getCompetitors(brandId, {
        period,
        relationship: 'SELF,DIRECT',
        limit: 100,
        sort: 'shareOfVoice',
        order: 'desc',
      }),
      client.getSourceDomains(brandId, {
        period,
        limit: 20,
        sort: 'mentions',
        order: 'desc',
      }),
    ]);

    const self = competitorData.competitors.find(
      (item) => item.relationship === 'SELF'
    );
    const direct = competitorData.competitors.filter(
      (item) => item.relationship === 'DIRECT'
    );

    return {
      scores: performance.scores,
      methodology: performance.methodology,
      self: self ?? null,
      competitors: direct.map((item) => ({
        id: item.id,
        name: item.name,
        mentions: item.totalMentions,
        shareOfVoice: item.shareOfVoice,
        shareOfVoiceGap: self
          ? Number((item.shareOfVoice - self.shareOfVoice).toFixed(2))
          : null,
      })),
      sources: sourceData.sources.map((item) => ({
        domain: item.domain,
        citations: item.totalMentions,
        citationShare: item.rate,
        isSelf: item.isSelf,
      })),
    };
  }
  ```

  ```python Python theme={null}
  def fetch_dashboard_data(client, brand_id: str, period: int = 30) -> dict:
      performance = client.get_performance(brand_id, period=period)
      competitor_data = client.get_competitors(
          brand_id, period=period, limit=100,
          sort='shareOfVoice', order='desc',
      )
      source_data = client.get_source_domains(
          brand_id, period=period, limit=20,
          sort='mentions', order='desc',
      )

      self_brand = next(
          (item for item in competitor_data['competitors']
           if item['relationship'] == 'SELF'),
          None,
      )
      direct = [
          item for item in competitor_data['competitors']
          if item['relationship'] == 'DIRECT'
      ]

      return {
          'scores': performance['scores'],
          'methodology': performance['methodology'],
          'self': self_brand,
          'competitors': [
              {
                  'id': item['id'],
                  'name': item['name'],
                  'mentions': item['totalMentions'],
                  'share_of_voice': item['shareOfVoice'],
                  'share_of_voice_gap': round(
                      item['shareOfVoice'] - self_brand['shareOfVoice'], 2
                  ) if self_brand else None,
              }
              for item in direct
          ],
          'sources': [
              {
                  'domain': item['domain'],
                  'citations': item['totalMentions'],
                  'citation_share': item['rate'],
                  'is_self': item['isSelf'],
              }
              for item in source_data['sources']
          ],
      }
  ```
</CodeGroup>

Le client Python du Démarrage rapide n’expose pas l’argument `relationship`. Filtrez la liste renvoyée comme ci-dessus, ou étendez le wrapper pour transmettre ce paramètre de requête.

## Libeller les indicateurs selon leur source

Ne remplacez pas ces définitions par des formules homonymes du tableau de bord, des exports, du MCP ou de Looker Studio.

| Champ | Périmètre de performance REST |
| - | - |
| `scores.mentionRate` | Réponses mentionnant SELF divisées par les réponses avec une mention SELF ou DIRECT |
| `scores.sourceRate` | Réponses citant SELF divisées par les réponses avec une citation SELF ou DIRECT |
| `scores.coverage` | Réponses mentionnant SELF divisées par l’ensemble des réponses du périmètre d’API sélectionné |
| `scores.shareOfVoice` | Occurrences de mentions SELF divisées par les occurrences SELF et DIRECT |
| `scores.sentiment` | Sentiment SELF moyen sur l’échelle de `0` à `100` |

Affichez `methodology.responsesTotal`, `methodology.promptsCount` et `methodology.providers` près des cartes de score. Une variation de ces valeurs peut rendre deux périodes non comparables.

## Ajouter des diagnostics de réponses

L’endpoint Answers applique `hasSelfSource=true`, mais ignore actuellement la valeur inverse `false`. Demandez les réponses mentionnant SELF et filtrez l’indicateur `hasSelfSource` renvoyé dans votre client.

```javascript JavaScript theme={null}
async function fetchDiagnostics(client, brandId, period = 30) {
  const [answerData, searchData] = await Promise.all([
    client.getAnswers(brandId, {
      period,
      hasSelfMention: true,
      limit: 100,
      sort: 'createdAt',
      order: 'desc',
    }),
    client.getSearch(brandId, {
      period,
      limit: 20,
      sort: 'occurrences',
      order: 'desc',
    }),
  ]);

  return {
    sampledMentionWithoutCitation: answerData.answers
      .filter((answer) => !answer.hasSelfSource)
      .map((answer) => ({
        prompt: answer.promptText,
        provider: answer.provider,
        position: answer.selfMentionPosition,
      })),
    queryFanOut: searchData.searches.map((record) => ({
      query: record.query,
      occurrences: record.occurrences,
      prompts: record.prompts.map((prompt) => prompt.text),
      models: record.models,
    })),
  };
}
```

<Note>
  Le diagnostic des réponses se limite à la page demandée. Sa longueur n’est pas le nombre total de réponses correspondantes. Paginez avant de calculer un total complet.
</Note>

## Vérifier le tableau de bord

1. Affichez la période sélectionnée et la méthodologie de l’API.
2. Vérifiez que les relations SELF et DIRECT ne sont pas mélangées avec d’autres types de concurrents.
3. Considérez un écart de part de voix comme une différence dans l’ensemble de réponses sélectionné, pas comme une part de marché.
4. Gardez les citations des réponses, le Query Fan-Out et les mentions des concurrents comme des observations distinctes.
5. Comparez des filtres et des ensembles de prompts équivalents avant de parler de tendance.

## Pages associées

* [Obtenir l’instantané de performance](/fr/developers/endpoints/performance)
* [Lister les concurrents](/fr/developers/endpoints/competitors/list)
* [Lister les domaines sources](/fr/developers/endpoints/source-domains/list)
* [Lister les réponses](/fr/developers/endpoints/answers/list)
* [Lister les enregistrements Query Fan-Out](/fr/developers/endpoints/search)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.