The HonestTag export format
By the HonestTag team ยท Published August 31, 2026
Your data is yours. From the Orders tab in the app you can download your full attribution history and per-order proof at any time, in the documented format on this page. The export works on every plan and in every billing state, including after you cancel. Canceling never deletes your data; only uninstalling starts Shopify's formal deletion process.
Where to find it
Open the app, go to the Orders tab, and use the Export everything card. Two buttons download two files: daily history and order proof. Both are NDJSON: plain text, one JSON object per line, readable by any spreadsheet importer, script, or warehouse loader.
The three parts
- manifest: one line describing the export. It names the format (
honesttag-portability), the format version, the parts, and the exact retention windows that bound what you get. - daily: every retained day-grain row, plus every non-day-grain row we hold for your store. Day-grain line types:
metrics_day(your store's own order metrics per day, including the per-platform first-click counts),spend_day(pulled spend and each platform's own reported conversions per account per day),spend_campaign_day(the same, per campaign),fcnc_campaign_day(our measured first-click new-customer orders per campaign per day),delivery_day(conversions HonestTag delivered per platform per day),delivery_campaign_day(the same, per campaign),delivery_outcome_day(daily counts by reason for purchases or batches not counted as delivered, including terminalpartial_acceptbatches),email_touch_day(email and SMS click counts per day),email_claims_day(your email platform's own claimed orders and value per day),link_stats_day(clicks and orders per tracking link per day),annotation(each note you added to the trends chart, by its date), andverdict(each stored weekly verdict with the figures that produced it, by week start). Then the rows that are not day-grain:link(each tracking link you created, with its UTM set),spend_manual(each manual spend line you typed in),metric_target(each target you set, store-wide or per channel),cohort_member,cohort_revenue,cohort_revenue_channelandcohort_revenue_dim(the cohort curves behind Cohorts and payback), andemail_health_address(the delivery state of each address you asked us to alert). Each page starts with a manifest line (with its part and row count added) that lists these line types and names every table we hold that is not in the export, with the reason, so a file saved from the in-app button holds one manifest line per page. This part is paged too, by day: each page holds every day-grain row for a run of days, up to 5,000 rows per page, so a store with many campaigns on several platforms gets more, smaller pages rather than one page that fails. A page never splits a day: every row of a given day, in every day-grain table, is on the same page. The non-day-grain rows come on the first page. The last line of each page is apageline that states the day window the page covers (fromandto); when it carriesnext_cursor, request the next page with?cursor=set to it (the same value is in theX-HT-Cursorresponse header), and when it sayslast_pageyou have everything. If one day alone holds more rows than a page, that day is served whole and the page line saysover_budget. The in-app button follows the pages for you and saves one file. - orders: one
orderline per tracked order, paged. Page size is not fixed: it is computed from how wide your store's per-order proof actually is, so a store with many ad accounts or a long refund history gets more, smaller pages rather than one page that fails. Each line carries the recorded conversion value and, on paid plans, the full proof record: the classification and its inputs, the click that was credited, consent state, every delivery receipt, refund adjustments, and a plain-English explanation. The last line of each page is apageline; when it carriesnext_cursor, request the next page with?cursor=set to it (the same value is in theX-HT-Cursorresponse header), and when it sayslast_pageyou have everything. The in-app button follows the pages for you and saves one file.
The raw event archive
Every beacon, pageview and order event HonestTag records for your store is also kept as a raw analytics row for three months. HonestTag copies your store's rows into your own archive, one file per UTC day, once the day has been over for a full day, and keeps each file for 25 months, the same as daily history. The archive works on every plan. You'll find it on the same Export everything card, under Raw event archive.
- The file.
honesttag_events_YYYY-MM-DD.ndjson.gz, gzip-compressed NDJSON, one row per line. Every line has the same keys in the same order:timestamp(UTC),_sample_interval,index1(your store's id),blob1toblob20anddouble1todouble20.blob1names the event, for examplepageview,pixel,conversionordelivery_failure. Apageviewrow, or apixelrow whoseblob3ispage_viewed, withbotinblob16is a page load from a browser that identified itself as a known crawler: it stays in the archive and is not counted toward your pageviews. - Sampling. The rows are what our event store returned. The event store samples a busy store on write and can return a lower-resolution copy for a large query. Each row's
_sample_intervalis how many events it stands for, so to count events, add up_sample_intervalrather than counting lines. Each day is queried in windows of at most 10,000 rows. A day that still does not fit is not stored, and the gap is reported to us, so a stored day is never a cut-off one. - What changes on the way in. Any value that is a web address keeps its scheme, host and path and loses its query string and fragment, because a referring page's query string can carry what a shopper typed into a search box.
- Checking a download. The list in the app shows each day's row count, weighted event count, sampled rows and SHA-256. The download carries the same SHA-256 in its
X-HT-SHA256header, andsha256sumon the file you saved should print it. - Customer erasure. When Shopify sends a customer erasure request, every archived day is rewritten without the rows that carry that customer's visitor ID or order IDs, and days archived later are written without them. The list shows each erasure with the files it rewrote and the rows it removed, never the IDs themselves. A rewritten day gets a new SHA-256, and the list shows the new one.
- Before the archive existed. The first run copies back up to 85 days, inside what the event store still holds, and never to a day before your store installed HonestTag.
What is never in it
No customer email addresses, phone numbers, names, or addresses appear in an export or the analytics data plane. The one direct identifier the file does carry is your own: the email_health_address lines hold the addresses you gave us for alerts, so that you get them back too. Raw Shopify webhook payloads may contain contact data while held in the durable processing inbox. Successful payloads are cleared after processing, and failed dead-letter payloads are purged within 30 days. Identifiers in proof records are click ids, hashed values, and random visitor ids. The export contains your store's data and nothing from any other store.
How long the export stays available
- Canceling a plan deletes nothing. Reporting locks to the free Mirror view, but the export keeps working for as long as the app stays installed.
- Per-order proof is kept for 400 days from each order. Orders older than that have their recorded values in the daily history but no proof record.
- Daily history is kept for 25 months. Campaign-level detail is kept for 13 months.
- The raw event archive keeps each day's file for 25 months.
- Uninstalling ends it. Shopify sends us the formal deletion request about 48 hours after uninstall, and we then delete the store's data. Export before you uninstall.
The free plan's honest limit
The free Mirror stores aggregates, and it does not write per-order proof records. On the free plan the orders part carries each order's recorded conversion values, with a note in place of the proof. Paid plans and the trial write the full proof record for every order from the day they start.
Versioning
The manifest line carries a format version, currently 1. If the format ever changes shape, the version number changes with it and this page documents both. Lines you do not recognize are safe to skip; new line types will only ever be added, not silently redefined.