Gjurmimi i hapjeve dhe i klikimeve
GET /tracking: nëse një mesazh u lexua dhe cilat lidhje u ndoqën.
Ekzekuton cilëndo nga 6 thirrjet e kësaj faqeje kundrejt hapësirës suaj të punës, me çelësin tuaj.
Çfarë regjistrohet
Dy çelësa të pavarur, të dy të ndezur nëse nuk janë fikur për adresën nga e cila dërgohet një mesazh ose për Të gjitha adresat. opens shton një imazh 1×1; clicks i rishkruan lidhjet në pjesën e re të trupit. Historiku i cituar poshtë një përgjigjeje është mesazhi i dikujt tjetër dhe nuk preket. Një dërgim emërton tracking: { opens, clicks } për të vendosur për një mesazh të vetëm (në të dy drejtimet, ndaj false është mënyra si një program refuzon atë që adresa është caktuar të bëjë), ndërsa një fushë që lini jashtë bie te cilësimi i adresës nga e cila dërgohet, pastaj te Të gjitha adresat, e jo te një parazgjedhje që ky API do ta zgjidhte në emër të një hapësire pune.
{ "from": "Acme Billing <[email protected]>", "to": ["[email protected]"], "subject": "Your September invoice", "html": "<p>Invoice attached.</p>", "tracking": { "opens": true, "clicks": true } }Me së shumti 100 destinacione për mesazh rishkruhen, nga një herë secili. I njëjti URL i lidhur nga një imazh koke, një buton dhe një fundfaqe është një rresht i vetëm, sepse është e njëjta pyetje e bërë tri herë. Përtej kufirit, lidhjet e mbetura lihen saktësisht siç u shkruan: një lidhje e pagjurmuar prapë funksionon, ndërsa një mesazh që humb në heshtje dyqind lidhjet e fundit është dështim shumë më i rëndë se një raport i paplotë.
Lidhjet e rishkruara dhe pikseli drejtojnë si parazgjedhje te hosti i API-së së OpenEmail-it. Kur domeni dërgues ka një domen të personalizuar gjurmimi, tracking.status i të cilit është active, posta e re nga ai domen përdor https://<tracking host>/t/... në vend të tij, dhe PATCH /domains/{id} është vendi ku e caktoni një të tillë.
E gjithë kjo kërkon emails:read, dhe nuk ka një fushëveprim gjurmimi. Ai fushëveprim tashmë do të thotë «lexo mesazhet e dërguara dhe gjendjen e dërgesës së tyre», dhe nëse dikush e hapi një mesazh është gjendja e dërgesës më e mirëfilltë e mundshme.
Endpoint-et
| Thirrja | Kthen |
|---|---|
| `GET /tracking` | Mesazhet e gjurmuara, më të rejat të parat. opened, clicked, days (1–365, parazgjedhje 30), limit (maksimumi 200). |
| `GET /tracking/stats` | Normat gjatë një dritareje. days (parazgjedhje 30) dhe offsetMinutes, që ditët të ndahen aty ku ndahet dita e lexuesit. |
| `GET /tracking/{id}` | Një raport i vetëm. Merr një id gjurmimi tmsg_ ose id-në msg_ që ktheu një dërgim. |
| `GET /tracking/{id}/opens` | Marrjet individuale. includeMachine, limit (maksimumi 200). |
| `GET /tracking/{id}/clicks` | E njëjta gjë, me linkId dhe url te secili rresht. |
| `GET /emails/{id}/tracking` | I njëjti raport, nisur nga id-ja e dërgimit që keni tashmë. |
Vlerat boolean shkruhen shkoqur te vargu i pyetjes: true, false, 1 ose 0, dhe çdo gjë tjetër refuzohet. Boolean("false") është true, ndaj një ?opened=false i konvertuar automatikisht do të kthente pikërisht të kundërtën e asaj që u kërkua.
Ky është një resurs më vete e jo disa fusha te /emails për shkak të mbulimit: ajo listë mban regjistrime dërgimesh, ndërsa kompozuesi, mjetet MCP dhe asistenti dërgojnë të gjithë pa shkruar asnjë. Një raport i ndërtuar mbi të do të ishte raport për trafikun tuaj të API-së e jo për kutinë postare.
Raporti
{ "object": "tracking", "id": "tmsg_9c1f7b2e4a5d40b8a3e61d2f", "sendId": "msg_c5f21cc6bfec4e848caf905b", "threadId": "thread_2f9b…", "messageId": "<2598…@acme.com>", "subject": "Your September invoice", "from": "[email protected]", "source": "api", "sentAt": "2026-08-29T08:19:08.000Z", "opens": true, "clicks": true, "opened": true, "clicked": true, "attributable": true, "openCount": 3, "openCountRaw": 7, "clickCount": 1, "clickCountRaw": 2, "firstOpenAt": "2026-08-29T09:04:11.000Z", "lastOpenAt": "2026-08-30T07:42:55.000Z", "firstClickAt": "2026-08-29T09:05:02.000Z", "lastClickAt": "2026-08-29T09:05:02.000Z", "recipients": [ { "email": "[email protected]", "kind": "to", "attributed": true, "openCount": 3, "clickCount": 1, "firstOpenAt": "2026-08-29T09:04:11.000Z", "lastOpenAt": "2026-08-30T07:42:55.000Z", "firstClickAt": "2026-08-29T09:05:02.000Z", "lastClickAt": "2026-08-29T09:05:02.000Z" } ], "links": [ { "id": "lnk_4f0a1c8d29b74e6fa3c05d17", "url": "https://acme.com/invoices/42", "label": "View invoice", "clickCount": 1, "clickCountRaw": 2 } ] }opens dhe clicks janë ato që u ZBATUAN mbi mesazhin; opened dhe clicked janë ato që ndodhën. openCount numëron leximet dhe openCountRaw numëron marrjet. Diferenca, katër këtu, janë skanuesit dhe proxy-t e privatësisë, të mbajtura që hendeku mes regjistrit dhe totalit të jetë i shqyrtueshëm e jo i pashpjeguar. attributable është fusha që duhet lexuar para se të emërtoni dikë: false do të thotë se një lexim ra mbi një kopje që shkoi te e gjithë lista, dhe çdo fjali pas saj për një marrës të caktuar është hamendje.
source emërton sipërfaqen që e dërgoi: api për një dërgim përmes këtij API-je, composer për gjithçka që dërgoi vetë aplikacioni. sendId është null për llojin e dytë, dhe pikërisht për këtë ekziston id-ja e gjurmimit.
Një rresht me email null dhe attributed: false është vendi ku bie një lexim që nuk mund t’i ngjitet një personi, dhe një raport e shfaq vetëm kur një lexim ka ndodhur vërtet. Një mesazh me një marrës të vetëm nuk ka asnjë të tillë, sepse një trup dhe një adresues janë i njëjti pohim. Një mesazh me disa marrës ka një të tillë pas vetes që nga çasti kur niset, sepse transporti nuk është i vendosur deri në dërgim, dhe ai mbetet jashtë raportit derisa të mbërrijë diçka mbi të: një «dikush: nuk e hapi» i përhershëm pranë marrësve të emërtuar është një rresht që mund vetëm të keqlexohet. Aty ku ai ËSHTË i pranishëm, rreshtat e emërtuar janë ata që rrinë në zero dhe attributable është false. Leximi është real, lexuesi është njëri nga personat në mesazh, dhe «dikush në këtë mesazh» është e vetmja paraqitje që e mbështet e dhëna. Kurrë mos e plotësoni emrin nga lista e marrësve.
Normat gjatë një dritareje
{ "object": "tracking_stats", "tracked": 128, "trackedForOpens": 128, "trackedForClicks": 47, "opened": 91, "clicked": 34, "openRate": 71.1, "clickRate": 72.3, "totalOpens": 240, "totalClicks": 52, "machineOpens": 173, "medianTimeToOpenSeconds": 2714, "byDay": [{ "day": "2026-08-27", "sent": 12, "opened": 9, "clicked": 3 }], "topLinks": [{ "url": "https://acme.com/pricing", "label": "See pricing", "clickCount": 18 }], "clients": [{ "client": "Gmail", "count": 96 }], "countries": [{ "country": "GB", "count": 71 }] }Normat janë përqindje mbi mesazhet E GJURMUARA, jo mbi të gjithë postën e dërguar: një hapësirë pune që gjurmon një mesazh nga dhjetë ka një normë hapjeje për ato dhjetë, dhe pjesëtimi me gjithçka që ka dërguar ndonjëherë do të binte sa herë që dikush dërgon një përgjigje të pagjurmuar. Një mesazh i hapur pesë herë është NJË mesazh i hapur. Normat numërojnë mesazhe dhe totalet numërojnë goditje, dhe ngatërrimi i të dyjave është mënyra si publikohen norma hapjeje mbi 100%.
byDay është i rrallë: një ditë në të cilën nuk u gjurmua asgjë mungon fare në vend që të jetë zero, ndaj plotësoni boshllëqet para se ta vizatoni në grafik. Ditët grupohen offsetMinutes në lindje të UTC-së (−840 deri në 840), që të ndahen aty ku ndahet dita e lexuesit. medianTimeToOpenSeconds është medianë e jo mesatare, sepse një mesazh i hapur tri javë me vonesë e tërheq një mesatare diku ku nuk ndodhet asnjë mesazh.
Goditjet individuale
{ "object": "list", "data": [ { "object": "open", "id": "opn_1a7c…", "trackedMessageId": "tmsg_9c1f7b2e4a5d40b8a3e61d2f", "recipient": "[email protected]", "kind": "machine", "counted": false, "client": "Apple Mail Privacy Protection", "device": "unknown", "os": "macOS", "country": "GB", "region": "England", "city": "London", "createdAt": "2026-08-29T08:19:11.000Z" } ] }kind është human, proxy ose machine, ndërsa counted thotë nëse ajo goditje i lëvizi numrat. Goditjet e makinave përjashtohen nëse nuk kaloni includeMachine=true, që është parazgjedhja e ndershme: ato regjistrohen sepse heqja e tyre do të linte një hendek të pashpjegueshëm, jo sepse janë angazhim i vërtetë.
Vendndodhja është e trashë sepse kjo është gjithçka që ka. Për asnjë goditje nuk ruhet adresë IP. Shteti, rajoni dhe qyteti janë ato që i dinte tashmë skaji i rrjetit, dhe i vetmi identifikues tjetër që mbahet është një hash, kripa e të cilit rrotullohet çdo ditë, kështu që ai mund të dallojë dy marrje brenda një dite dhe bëhet inert ditën tjetër.
Çfarë nuk mund të thonë numrat
- Apple Mail Privacy Protection i merr të gjitha imazhet në çdo mesazh sapo ai mbërrin, pavarësisht nëse e sheh dikush. Klasifikohet nga User-Agent dhe nga rrjeti dhe regjistrohet si
machine, po ashtu edhe çdo gjë që mbërrin brenda dhjetë sekondave nga dërgimi, sepse asgjë që bën një person nuk ndodh kaq shpejt. - Proxy-ja e imazheve e Gmail-it është
proxye jomachine: dikush e shfaqi mesazhin, ndaj hapja është reale, ndërsa pajisja, klienti dhe vendndodhja nuk janë të njohshme. Proxy-ja gjithashtu ruan në kesh, ndaj një lexim i dytë mund të mos mbërrijë kurrë te ne. Numërimet përmes Gmail-it janë një dysheme, kurrë një total. - Dy marrje të së njëjtës kopje brenda tridhjetë sekondave janë një lexim i vetëm. Një panel parapamjeje që rivizatohet ose një mesazh që kthehet në pamje e rimerr imazhin; vizita e dytë e vërtetë një orë më vonë prapë numërohet.
- Emërtimi i marrësit kërkon një mesazh mjaft të vogël sa të rindërtohet për secilin person: madhësia e vlerësuar shumëzuar me numrin e marrësve duhet të mbetet nën 8 MB. Mbi këtë, një trup i vetëm u shkon të gjithëve, dhe çdo goditje mbi të mbetet e paatribuar.
- Një mesazh me klikime dhe pa hapje është lexuar me siguri: imazhet bllokohen shumë më shpesh sesa lidhjet mbeten pa u klikuar. Lexojini të dy numëruesit veç e veç, në vend që t’i mblidhni.
- Kërkesa për klikime mbi një trup pa lidhje nuk regjistron fare asgjë: bajtet që dolën janë identike me një dërgim të pagjurmuar, dhe një rresht që pretendon të kundërtën nuk do të pajtohej me asgjë. E njëjta vlen për një mesazh pa trup për t’u rishkruar.
- OpenEmail i heq imazhet 1×1 nga posta që lexojnë përdoruesit e vet, përfshirë pikselin që dërgon vetë, dhe e regjistron hapjen vetë kur një mesazh shfaqet me imazhet të ndezura. Ajo goditje është
humanme klientOpenEmail. Me imazhet të fshehura nuk regjistrohet asgjë.
GET /tracking/{id} dhe GET /emails/{id}/tracking përgjigjen me 404 për një mesazh që nuk u gjurmua kurrë, në vend të një raporti bosh. Shprehjet «ne nuk regjistruam asgjë» dhe «askush nuk e hapi» janë përgjigje të ndryshme dhe nuk duhet të ndajnë të njëjtën përgjigje. Endpoint-i i listës mban vetëm mesazhe të gjurmuara, ndaj një i pagjurmuar thjesht mungon prej saj e nuk është i pranishëm me zero.
Të njoftohesh në vend që të pyesësh
Një hapje e numëruar nxit email.opened dhe një klikim i numëruar nxit email.clicked te çdo endpoint i abonuar, dhe të dyja shkruhen te gjurma e ngjarjeve të vetë mesazhit atje ku ai kaloi përmes këtij API-je. Asnjëra nuk nxitet për një skanues apo një proxy privatësie. Shtyrja e tyre do t’i mbushte regjistrin e marrësit pikërisht me trafikun që klasifikuesi ekziston për ta mbajtur jashtë numrave.
Një skedar që doli si lidhje shkarkimi raportohet në të njëjtën mënyrë. Një shkarkim i numëruar nxit email.downloaded dhe bie te e njëjta gjurmë, dhe i njëjti klasifikues i mban skanuesit dhe parapamësit e lidhjeve jashtë saj, kështu që numri janë njerëz. Ngarkesa e emërton skedarin (shareId, fileId, filename, mimeType, sizeBytes, url) me downloadCount, first dhe downloadedAt krahas fushave të klientit dhe vendndodhjes që mbart një klikim. recipient është gjithmonë null dhe attributed gjithmonë false: një lidhje shkarkimi është një URL i vetëm për çdo marrës të mesazhit, ndaj një shkarkim nuk mund t’i ngjitet njërit prej tyre.
Nga SDK-ja
const report = await openemail.tracking.get('msg_c5f21cc6bfec…')const cold = await openemail.tracking.list({ days: 30, opened: false })const stats = await openemail.tracking.getStats({ days: 30, offsetMinutes: -new Date().getTimezoneOffset(),})Çdo thirrje këtu është një lexim i thjeshtë dhe klienti e riprovon secilën më vete. get hedh një OpenEmailApiError, isNotFound i të cilit është true për një mesazh që nuk u gjurmua kurrë — dallimi që ia vlen të ruhet kudo ku ta çoni.