API Reference · Data Bank
Pagination
Series endpoints paginate observations, not areas, dates, series objects or curve snapshots. The default page size is 1,000 observations and the maximum is 5,000.
GET /v1/rates/series?dataset=bank_rate&from=2020-01-01&page_size=1000Read next_cursor. If it is non-null, request the next page from the same family endpoint:
GET /v1/rates/series?cursor=ENCODED_CURSOR_FROM_PREVIOUS_RESPONSEAlways URL-encode the cursor and send the Authorization header again. Continue until next_cursor is null. Do not stop because a page contains fewer series than expected, and do not assume the first page contains every curve point or metric.
What the Cursor Preserves
The token binds the authenticated identity, family, dataset, selectors, date filters, page size, original release and position. A new current release does not switch a continuation mid-query.
The token expires 24 hours after the first page; following a page does not extend that deadline. It is opaque: do not decode it as part of your application, edit it, log it publicly or reuse it with another customer's credentials.
You may repeat unchanged filters, but cursor-only continuation is less error-prone. Changed filters or page size fail. To make a new selection, start a new request without a cursor.
Permission is checked for every page. A revoked key or entitlement stops continuation. A cursor is not a guaranteed retention policy: if its release is no longer available, pagination cannot continue. No minimum long-term release-retention period is promised by this reference.
Reassembling a Result
Group observations by series_id, retaining that series' metadata. The same series may appear on several pages. Use (release_id, series_id, period) as a useful identity for an observation. Keep all pages from the same release.
Do not concatenate pages and count their series lengths as the number of distinct series. Do not assume a page contains exactly one month across every metric. Sort the final observations by period for charting when required.
If a network failure occurs, retry the same idempotent GET within the cursor lifetime. Merge by observation identity to prevent duplicate ingestion. If a cursor expires, restart against the same retained release_id if available; otherwise begin a clearly identified new extraction from current data.
Python Example
This example requires requests. It keeps credentials in an environment variable and fails on HTTP errors rather than accidentally treating an error payload as data.
import os
import requests
url = "https://api.valtaic.io/v1/rates/series"
params = {"dataset": "bank_rate", "from": "2020-01-01", "page_size": 1000}
headers = {"Authorization": f"Bearer {os.environ['VALTAIC_API_KEY']}"}
series_by_id = {}
release_id = None
with requests.Session() as session:
while True:
response = session.get(url, params=params, headers=headers, timeout=30)
response.raise_for_status()
page = response.json()
if release_id is None:
release_id = page["release_id"]
if page["release_id"] != release_id:
raise RuntimeError("Unexpected release change during pagination")
for item in page["series"]:
target = series_by_id.setdefault(item["series_id"], {
**item, "observations": []
})
target["observations"].extend(item["observations"])
cursor = page["next_cursor"]
if cursor is None:
break
params = {"cursor": cursor}The example omits application-specific persistence and retry/backoff logic. See Integration Guide for operational recommendations. Catalogue, areas and coverage are not observation-paginated routes.