Aller au contenu
Docs

Référence

Statistiques interrogeables en SQL

Interrogez vos données d’envoi avec le générateur Queryable ou en SQL ClickHouse brut, découvrez les tables disponibles et les limites, et partez d’exemples de requêtes.

Disponible surPay as you goProBusinessCustomMis à jour le 1 oct. 2026

L’onglet Queryable de Email APIAnalytics vous permet de poser vos propres questions à vos données d’envoi, soit avec un générateur visuel, soit en SQL ClickHouse en lecture seule. Il est disponible sur Pay as you goProBusinessCustom. Les résultats s’affichent sous forme de graphique et de tableau, et vous pouvez enregistrer des requêtes pour votre équipe.

Générateur

Le générateur écrit la requête à votre place et utilise la plage de dates et les filtres Sending domain et API key de la page.

Contrôle Options
Measure sends, bounces, complaints, loads, clicks, unique loads, unique clicks, unique emails, failed, rejected, suppressed, avg delivery time, bounce rate, complaint rate
Time grain hour, day, week
Group by none, status, domain, credential (clé API), campaign, tag, country
Chart type Timeseries, Pie, Stat, Table

Toutes les combinaisons ne s’appliquent pas. Group by country fonctionne avec les chargements et les clics, qui ont un pays ; status, domain, credential, campaign et tag fonctionnent avec les mesures portant sur les e-mails (envois, rebonds, en échec, rejetés, bloqués, e-mails uniques et les deux taux). Les plaintes et la durée moyenne de livraison ne sont pas regroupées. Les groupes affichent des ID comme dom_… et key_… ; utilisez le SQL brut pour joindre les noms. Le regroupement par tag renvoie généralement un seul groupe (none).

Sélectionnez Run pour afficher le résultat.

SQL brut

Activez Raw SQL pour écrire du SQL ClickHouse dans l’éditeur, puis sélectionnez Run.

  • Les requêtes doivent commencer par SELECT ou WITH et ne peuvent lire que les tables listées ci-dessous. Les écritures, les fonctions de table comme url() ou s3() et les tables system sont bloquées.
  • Chaque table est automatiquement limitée à votre espace de travail. Vous n’avez pas besoin de condition workspace_oid.
  • La plage de dates et les filtres de la page ne s’appliquent pas au SQL brut. Ajoutez votre propre condition temporelle, comme created_at >= now() - INTERVAL 30 DAY, sinon les requêtes parcourent toutes les données conservées.
  • Chaque FROM et chaque JOIN doit nommer directement une table. Les sous-requêtes entre parenthèses sont acceptées, mais ne placez pas d’alias après un nom de table (FROM emails_raw e) et ne sélectionnez pas depuis une requête WITH nommée. Qualifiez plutôt les colonnes avec le nom de la table, par exemple sending_domains_dim.name.
  • Les requêtes renvoient au maximum 5 000 lignes et s’arrêtent au bout de 10 secondes. Une requête peut compter jusqu’à 20 000 caractères.

Pour afficher le résultat sous forme de graphique, renvoyez une colonne temporelle nommée t, une colonne numérique nommée v et, si vous le souhaitez, une colonne group_key pour obtenir une série par valeur. Tout autre format s’affiche sous forme de tableau. Le tableau de la page affiche les 100 premières lignes.

Requêtes enregistrées

Saisissez un nom dans Save as… et sélectionnez Save query pour enregistrer les réglages actuels du générateur ou le SQL. Les requêtes enregistrées apparaissent sous forme de boutons au-dessus des résultats, pour tous les membres de l’espace de travail. Sélectionnez-en une pour la charger, ou sélectionnez son × pour la supprimer.

Tables

Les tables _raw sont conservées jusqu’à 365 jours. Les tables _daily contiennent les totaux quotidiens et suivent la durée de conservation des statistiques de votre forfait.

emails_raw

Une ligne par version de chaque e-mail. Chaque changement de statut ajoute une nouvelle version : un e-mail apparaît donc plusieurs fois. Regroupez par oid et utilisez argMax(column, _peerdb_version) pour lire la dernière valeur, comme dans les exemples ci-dessous.

Colonne Description
oid ID de l’e-mail (em_…).
type outgoing pour les e-mails envoyés, inbound pour les e-mails reçus.
status Le statut de l’e-mail, par exemple delivered ou bounced.
rcpt_to, mail_from, subject, message_id Enveloppe et objet.
sending_domain_oid, credential_oid ID du domaine d’envoi (dom_…) et ID de la clé API (key_…).
campaign_oid, automation_oid Renseignés pour les envois de campagnes et d’automatisations.
tag Généralement vide.
spam_score, inspected Score Rspamd, et indication que l’e-mail a été évalué ou non.
size Taille du message en octets.
loaded, clicked Heure de la première ouverture et du premier clic, ou NULL.
created_at, updated_at Horodatages en UTC.
_peerdb_version Numéro de version ; plus il est élevé, plus la version est récente.

deliveries_raw

Une ligne par enregistrement de livraison : chaque tentative, ainsi que les enregistrements comme retenu ou bloqué.

Colonne Description
oid, email_oid ID de la livraison et e-mail auquel elle appartient.
status Par exemple delivered, attempted, bounced, held, suppressed.
output La réponse du serveur destinataire, par exemple 250 2.0.0 OK.
details La description du résultat par Emailit.
time La durée de la tentative, la valeur utilisée par Time to inbox.
sent_with_ssl Indique si la connexion utilisait TLS.
timestamp, created_at Moment de la tentative.

loads_raw et clicks_raw

Une ligne par ouverture ou clic.

Colonne Description
oid, email_oid ID du chargement ou du clic et e-mail auquel il appartient.
link_oid clicks_raw uniquement : l’ID du lien cliqué (link_…). Les URL des liens ne sont pas stockées dans les tables de statistiques.
ip_address, country, city, user_agent Provenance de l’ouverture ou du clic.
timestamp, created_at Moment où il a eu lieu.

events_raw

Une ligne par événement : oid (evt_…), type, data (le payload sous forme de chaîne JSON ; lisez-le avec des fonctions comme JSONExtractString(data, 'object', 'id')) et created_at.

Tables quotidiennes

Table Colonnes
events_daily day, type, cnt, unique_emails
deliveries_daily day, status, cnt, avg_time
loads_daily day, cnt, unique_emails, countries
clicks_daily day, cnt, unique_emails, unique_links

Additionnez cnt avec sum(cnt). Les autres colonnes sont des états d’agrégation ClickHouse : lisez-les avec uniqMerge(unique_emails), uniqMerge(unique_links), avgMerge(avg_time) et topKMerge(10)(countries).

Tables de dimensions

Table Colonnes
sending_domains_dim oid, name, created_at
campaigns_dim oid, name, status, created_at
workspaces_dim oid, name, plan_id, created_at

Joignez-les pour afficher des noms plutôt que des ID.

Exemples de requêtes

Taux de rebond par domaine d’envoi et par jour

SQL
SELECT
  toDate(latest.first_seen) AS t,
  sending_domains_dim.name AS group_key,
  countIf(latest.status = 'bounced') / count() AS v
FROM (
  SELECT
    oid,
    min(created_at) AS first_seen,
    argMax(status, _peerdb_version) AS status,
    argMax(sending_domain_oid, _peerdb_version) AS sending_domain_oid
  FROM emails_raw
  WHERE type = 'outgoing'
    AND created_at >= now() - INTERVAL 30 DAY
  GROUP BY oid
) AS latest
LEFT JOIN sending_domains_dim ON sending_domains_dim.oid = latest.sending_domain_oid
GROUP BY t, group_key
ORDER BY t, group_key

Choisissez le graphique Timeseries pour obtenir une courbe par domaine.

SQL
SELECT
  link_oid,
  count() AS clicks,
  uniqExact(email_oid) AS emails_clicked
FROM clicks_raw
WHERE timestamp >= now() - INTERVAL 7 DAY
GROUP BY link_oid
ORDER BY clicks DESC
LIMIT 20

Les tables de statistiques stockent l’ID du lien, pas son URL. Pour voir l’URL d’un lien, ouvrez un e-mail qui comporte le clic et consultez son onglet Clicks, ou récupérez link.url dans les webhooks email.clicked.

Percentiles du délai de livraison

SQL
SELECT
  toDate(timestamp) AS t,
  count() AS deliveries,
  quantile(0.5)(toFloat64(time)) AS p50,
  quantile(0.95)(toFloat64(time)) AS p95,
  quantile(0.99)(toFloat64(time)) AS p99
FROM deliveries_raw
WHERE status = 'delivered'
  AND time IS NOT NULL
  AND timestamp >= now() - INTERVAL 14 DAY
GROUP BY t
ORDER BY t

Envois et ouvertures par campagne

SQL
SELECT
  campaigns_dim.name AS campaign,
  count() AS sent,
  countIf(latest.loaded IS NOT NULL) AS opened,
  countIf(latest.clicked IS NOT NULL) AS clicked
FROM (
  SELECT
    oid,
    argMax(campaign_oid, _peerdb_version) AS campaign_oid,
    argMax(loaded, _peerdb_version) AS loaded,
    argMax(clicked, _peerdb_version) AS clicked
  FROM emails_raw
  WHERE type = 'outgoing'
    AND created_at >= now() - INTERVAL 90 DAY
  GROUP BY oid
) AS latest
INNER JOIN campaigns_dim ON campaigns_dim.oid = latest.campaign_oid
GROUP BY campaign
ORDER BY sent DESC

Erreurs

Message Cause
Only SELECT queries are allowed La requête ne commence pas par SELECT ou WITH.
Table “…” is not allowed Un FROM ou un JOIN nomme autre chose qu’une table autorisée, par exemple une requête WITH nommée.
Query must read an allowlisted analytics table La requête ne comporte aucun FROM portant sur une table autorisée.
External tables and table functions are not allowed La requête utilise une fonction de table comme url().
Queries cannot target another workspace Une condition workspace_oid = '…' désigne un autre espace de travail.

Les erreurs de syntaxe ClickHouse, par exemple dues à un alias après un nom de table, s’affichent telles que ClickHouse les renvoie.

Cette page vous a-t-elle été utile ?

Merci pour votre retour.

Merci, nous lisons chaque message.