Documentation
Import historical Plausible analytics — api / integrations / plausible
Use Plausible's Site Settings → Imports & Exports → Export Data → Export to CSV export. Download the emailed ZIP, then open the website's AnalyticFast import settings, choose the ZIP, preview it, confirm its website and timezone, and import it. Administrators and owners can manage imports; viewers can inspect history.
Plausible's current export documentation, retrieved October 28, 2026, distinguishes full native-data exports from dashboard exports. Dashboard ZIPs contain truncated reports and are rejected. Full site-settings exports exclude data previously imported into Plausible. Scheduled raw-event/Parquet exports are also unsupported. The DataFast reference informed the upload/preview workflow; the format comes from Plausible.
Supported format
The exact filenames, headers and daily aggregate semantics follow Plausible's official export implementation, export tests, and CSV importer fixtures, fetched before implementation.
Files are root-level imported_<report>.csv, optionally ending in _YYYYMMDD_YYYYMMDD.csv. A nonempty imported_visitors report is required. Supported optional reports are sources, pages, entry pages, exit pages, locations, devices, browsers, and operating systems. Quoted headers, commas, escaped quotes, multiline fields, UTF-8 BOM, LF and CRLF are supported. Stored ZIP entries, streaming data descriptors and DEFLATE entries are supported.
The visitors report imports daily visitors, pageviews, visits, bounces and total visit duration. Plausible's duration is in seconds; native reporting uses milliseconds. Supported breakdowns include source/referrer, UTM source/medium/campaign/content/term, pages, hostname, entry/exit pages, country/region/city, browser, operating system and device. City values remain Plausible GeoNames IDs; region/OS/source labels retain the exported vocabulary. Older optional report variants without pageviews or browser/OS versions are accepted; missing metrics stay zero, and missing versions use an empty label. They cannot supply filtered metrics absent from their CSVs.
Custom events and properties CSVs are validated within the same resource limits, then skipped with preview warnings. Recreate goals separately. Channels, affiliate codes, revenue, refunds, customer identities, journeys, funnels, assisted revenue and live visitors cannot be reconstructed from these aggregates. Historical page/exit-page reports can lack engagement metrics; filtered bounce/session-duration figures should not be treated as complete for those reports.
Date overlap and duplicate policy
- Import only complete site-local days strictly before the first native session/event/retained rollup day, and before today. Preview identifies the accepted range and skipped rows. An export containing no eligible historical days is rejected.
- Full daily visitors totals are the authoritative historical overview. Breakdown files never add to the unfiltered overview totals.
- Published imports reserve their inclusive date interval. A different archive overlapping any part of that interval is rejected, including gaps within it. Delete the earlier import before replacing it. Nonoverlapping imports can coexist.
- A per-site semantic digest recognizes identical supported data despite ZIP recompression, row/header ordering or filename suffix changes. Repeat uploads return the existing import without duplicating counts. A fuller/different export of the same dates must replace the old import.
- Native data always takes precedence from its earliest recorded day onward. If older native events are added after an import, historical aggregates on/after that day are excluded. Native rows themselves are never deleted by an import.
- Preview is recalculated on confirmation. A changed file, reporting timezone or native cutoff requires another preview. Concurrent publication is protected by a database overlap trigger.
ZIPs do not reliably identify their website or timezone. The administrator must select the correct website and confirm the export uses that website's reporting timezone. Each import stores its timezone; changing the site's timezone excludes that import until the timezone is restored or the import is deleted and reimported appropriately. Aggregates cannot be accurately re-zoned.
Visitor estimates and reporting
Daily visitors are aggregate counts, not identities. Summing days counts returning people again. Summing source rows, browser versions, pages, locations or other groups can also count a person repeatedly. No synthetic visitors or sessions are created. Imported and native people cannot be deduplicated. Conversion rates and revenue per visitor use the resulting estimated visitor denominator; revenue amounts and attribution stay native.
Overview responses include historical metadata stating imported days/counts and these limitations. Breakdown rows with historical contributions include importedVisitors and visitorCountsAreEstimates. Daily, weekly and monthly chart buckets include historical counts. Hourly charts exclude historical values rather than inventing an hourly distribution; headline KPIs still include eligible full days. Partially selected local days exclude their historical aggregates. The all-time overview/breakdown range extends to the earliest published import.
Filtering within a single exported report works (for example, UTM source plus campaign). Cross-report combinations such as country plus source exclude imported data, since the necessary joint distribution does not exist. Unsupported filters/dimensions remain native-only. Overview metadata reports whether historical filters are supported. Existing dashboard, share-link and token entitlement checks continue to apply to analytics reads.
Limits and lifecycle
Uploads are limited to 8 MiB compressed, 12 MiB expanded, 4 MiB per file, 16 files and 25,000 CSV data rows across all reports. CSV fields are limited to 4,096 characters and records to 16,384 characters. Metrics must be finite nonnegative decimal numbers at most 10^12. Dates must be real YYYY-MM-DD calendar dates from 2000 through 2100, within any filename range. Each breakdown day must exist in daily visitors. Unknown files/columns, duplicate report files/aggregate keys, encrypted files, ZIP64/split archives, special files and filenames containing paths are rejected. Corrupt CRCs and deceptive expansion sizes are rejected.
No archive or raw CSV response is saved. Normalized daily aggregates are staged separately in D1, using bounded JSON insertion chunks. Only a successfully published import is visible in reports. A staging failure cleans that import up. A terminated request can leave an unfinished, invisible import in history: wait for a still-running request, or delete that entry before retrying. A lost response after publication is safe to retry. Deletion targets exactly one site/import ID and cascades only its aggregate rows. Site deletion also cascades imports. Import history lists the latest 50 entries; deleting an entry exposes older ones.
The importer does not increment event quotas or alter plan state. Worker/D1 execution limits can still stop a large request; such an import remains unpublished. Large exports exceeding the supported bounds need an offline/staged migration outside this importer; do not truncate a ZIP or invent missing visitors.
Integration contract
Apply migrations/1400_plausible_imports.sql before serving the changed report code. The lead mounts createImportsRouter() from src/worker/imports/router.ts at /api/sites, before the API catch-all, and renders ImportSettings({ siteId, canManage }) in site settings. This workstream intentionally does not edit the route table or settings page.
| Method | Path under /api/sites | Role / body |
|---|---|---|
| GET | /:id/imports | viewer; latest history, limits, timezone |
| POST | /:id/imports/plausible/preview | admin; raw ZIP, Content-Type: application/zip |
| POST | /:id/imports/plausible | admin; same raw ZIP plus X-Import-Preview token from preview |
| DELETE | /:id/imports/:importId | admin; removes only that import |
All routes independently require browser authentication and site access. Cookie mutations use the existing CSRF protection. Foreign sites are rejected before reading the upload. Imports are settings operations; historical analytics use the existing entitled overview/breakdown endpoints. Duplicate imports return HTTP 200; new imports return 201; unsupported inputs return 400/415; limits return 413; stale previews, overlaps and active staging return 409.
The small MIT-licensed fflate dependency supplies incremental raw DEFLATE. Directory validation, bounded input/output handling, CRC verification, CSV parsing, schema validation and persistence are implemented here. D1 publication relies on a single atomic status change, with a completeness/overlap trigger; see Cloudflare's D1 transaction guarantees.
Questions, answered.
How do I use import historical plausible analytics with AnalyticFast?
Follow the Import historical Plausible analytics instructions on this page using your own website’s Site ID and configuration. Verify a real event before relying on the reports.
Where can I get setup help?
Contact support@analyticfast.com with the website domain and a redacted description. Do not send API tokens, signing secrets or personal customer data.