9 min de cititTutoriale

API de analiză a linkurilor: statistici de click cu o cheie API

API-ul de analiză a linkurilor: ce rapoarte de click citește o cheie API, parametrii, structura JSON, paginarea cu cursor și un script de raport zilnic în Slack.

Marius Voß
DevRel · edge infra

API-ul Elido de analiză a linkurilor este un singur endpoint, GET /v1/workspaces/{workspace_id}/analytics/{report} pe https://api.elido.app, autentificat cu o cheie API de workspace. Servește 15 rapoarte: serie temporală de clicuri, un sumar al interacțiunii, cele mai bune linkuri, un flux de clicuri recente paginat cu cursor și defalcări pe țară, referrer, dispozitiv, browser, host și destinație. Datele implicite acoperă ultimele 30 de zile, link_id restrânge orice raport la un singur link scurt, iar exportul CSV, pâlniile, cohortele și LTV rămân în dashboard.

Dacă ai nevoie doar de URL, acesta este tot răspunsul. Restul ghidului este ce mi-aș fi dorit să spună de la început fiecare pagină despre un API de analiză a clicurilor: parametrii exacți, JSON-ul pe care îl primești, locul unde intervalul de date funcționează discret altfel decât ai presupune și un script de 30 de linii care postează în fiecare dimineață cifrele de ieri în Slack.

Cei mai mulți oameni care extrag date de click închid un circuit care începe cu etichetarea campaniilor, așa că, dacă linkurile tale nu poartă încă UTM-uri consecvente, rezolvă mai întâi asta cu urmărirea UTM de la cap la coadă. Datele de intrare curate fac statisticile demne de extras.

Ce returnează API-ul de analiză a linkurilor

Toate rapoartele se află pe aceeași cale, iar numele raportului este ultimul segment. Numele cu slash (links/top, clicks/recent, breakdown/country) se trimit neencodate. Dacă ceri ceva din afara listei permise, primești un 404 cu unknown analytics report.

RaportStructura răspunsuluiUtil pentru
timeseries{items: [{ts, count}]}Grafice, comparații de la o zi la alta
summaryobiect plat cu cinci metriciRezumate zilnice, tile-uri KPI
links/top{items: [{link_id, slug, count}]}„Care linkuri au dus săptămâna"
clicks/recent{items: [click rows], next_cursor}Fluxuri aproape în timp real, stocare proprie
breakdown/country, /referrer, /device, /browser, /host, /destination{items: [{key, count}]}Diagrame circulare, împărțirea pe canale
top-countries, top-referrers, top-destinations{items: [{key, count}]}Aceleași date, nume mai simple
top-regions, top-cities{points: [{country, region or city, count}]}Detaliere geografică sub nivelul țării

Observă ultimul rând. Rapoartele pentru regiuni și orașe își împachetează rândurile în points, nu în items, pentru că fiecare rând poartă o țară plus o regiune sau un oraș, în loc de o singură cheie. Am văzut un parser generic blocându-se pe asta o singură dată. O dată îți ajunge.

Aceeași suprafață stă în spatele API-ului și SDK-urilor, al instrumentului de analiză din serverul MCP și al operațiunii Get Analytics din nodul n8n, așa că ce înveți aici se aplică și acolo.

Pagina Chei API din Elido, cu o cheie de raportare doar pentru citire lângă două chei de editor, fiecare cu prefixul și numărul de cereri

Autentificarea cu o cheie API de workspace

Cheile API încep cu elido_ și aparțin unui singur workspace. Trimite cheia ca bearer token:

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

Routerul verifică două lucruri înainte de orice interogare: că cheia aparține workspace-ului 4821 și că deține analytics.view. Fiecare rol predefinit are această permisiune, inclusiv Viewer. Creează deci o cheie Viewer pentru joburile de raportare. Un cron de raportare n-are ce căuta cu dreptul de a șterge linkuri, iar o cheie Viewer nu poate. O cheie fără acces primește 403.

Nici link_id nu lărgește accesul. ID-ul de workspace din cale este cel verificat, așa că un ID de link împrumutat din workspace-ul altcuiva nu se potrivește cu niciun rând și returnează o listă goală. Este eșecul corect: plictisitor și fără scurgeri.

Parametrii de interogare pentru statistici de click: date, fus orar, filtre

Șase parametri acoperă aproape orice apel de statistici pentru linkuri scurte pe care îl vei face:

  • from și to, în format YYYY-MM-DD. Dacă le omiți pe amândouă, primești cele 30 de zile până acum. Dacă setezi doar to, from ia implicit valoarea cu 30 de zile înainte.
  • link_id pentru a limita orice raport la un link și host pentru a-l limita la un domeniu de redirecționare, util când un workspace rulează mai multe domenii de brand.
  • interval pentru timeseries, fie hour, fie day (implicit). Orice altceva face cererea să eșueze.
  • limit pentru defalcări și topuri, de la 1 la 200, implicit 50. links/top este excepția: returnează 10 dacă nu ceri mai mult.

Iată detaliul care mușcă. Ambele date sunt citite ca miezul nopții UTC, iar fereastra include from, dar se oprește înainte de to. Pentru toată ziua de 21 septembrie, trimite from=2026-09-21&to=2026-09-22. Dacă trimiți to=2026-09-21, nu primești nimic din ziua respectivă.

Fusul orar este cealaltă capcană. Trimite tz ca nume de fus orar IANA sau setează antetul X-User-TZ, iar timeseries își taie intervalele orare sau zilnice pe ora locală. Se mută doar intervalele. Fereastra from/to rămâne UTC, așa că un „ieri" al Berlinului cere o fereastră puțin mai largă, lucru pe care îl rezolvă scriptul de mai jos. O greșeală de scriere precum Europe/Berln returnează un 400 cu unknown IANA timezone, ceea ce e mai bine decât un grafic greșit în tăcere.

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"

Structuri de răspuns pe care le poți codifica

Un punct din seria temporală conține ts, un timestamp RFC 3339 pentru începutul intervalului, și count. Intervalele fără clicuri lipsesc pur și simplu, așa că completează golurile singur înainte de a trasa graficul, altfel o duminică liniștită dispare de pe axa x.

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

Defalcările returnează {"items": [{"key": "DE", "count": 1204}, ...]}, sortate după count. Sumarul este un obiect plat:

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

Două definiții contează. Vizitatorii unici se numără după adresa IP distinctă din fereastră, deci un birou aflat în spatele unei singure conexiuni se numără o dată. Iar bounce_rate este o fracție, nu un procent: ponderea vizitatorilor unici care au dat un singur click în fereastră. Nu spune nimic despre ce s-a întâmplat pe pagina ta de destinație, motiv pentru care aceste cifre nu se potrivesc niciodată cu sesiunile GA4 (articolul despre clicuri vs sesiuni GA4 explică diferența). Fiecare cifră este filtrată de boți înainte să ajungă la tine, aceleași valori pe care le vezi în analiza linkurilor Elido.

Paginarea clicurilor recente cu un cursor

clicks/recent este raportul API de urmărire a linkurilor care returnează clicuri individuale, cele mai noi primele. Fiecare rând are ts, link_id, slug, host, referer, country_code, device, browser, destination, user_agent și ip. Dimensiunea paginii este de la 1 la 500, implicit 100.

Când o pagină vine plină, răspunsul conține un next_cursor. Trimite-l ca ?cursor= pentru a primi pagina următoare, mai veche; null înseamnă că ai ajuns la capătul ferestrei.

Paginarea cu cursor a raportului clicks/recent din API-ul de analiză a linkurilor: prima cerere returnează pagina cu cele mai noi clicuri plus next_cursor, clientul îl trimite înapoi ca ?cursor= pentru pagina următoare, mai veche, iar un next_cursor null încheie bucla

Cursorul indică timestamp-ul ultimului rând și ID-ul linkului. Două clicuri pe același link în aceeași milisecundă pot ajunge la egalitate la granița dintre pagini, iar cel mai rău caz este un rând duplicat, niciodată unul sărit. Deduplică pe rândul întreg când le stochezi. Rar, dar zece linii de insert bat o explicație despre o eroare de unu la finanțe.

Acele rânduri includ adrese IP și user agents, deci sunt date personale. Dacă le copiezi într-un depozit de date, ține-le în UE și stabilește o perioadă de retenție; ghidul despre rezidența datelor în UE pentru echipele de marketing explică raționamentul. Pentru majoritatea rapoartelor nu ai nevoie deloc de rânduri brute, iar un agregat zilnic e mai blând cu toată lumea.

Un script de raport zilnic de clicuri pentru Slack sau un sheet

Iată jobul pe care îl vor de fapt cei mai mulți: în fiecare dimineață, postează într-un canal clicurile de ieri și primele cinci linkuri. Folosește doar biblioteca standard Python și un webhook de intrare 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"}))

Rulează-l din cron la 07:00 ora locală. Trucul cu orele este ceea ce face totalul o zi reală a Berlinului, nu una UTC; links/top nu are tz, așa că ierarhia lui rămâne pe ziua UTC, iar mesajul o spune.

Vrei un sheet în loc de Slack? Aceleași două apeluri funcționează din Google Apps Script cu UrlFetchApp și un trigger zilnic, adăugând un rând pe zi. Este și cea mai ieftină cale spre un dashboard Looker Studio.

Dacă încă mai copiezi cifre din capturi de ecran în fiecare luni, dă o cheie Viewer unui script și ia-ți diminețile înapoi.

Ce rămâne doar în dashboard

Suprafața cheii API este doar pentru citire și deliberat mai îngustă decât dashboardul. Acestea nu pot fi accesate cu o cheie:

  • Exportul CSV al clicurilor (clicks.csv). Butonul Descarcă CSV din dashboard este calea pentru fișierele în volum.
  • Pâlniile, cohortele, raportul LTV, hărțile de căldură pe timp și geografie și vizualizarea calității traficului.

Dacă tot ce îți trebuie este un fișier care ajunge undeva după un program, rapoartele programate prin e-mail din dashboard fac asta fără cod. Pentru o extragere completă, de nivel offboarding, vezi ce poți exporta dintr-un cont de linkuri scurte și cum verifici că e completă. Iar un apel combinat „tot pentru un link" nu există încă, deci un dashboard per link înseamnă o cerere pe raport. Quickstart-ul SDK explică rularea lor în paralel și retragerea cu backoff când atingi limitele de rată.

Interogarea API-ului de analiză a clicurilor vs webhook-uri pentru timp real

Versiunea sinceră: astăzi, datele de click se obțin doar prin interogare. Webhook-urile Elido trimit evenimente de link și de domeniu, semnate și reîncercate, dar un eveniment click.created pentru fiecare click este pe roadmap și nu este emis încă. Orice vrei în timp real despre clicuri înseamnă interogarea clicks/recent.

Comparație între interogarea periodică a API-ului de analiză a linkurilor și webhook-uri pentru datele de click: interogarea clicks/recent cu un cursor stocat funcționează astăzi, în timp ce webhook-urile acoperă evenimentele de link și de domeniu, iar evenimentul click.created per click este planificat, dar neemis

E mai puțin dureros decât sună. Interoghează la un minut sau două, oprește-te imediat ce ajungi la un rând pe care l-ai stocat deja, iar încărcarea rămâne minusculă, pentru că un minut liniștit înseamnă o pagină mică. Când apare click.created, handlerul care procesează un rând nu va ține cont dacă a venit dintr-o pagină sau dintr-un push. Compromisurile în general sunt expuse în webhook-uri vs interogare periodică pentru urmărirea clicurilor, iar dacă te hotărăști care dintre aceste cifre merită un raport, ce să măsori în analiza linkurilor scurte este lectura mai scurtă.

Părerea mea: începe cu sumarul zilnic. Aproape fiecare echipă care îmi cere clicuri în timp real e mulțumită de cifrele de ieri livrate înainte de cafea.

Citește articolul de referință → Cum urmărești campaniile UTM de la cap la coadă

Articole conexe

Întrebări frecvente

Are Elido un API de analiză pentru clicurile pe linkurile scurte?

Da. O cheie API de workspace poate apela GET /v1/workspaces/{workspace_id}/analytics/{report} pe api.elido.app și poate citi 15 rapoarte: serie temporală, sumar, cele mai bune linkuri, clicuri recente, șase defalcări și cinci topuri. Cheia are nevoie de permisiunea analytics.view, pe care o au deja toate rolurile predefinite, inclusiv Viewer.

Cum obțin statisticile de click pentru un singur link scurt prin API?

Adaugă link_id în query string-ul oricărui raport. ID-ul numeric al linkului restrânge seria temporală, sumarul, defalcările și clicurile recente la acel link. Accesul îl decide în continuare workspace-ul din cale, așa că un ID de link din alt workspace nu returnează niciun rând, în loc să scurgă date.

Pot exporta datele de click în CSV prin API?

Nu cu o cheie API. Exportul CSV al clicurilor, pâlniile, cohortele și raportul LTV sunt disponibile doar în dashboard. Pentru un flux automatizat, parcurge pagină cu pagină raportul clicks/recent cu cursorul lui și scrie rândurile singur, sau programează din dashboard un raport prin e-mail dacă îți ajunge un fișier în inbox.

Ce fus orar folosește API-ul de analiză a linkurilor?

Datele from și to sunt citite ca zile calendaristice UTC. Pentru raportul timeseries poți trimite tz ca nume IANA, de exemplu Europe/Berlin, sau antetul X-User-TZ, iar intervalele orare sau zilnice se taie în acel fus. Un nume de fus necunoscut returnează eroarea 400.

Pot primi un webhook la fiecare click pe un link scurt?

Încă nu. Un webhook click.created pentru fiecare click este pe roadmap, dar nu este emis momentan, așa că webhook-urile acoperă acum doar evenimentele de link și de domeniu. Pentru date de click aproape în timp real, interoghează periodic raportul clicks/recent și păstrează ultimul cursor între rulări.

Ce rol de cheie API poate citi analizele de click?

Orice rol predefinit. Citirea analizelor cere analytics.view, iar rolul Viewer o are deja, deci cea mai sigură alegere pentru un script de raportare este o cheie Viewer. Poate citi toate rapoartele permise, dar nu poate crea, edita sau șterge linkuri dacă cheia ajunge vreodată să se scurgă de pe un server cu cron.

Încearcă Elido

Lipește un URL, obții un link scurt funcțional

Fără înregistrare. Linkul este activ timp de 30 de zile. Înregistrează-te ca să-l păstrezi pentru totdeauna.

Fără înregistrare. Creează un cont gratuit pentru 50 linkuri pe lună.

Încearcă Elido

Scurtător de URL-uri găzduit în UE, cu domenii personalizate, analiză avansată și un API deschis. Nivel gratuit - fără card bancar.

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

Continuă lectura