X-Eolas-Notice header (trial row cap and
end date, "large pulls are paginated and slow on trial", Free-plan sunset) is
now shown once per R session as a warning of class eolas_plan_notice.
Silence it with suppressWarnings(..., classes = "eolas_plan_notice").eolas_key_save() / eolas_key_status() print your plan and any trial
notice (via GET /v1/me). This is best effort: offline it is skipped
silently, and EOLAS_NO_NOTICE=1 turns it off.eolas_plan_error condition. Plan refusals now abort with class
eolas_plan_error, which carries $code, $status and $upgrade_url.
bulk_not_in_plan (403) means bulk and the changelog aren't in the trial.
trial_expired (402) means the trial has ended and metadata still works.
trial_soft_cap (429) means the trial allowance is used up. Catch it with
tryCatch(..., eolas_plan_error = function(e) ...).Default API host is https://api.eolas.nz. EOLAS_BASE_URL still overrides
it. https://api.eolas.fyi keeps serving. Signup, pricing, and docs links point
at eolas.nz. [email protected] is unchanged. Version moves 1.11.0 -> 1.13.0
to line up with eolas-data.
Plan-cap truncation is now visible. eolas_get() / eolas_download() read the
server's X-Eolas-Truncated / X-Plan-Row-Cap headers. A capped response now
warns, stamps eolas_meta(df)$truncated / $row_cap, prints TRUNCATED in the
dataset header, and says explicitly that limit = N on a capped slice is the
latest N within that file-order slice, not the dataset's most recent N.
Previously the 50k Free-plan slice was returned silently as if it were the whole
table. eolas_download() also now actually forwards limit (it read a
non-existent field and dropped it). (C22)
eolas_sync_bulk() stamps the snapshot actually received. The sidecar and
current_snapshot_id now come from X-Snapshot-Version on the final GET response
(after any 302 to the monthly artifact), not from the HEAD, which reports the live
id even when the live artifact is not materialised. A redirect that lands on the
artifact already on disk is reported as "unchanged" with no body download. New
freshness_resolved result field and sidecar head_snapshot_id /
freshness_resolved fields. (C23)
Client mirror of the live-data 413 guard matches the server rule (2026-08-30).
On a >100,000-row or geometry table with no start/end date filter the API
now serves a live pull only as a slice of 0 < limit <= 10000 rows; NULL,
0 and anything larger are refused alike (a positive limit was never a
server-side back door). .eolas_live_pull_blocked() gains limit = and the new
.eolas_live_slice_allowed() encodes the exception, so
eolas_get(name, limit = 50000) on such a table is served from the bulk cache
and trimmed client-side instead of erroring with 413. eolas_download() docs
corrected: only 1..10000 is accepted on those tables. (C2/C3 client mirror)
eolas_pivot_longer() / eolas_pivot_wider() — client-side long/wide reshape.
Explicit functions (never called automatically by eolas_get()). They read the new
server-side layout metadata (long/wide/feature/entity plus id/value/measure
columns) and refuse rather than guess -- an error when a table has no layout
metadata, or a feature/entity layout, or a geometry column present (the discipline
that removed eolas_plot()). eolas_pivot_longer() reattaches each measure's
series_id on the melt; eolas_pivot_wider() aborts on non-unique
(id, names_from) keys (with a values_fn escape hatch) instead of silently making
list-columns. Both re-declare the reshaped frame's new layout so longer<->wider
round-trips. Version jumps 1.9.1 -> 1.11.0 to re-align with eolas-data.geometry = FALSE now skips the column at READ time, not after. Previously
the whole Parquet was read -- including the WKT -- and the column was dropped
afterwards, paying the full parse and peak memory for data immediately
discarded. eolas_get_local() now passes a col_select projection to
arrow::read_parquet(), so those column chunks are never decoded, and the
entire sf/sfarrow/WKB conversion path is skipped. Geometry is typically ~95% of
a spatial layer's bytes.eolas_get_local() gains a geometry argument, mirroring eolas_get().tidyselect (already an indirect arrow dependency).Version jumps 1.4.0 -> 1.9.0 to clear a band of PyPI versions (1.5.0-1.8.0)
burned by yanked May-2026 uploads of the sibling eolas-data package. Yanked
filenames are permanently reserved, so those numbers can never be published
again. Both clients move together to keep their versions aligned.
eolas_get(geometry = FALSE) omits the geometry_wkt column. Two-thirds
of eolas datasets (1017/1536) carry geometry, and on TA/RC boundary tables the
WKT dwarfs the attributes you actually wanted. The column is now projected away
at the API's storage layer, so it is never read from S3 or transferred -- this
cuts I/O, not just payload. Responses carry X-Eolas-Geometry-Omitted: true.eolas_get("some_boundary_table") was diverted to a bulk download. With
geometry = FALSE the client keeps such calls on the live path, matching the
server's relaxed guard. The row-count trigger is unchanged -- dropping a column
does not reduce row count.geometry = FALSE is honoured on the bulk-routed path too. A spatial table
over the 100k-row threshold stays blocked even with geometry = FALSE, so the
call routes to the bulk cache -- which has no server-side projection. The flag
was dropped at that hand-off, so the caller silently received the full
geometry-bearing file and, with as_sf = NULL, an auto-converted sf object.
Found in peer review.geometry = FALSE with as_sf = TRUE now errors: there would be no geometry
to convert.eolas_get() first tries
the Arrow wire format, then falls back to JSON. A transport failure (timeout /
connection / DNS) on the Arrow attempt was swallowed and retried as JSON, so an
unreachable host paid the request timeout twice (~2x latency, ~240s at the
default budget). Transport failures are now re-raised immediately after the
first attempt; the JSON fallback is still used when a server simply does not
speak Arrow.EOLAS_BASE_URL environment variable is now honoured. The default API
base was previously a hardcoded literal, so setting EOLAS_BASE_URL (e.g. to
point at a dev/staging host) had no effect. It is now read at load, so
EOLAS_BASE_URL=... R or an .Renviron entry selects the host. A per-call
override is still the explicit base_url= argument.Hotfix release addressing issues found in the 2026-07-05 client-library audit.
httr2::req_perform_connection() (added in httr2 1.1.0) for all streaming
downloads, but declared only httr2 (>= 1.0.0). On systems with a pre-existing
httr2 1.0.x the install "succeeded" and then every bulk / large / geospatial
download crashed with 'req_perform_connection' is not an exported object. The
dependency floor is now httr2 (>= 1.1.0).httr2::req_timeout() to every request
builder (data, bulk, changelog). A black-holed connection can no longer hang the
caller indefinitely.cf-ray when present)
instead of dumping the multi-kilobyte HTML body into the error.eolas_download_bulk() rejects unknown arguments. A misspelled argument (e.g.
dest_dir= instead of path=) now errors instead of being silently ignored.freshness help and the 402 error message
no longer claim Free plans get a monthly bulk snapshot — bulk download is a
Pro/Enterprise feature and Free keys receive HTTP 402 (query datasets with
eolas_get() instead).arrow/sf may compile from source; documents the Posit Package
Manager / r2u binary path.