الانتقال إلى المحتوى

The data service — our estimates, in your tools

Everything the platform publishes on its maps is available as data: a versioned REST/JSON API, CSV for spreadsheets and pandas, and an OData v4 feed that Excel and Power BI open natively. Every figure is an estimate made by cameras counting people on sand — the fields say how confident each number is and how much of the beach was actually observed, and you should read them.

01Authentication

Every request carries an API key in the Authorization header: Authorization: Bearer yk_…. Keys are issued by us when a data contract is agreed — there is no self-serve signup yet. A key is scoped to the countries the contract covers; sites outside that scope do not appear in any response.

Contact us to request a key. Trial keys exist so you can judge the data before committing.

Lost your key? We store only a hash of it, so nobody here — including us — can read it back. Enter your contact address at /keys/request and we will email a one-time link that issues a replacement. Collecting it retires the old key immediately, so update your scripts and scheduled refreshes at the same time.

02Endpoints

Base URL /api/data/v1. This path is a versioned contract: field names are stable, changes are additions.

  • GET /sites — the catalogue your key can see: id, slug, name, country, lat, lng, practicalCapacity, timezone.
  • GET /sites/{id}/readings?from&to&bucket=5m|1h|1d — the occupancy series, bucketed. Each bucket carries occupancy (0–1 of practical capacity), confidence, coverageFraction, estimated people and the number of raw samples behind it. Five-minute queries span at most 31 days per request; hourly and daily buckets carry whole seasons.
  • GET /sites/{id}/daily?from&to — per-day summaries: peak estimated people, mean occupancy, and the UTC hour the peak fell in.

JSON responses are an envelope {"data": […], "next": cursor|null} — pass ?cursor= to continue. Timestamps are ISO 8601 UTC.

03Honest numbers

The counts are estimates, and we publish them as such. Occupancy is derived from smoothed camera counts weighted by how much of the site each camera covers; peopleis that occupancy multiplied by the site's practical capacity, rounded. When coverageFraction is 0.4, six tenths of the beach was not observed in that bucket, and the estimate extrapolates. We do not publish accuracy claims; we publish the inputs you need to decide what the number is worth.

04Tiers and limits

  • Trial — 1,000 requests/day.
  • Standard — 20,000 requests/day.
  • Partner — fair use, agreed per contract.

Limits reset at UTC midnight. Requests over the limit receive HTTP 429 with a JSON error naming the limit and the reset time. Every request is metered per key, per day, per endpoint — the same numbers your invoice cites.

05curl

# The catalogue of sites your key can see
curl -H "Authorization: Bearer yk_YOUR_KEY" \
  "https://ystara.com/api/data/v1/sites"

# Hourly occupancy for one site, one week, as JSON
curl -H "Authorization: Bearer yk_YOUR_KEY" \
  "https://ystara.com/api/data/v1/sites/SITE_ID/readings?from=2026-08-01T00:00:00Z&to=2026-08-08T00:00:00Z&bucket=1h"

# The same rows as CSV
curl -H "Authorization: Bearer yk_YOUR_KEY" \
  "https://ystara.com/api/data/v1/sites/SITE_ID/readings?from=2026-08-01T00:00:00Z&to=2026-08-08T00:00:00Z&bucket=1h&format=csv"

06pandas

The CSV variant (append ?format=csv or send Accept: text/csv) loads straight into a DataFrame:

import pandas as pd

BASE = "https://ystara.com/api/data/v1"
HEADERS = {"Authorization": "Bearer yk_YOUR_KEY"}

# pandas reads the CSV variant directly — no client library needed
df = pd.read_csv(
    f"{BASE}/sites/SITE_ID/daily?from=2026-06-01&to=2026-09-01&format=csv",
    storage_options=HEADERS,
    parse_dates=["day"],
)
print(df.groupby(df["day"].dt.month)["peakPeople"].max())

07Excel and Power BI (OData)

The OData v4 feed at /odata/v1/ is read-only and made for the built-in connectors — no add-ins, no scripts:

Feed URL:   https://ystara.com/odata/v1/
Excel:      Data → Get Data → From Other Sources → From OData Feed
Power BI:   Get Data → OData feed

When asked to sign in, choose Basic; user name "ystara",
and your key (yk_…) as the password.

You will see three tables: Sites, Readings (hourly buckets,
last 31 days by default) and DailySummaries (last year by
default). Filters on siteId, country, bucketStart and day are
pushed to the server, e.g.:

  /odata/v1/Sites?$filter=country eq 'MA'&$count=true
  /odata/v1/Readings?$filter=siteId eq 'SITE_ID' and bucketStart ge 2026-08-01T00:00:00Z

The feed supports $filter (eq, ge, le, and), $select, $top (max 5,000), $skip, $orderby and $count. Anything else answers 501 with a sentence saying what is supported, rather than pretending.