10 min di letturaTutorial

API di analisi dei link: ottieni le statistiche dei clic con una chiave API

Guida all'API di analisi dei link: quali report sui clic può leggere una chiave API, i parametri di query, le forme delle risposte JSON, la paginazione con cursore e uno script per un report Slack giornaliero.

Marius Voß
DevRel · edge infra
Copertina dell'API di analisi dei link: una richiesta curl con una chiave API del workspace restituisce JSON di serie temporali, ripartizione e riepilogo dei clic accanto a un grafico a barre pixel

L'API di analisi dei link Elido è un unico endpoint, GET /v1/workspaces/{workspace_id}/analytics/{report} su https://api.elido.app, autenticato con una chiave API del workspace. Fornisce 15 report: serie temporali dei clic, un riepilogo dell'engagement, link principali, un feed di clic recenti paginato con cursore e ripartizioni per paese, referrer, dispositivo, browser, host e destinazione. Per impostazione predefinita le date coprono gli ultimi 30 giorni, link_id limita qualsiasi report a un link breve e l'esportazione CSV, i funnel, le coorti e LTV restano nella dashboard.

Questa è la risposta completa, se ti serviva solo l'URL. Il resto della guida contiene ciò che vorrei fosse spiegato subito in ogni pagina su un'API di analisi dei clic: parametri esatti, JSON restituito, i punti in cui l'intervallo di date funziona silenziosamente in modo diverso da quanto immagini e uno script di 30 righe che ogni mattina invia a Slack i numeri di ieri.

La maggior parte delle persone che estrae dati sui clic sta chiudendo un ciclo iniziato con il tagging delle campagne, quindi se i tuoi link non includono ancora UTM coerenti, risolvi prima questo aspetto con il monitoraggio UTM end-to-end. Dati di input puliti rendono utili le statistiche estratte.

Ogni report si trova sotto lo stesso percorso e il nome del report è l'ultimo segmento. I nomi con una barra (links/top, clicks/recent, breakdown/country) rimangono senza codifica. Se chiedi qualcosa fuori dall'elenco consentito, ricevi un 404 con unknown analytics report.

ReportForma della rispostaUtile per
timeseries{items: [{ts, count}]}Grafici, confronti giorno su giorno
summaryoggetto piatto di cinque metricheRiepiloghi giornalieri, riquadri KPI
links/top{items: [{link_id, slug, count}]}"Quali link hanno sostenuto la settimana"
clicks/recent{items: [click rows], next_cursor}Feed quasi in tempo reale, archiviazione propria
breakdown/country, /referrer, /device, /browser, /host, /destination{items: [{key, count}]}Grafici a torta, suddivisioni per canale
top-countries, top-referrers, top-destinations{items: [{key, count}]}Stessi dati, nomi più semplici
top-regions, top-cities{points: [{country, region or city, count}]}Dettagli geografici sotto il livello paese

Nota l'ultima riga. I report per regione e città racchiudono le righe in points, non in items, perché ogni riga contiene un paese più una regione o una città invece di una sola chiave. Ho visto un parser generico bloccarsi proprio su questo una volta. Una volta basta.

La stessa superficie supporta le API e SDK, lo strumento di analisi del server MCP e l'operazione Get Analytics nel nodo n8n, quindi ciò che impari qui si trasferisce anche altrove.

Autenticazione con una chiave API del workspace

Le chiavi API iniziano con elido_ e appartengono a un solo workspace. Invia la chiave come token bearer:

curl -s "https://api.elido.app/v1/workspaces/4821/analytics/summary" \
  -H "Authorization: Bearer $ELIDO_API_KEY"

Il router verifica due aspetti prima di eseguire qualsiasi query: che la chiave appartenga al workspace 4821 e che disponga di analytics.view. Ogni ruolo integrato possiede questo permesso, incluso Viewer. Crea quindi una chiave Viewer per i processi di reporting. Un cron di reporting non deve poter eliminare link e una chiave Viewer non può farlo. Una chiave senza accesso riceve un 403.

Nemmeno link_id amplia l'accesso. L'ID workspace nel percorso è quello verificato, quindi un ID link preso in prestito dal workspace di qualcun altro corrisponde a zero righe e restituisce un elenco vuoto. È l'errore giusto: noioso, e senza fughe di dati.

Parametri di query per le statistiche dei clic: date, fuso orario, filtri

Sei parametri coprono quasi tutte le chiamate all'API delle statistiche dei link brevi che farai:

  • from e to, in formato YYYY-MM-DD. Omettili entrambi e ottieni i 30 giorni fino a ora. Imposta solo to e from assume il valore di 30 giorni prima.
  • link_id per limitare qualsiasi report a un link e host per limitarlo a un dominio di reindirizzamento, utile quando un workspace gestisce più domini brandizzati.
  • interval per timeseries, hour oppure day (il valore predefinito). Qualsiasi altro valore fa fallire la richiesta.
  • limit per ripartizioni ed elenchi principali, da 1 a 200, valore predefinito 50. links/top è l'eccezione: restituisce 10 risultati se non ne chiedi di più.

Ecco il dettaglio insidioso. Entrambe le date vengono lette come mezzanotte UTC e la finestra include from ma termina prima di to. Per includere tutto il 21 settembre, invia from=2026-09-21&to=2026-09-22. Se invii to=2026-09-21, non ottieni nulla di quel giorno.

L'altro aspetto è il fuso orario. Passa tz come nome di fuso orario IANA, oppure imposta un'intestazione X-User-TZ, e timeseries calcola i bucket orari o giornalieri in ora locale. Si spostano solo i bucket. La finestra from/to resta UTC, quindi per avere lo "ieri" di Berlino serve una finestra leggermente più ampia, gestita dallo script sotto. Un errore di battitura come Europe/Berln restituisce un 400 con unknown IANA timezone, preferibile a un grafico silenziosamente errato.

curl -s -G "https://api.elido.app/v1/workspaces/4821/analytics/timeseries" \
  -H "Authorization: Bearer $ELIDO_API_KEY" \
  --data-urlencode "from=2026-09-01" \
  --data-urlencode "to=2026-09-22" \
  --data-urlencode "interval=day" \
  --data-urlencode "tz=Europe/Berlin" \
  --data-urlencode "link_id=918273"

Forme delle risposte utilizzabili nel codice

Un punto di una serie temporale contiene ts, un timestamp RFC 3339 che indica l'inizio del bucket, e count. I bucket senza clic sono semplicemente assenti, quindi riempi tu gli intervalli prima di creare un grafico, altrimenti una domenica tranquilla scompare dall'asse x.

{
  "items": [
    { "ts": "2026-09-19T00:00:00Z", "count": 412 },
    { "ts": "2026-09-21T00:00:00Z", "count": 388 }
  ]
}

Le ripartizioni restituiscono {"items": [{"key": "DE", "count": 1204}, ...]}, ordinate per conteggio. Il riepilogo è un oggetto piatto:

{
  "total_clicks": 5310,
  "unique_visitors": 3987,
  "returning_visitors": 611,
  "avg_clicks_per_visitor": 1.33,
  "bounce_rate": 0.85
}

Due definizioni sono importanti. I visitatori unici vengono conteggiati in base a indirizzi IP distinti nella finestra, quindi un ufficio dietro una sola connessione conta una volta. E bounce_rate è una frazione, non una percentuale: la quota di visitatori unici che hanno fatto clic una sola volta nella finestra. Non dice nulla su ciò che è accaduto nella landing page, per questo questi numeri non coincidono mai con le sessioni GA4 (il post clic rispetto alle sessioni GA4 spiega la differenza). Ogni valore è filtrato dai bot prima di arrivare a te, gli stessi conteggi visibili nelle analisi dei link Elido.

Paginare i clic recenti con un cursore

clicks/recent è il report dell'API di monitoraggio dei link che restituisce i clic individuali, prima i più recenti. Ogni riga contiene ts, link_id, slug, host, referer, country_code, device, browser, destination, user_agent e ip. La dimensione della pagina va da 1 a 500, con valore predefinito 100.

Quando una pagina torna piena, la risposta contiene un next_cursor. Passalo come ?cursor= per ottenere la pagina successiva, più vecchia; null significa che hai raggiunto la fine della finestra.

Paginazione con cursore per il report clicks/recent dell'API di analisi dei link: la prima richiesta restituisce la pagina più recente di clic più next_cursor, il client lo ripassa come ?cursor= per la pagina successiva più vecchia e un next_cursor null termina il ciclo

Il cursore punta al timestamp e all'ID link dell'ultima riga. Due clic sullo stesso link nello stesso millisecondo possono essere a pari merito al confine di una pagina e il caso peggiore è una riga duplicata, mai una riga saltata. Elimina i duplicati usando l'intera riga quando le archivi. È raro, ma un inserimento di dieci righe evita di dover spiegare un errore off-by-one all'ufficio finanziario.

Quelle righe includono indirizzi IP e user agent, quindi sono dati personali. Se li copi in un data warehouse, mantienilo nell'UE e imposta un periodo di conservazione; la guida alla residenza dei dati UE per i team marketing spiega il perché. Per la maggior parte dei report non servono affatto righe grezze e un'aggregazione giornaliera è più rispettosa per tutti.

Uno script per un report giornaliero dei clic su Slack o in un foglio

Ecco il processo che la maggior parte delle persone desidera davvero: ogni mattina, pubblicare in un canale i clic di ieri e i cinque link principali. Usa solo la libreria standard di Python e un webhook in entrata di Slack.

import datetime as dt, json, os, urllib.parse, urllib.request
from zoneinfo import ZoneInfo

BASE = "https://api.elido.app/v1/workspaces/{ws}/analytics/{report}"
WS, KEY = os.environ["ELIDO_WORKSPACE_ID"], os.environ["ELIDO_API_KEY"]
TZ = ZoneInfo("Europe/Berlin")

def report(name, **params):
    url = BASE.format(ws=WS, report=name) + "?" + urllib.parse.urlencode(params)
    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {KEY}"})
    with urllib.request.urlopen(req, timeout=20) as r:
        return json.load(r)

day = dt.datetime.now(TZ).date() - dt.timedelta(days=1)
# UTC window one day wider on each side, then keep only local hours of `day`
window = {"from": day - dt.timedelta(days=1), "to": day + dt.timedelta(days=2)}
hours = report("timeseries", interval="hour", tz="Europe/Berlin", **window)["items"]
total = sum(p["count"] for p in hours
            if dt.datetime.fromisoformat(p["ts"]).astimezone(TZ).date() == day)

top = report("links/top", limit=5, **{"from": day, "to": day + dt.timedelta(days=1)})
lines = [f"• {l['slug']}: {l['count']}" for l in top["items"]]
text = f"Clicks on {day} (Berlin): {total}\nTop links (UTC day):\n" + "\n".join(lines)

body = json.dumps({"text": text}).encode()
urllib.request.urlopen(urllib.request.Request(
    os.environ["SLACK_WEBHOOK_URL"], data=body,
    headers={"Content-Type": "application/json"}))

Eseguilo da cron alle 07:00 locali. Il trucco orario fa sì che il totale rappresenti un vero giorno di Berlino anziché un giorno UTC; links/top non ha tz, quindi la sua classifica resta sul giorno UTC e il messaggio lo precisa.

Preferisci un foglio? Le stesse due chiamate funzionano da Google Apps Script con UrlFetchApp e un trigger giornaliero, aggiungendo una riga al giorno. È anche il percorso più economico verso una dashboard Looker Studio.

Se ogni lunedì continui a copiare numeri dagli screenshot, assegna una chiave Viewer a uno script e riprenditi le tue mattine.

Cosa resta disponibile solo nella dashboard

La superficie della chiave API è in sola lettura e volutamente più ristretta della dashboard. Questi elementi non sono raggiungibili con una chiave:

  • L'esportazione CSV dei clic (clicks.csv). Il pulsante Download CSV della dashboard è la via per ottenere file in blocco.
  • Funnel, coorti, il report LTV, le mappe di calore temporali e geografiche e la vista sulla qualità del traffico.

Se ti basta che un file arrivi da qualche parte a cadenza programmata, i report email pianificati della dashboard lo fanno senza codice. Per un'estrazione completa adatta all'offboarding, vedi cosa puoi esportare da un account di link brevi e come verificare che sia completo. E una chiamata combinata per "tutto per un link" non esiste ancora, quindi una dashboard per singolo link richiede una richiesta per report. La guida rapida SDK spiega come eseguirle in parallelo e rallentare quando raggiungi i limiti di frequenza.

Interrogare l'API di analisi dei clic o usare webhook per il tempo reale

La versione onesta: oggi i dati sui clic sono disponibili solo tramite interrogazione (pull). I webhook Elido inviano eventi di link e domini, firmati e ritentati, ma un evento click.created per ogni clic è previsto nella roadmap e non viene ancora emesso. Tutto ciò che riguarda i clic in tempo reale richiede di interrogare clicks/recent.

Confronto tra l'interrogazione dell'API di analisi dei link e i webhook per i dati sui clic: interrogare clicks/recent con un cursore salvato funziona oggi, mentre i webhook coprono eventi di link e domini e l'evento click.created per ogni clic è pianificato ma non emesso

È meno doloroso di quanto sembri. Interroga ogni minuto o due, fermati non appena raggiungi una riga già archiviata e il carico resta minimo, perché un minuto tranquillo è una pagina piccola. Quando arriverà click.created, al gestore che elabora una riga non importerà se proviene da una pagina o da un push. I compromessi generali sono illustrati in webhook rispetto al polling per il monitoraggio dei clic e, se stai decidendo quali di questi numeri meritano un report, cosa misurare nelle analisi dei link brevi è una lettura più breve.

Il mio consiglio: inizia dal riepilogo giornaliero. Quasi tutti i team che mi chiedono clic in tempo reale sono soddisfatti dei numeri di ieri, consegnati prima del caffè.

Leggi la guida fondamentale → Come monitorare le campagne UTM end-to-end

Correlati nel blog

Domande frequenti

Elido dispone di un'API di analisi per i clic sui link brevi?

Sì. Una chiave API del workspace può chiamare GET /v1/workspaces/{workspace_id}/analytics/{report} su api.elido.app e leggere 15 report: serie temporali, riepilogo, link principali, clic recenti, sei ripartizioni e cinque elenchi principali. La chiave richiede il permesso analytics.view, già disponibile in ogni ruolo integrato, incluso Viewer.

Come ottengo le statistiche dei clic per un singolo link breve tramite API?

Aggiungi link_id alla stringa di query di qualsiasi report. L'ID numerico del link limita serie temporali, riepilogo, ripartizioni e clic recenti a quel singolo link. Il workspace nel percorso determina comunque l'accesso, quindi un ID link di un altro workspace restituisce semplicemente zero righe senza esporre dati.

Posso esportare i dati sui clic come CSV tramite API?

Non con una chiave API. L'esportazione CSV dei clic, funnel, coorti e il report LTV sono disponibili solo nella dashboard. Per un flusso automatizzato, scorri il report clicks/recent con il relativo cursore e salva autonomamente le righe, oppure pianifica un report email dalla dashboard se basta un file nella posta in arrivo.

Quale fuso orario usa l'API di analisi dei link?

Le date from e to vengono lette come giorni di calendario UTC. Per il report timeseries puoi passare tz come nome IANA, ad esempio Europe/Berlin, oppure inviare un'intestazione X-User-TZ; i bucket orari o giornalieri vengono quindi calcolati in quel fuso. Un nome di fuso sconosciuto restituisce un errore 400.

Posso ricevere un webhook per ogni clic su un link breve?

Non ancora. Un webhook click.created per ogni clic è previsto nella roadmap ma oggi non viene emesso, quindi i webhook coprono attualmente solo eventi di link e domini. Per dati sui clic quasi in tempo reale, interroga il report clicks/recent a intervalli brevi e conserva l'ultimo cursore tra un'esecuzione e l'altra.

Quale ruolo della chiave API può leggere le analisi dei clic?

Qualsiasi ruolo integrato. La lettura delle analisi richiede analytics.view, già presente nel ruolo Viewer, quindi la scelta più sicura per uno script di reporting è una chiave Viewer. Può leggere ogni report consentito ma non creare, modificare o eliminare link se la chiave dovesse mai trapelare da un server cron.

Prova Elido

Incolla un URL, ottieni un link breve

Senza registrazione. Il link vive 30 giorni. Iscriviti per conservarlo.

Gratis, nessuna registrazione richiesta · 2 al giorno

Prova Elido

Accorciatore di URL ospitato nell'UE: domini personalizzati, analisi approfondite e API aperta. Piano gratuito - senza carta di credito.

Tag
link analytics api
click analytics api
short link stats api
url shortener analytics api
link tracking api
click data export

Continua a leggere