Quickstart
The Skyfora API gives you Global Navigation Satellite System (GNSS) measurement data, reference station metadata, and network information. Use it in your own applications and workflows.
This guide shows how to create an API key, find your stations, and read measurement data.
1. Create an API key
Sign in to the Skyfora Portal and create an API key under your organization settings. The key is scoped to your organization and grants access to the stations and networks you are entitled to.
Include the key in every API request:
X-API-Key: your-api-key-here
2. List your stations
Find your stations before you query measurements. The stations endpoint returns metadata for every station your organization is entitled to. This includes the id that measurement queries need, and the display_name used across Skyfora products.
curl https://api.skyfora.com/api/v1/stations \
-H "X-API-Key: your-api-key-here"
Response:
{
"stations": [
{
"id": "4f9b1c2e-6a70-4a3e-9a4f-2d8f5b7c0e11",
"display_name": "BERG001",
"source_type": "cors",
"resolution_seconds": 30,
"country_code": "DE",
"latitude": 50.94,
"longitude": 6.96
},
{
"id": "7c2d9e40-1b5f-4c8a-8d3e-6f0a9b4c2d55",
"display_name": "SEED001",
"source_type": "cors",
"resolution_seconds": 30,
"country_code": "DE",
"latitude": 52.52,
"longitude": 13.41
}
],
"pagination": { "page": 1, "page_size": 20, "total_items": 2, "total_pages": 1 }
}
Use the id values when querying measurements in the next step.
You can filter stations by country, network, bounding box, or search term - see the Stations API reference for details.
3. Query measurements
Use the measurements endpoint to retrieve observation data for your stations. Specify a time range, one or more station ids, and the variables you want.
Available variables
The variables are sourced or derived from GNSS observations. The observation rate may differ for each station. Read resolution_seconds from GET /stations for the epoch interval of a given station.
| Variable | Description | Unit |
|---|---|---|
ztd |
Zenith Total Delay | mm |
ztd_sigma |
Zenith Total Delay uncertainty (standard deviation of the estimate) | mm |
pwv |
Precipitable Water Vapour | mm |
snr |
Carrier-to-noise density ratio (C/N0), per satellite and signal band | dB-Hz |
el |
Satellite elevation (per satellite) | degrees |
az |
Satellite azimuth (per satellite) | degrees |
prn |
Satellite pseudo-random noise (PRN) identifiers | - |
How Precipitable Water Vapour is derived: Skyfora estimates Precipitable Water Vapour (PWV) from Zenith Total Delay (ZTD). The estimate also uses surface pressure, air temperature at 2 m, and relative humidity. These meteorological inputs come from the nearest suitable observation, or from a numerical weather prediction (NWP) model when no observation is available. Skyfora adjusts them for the height of the GNSS site. The API response does not return these inputs. They are not necessarily measured at the GNSS station itself.
Data-quality filtering
Measurement responses are quality-filtered by default. The count in a JSON response counts only the filtered rows it returns.
Set "raw": true in the measurements request body to include observations excluded by the default filter. Use this mode for diagnostics.
Response formats
The API supports two response formats via content negotiation:
- NetCDF-4 (default) - binary scientific data format with CF-1.8 conventions. Returned when no
Acceptheader is set, or withAccept: application/x-netcdf. - JSON - returned when
Accept: application/jsonis set.
NetCDF-4 is the recommended format for data analysis workflows. It can be read directly by Python xarray, MATLAB, R ncdf4, and other NetCDF-compatible tools.
Download a NetCDF file
curl -X POST https://api.skyfora.com/api/v1/measurements/query \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key-here" \
-o measurements.nc \
-d '{
"start_time": "2026-03-20T00:00:00Z",
"end_time": "2026-03-21T00:00:00Z",
"station_ids": ["4f9b1c2e-6a70-4a3e-9a4f-2d8f5b7c0e11"],
"data_vars": ["ztd", "ztd_sigma", "pwv"]
}'
Fetch measurements as JSON
curl -X POST https://api.skyfora.com/api/v1/measurements/query \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: your-api-key-here" \
-d '{
"start_time": "2026-03-20T00:00:00Z",
"end_time": "2026-03-20T01:00:00Z",
"station_ids": ["4f9b1c2e-6a70-4a3e-9a4f-2d8f5b7c0e11"],
"data_vars": ["ztd", "ztd_sigma", "pwv"]
}'
To retrieve unfiltered observations for diagnostics, add "raw": true to the JSON body:
curl -X POST https://api.skyfora.com/api/v1/measurements/query \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-API-Key: your-api-key-here" \
-d '{
"start_time": "2026-03-20T00:00:00Z",
"end_time": "2026-03-20T01:00:00Z",
"station_ids": ["4f9b1c2e-6a70-4a3e-9a4f-2d8f5b7c0e11"],
"data_vars": ["ztd", "ztd_sigma"],
"raw": true
}'
Response:
{
"data": [
{
"timestamp": "2026-03-20T00:00:00.000Z",
"station_id": "4f9b1c2e-6a70-4a3e-9a4f-2d8f5b7c0e11",
"display_name": "BERG001",
"ztd": 2353.5,
"ztd_sigma": 4.0,
"pwv": 12.3
},
{
"timestamp": "2026-03-20T00:15:00.000Z",
"station_id": "4f9b1c2e-6a70-4a3e-9a4f-2d8f5b7c0e11",
"display_name": "BERG001",
"ztd": 2354.0,
"ztd_sigma": 4.0,
"pwv": 12.4
}
],
"count": 2
}
4. Analyze the data
Read NetCDF with Python
import xarray as xr
ds = xr.open_dataset("measurements.nc")
# Inspect the dataset. Stations are identified by station_id and display_name
print(ds)
# Convert to a pandas DataFrame and select one station
df = ds.to_dataframe().reset_index()
station = df[df.station_id == "4f9b1c2e-6a70-4a3e-9a4f-2d8f5b7c0e11"]
print(station.head())
Query multiple stations
curl -X POST https://api.skyfora.com/api/v1/measurements/query \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key-here" \
-o measurements.nc \
-d '{
"start_time": "2026-03-20T00:00:00Z",
"end_time": "2026-03-21T00:00:00Z",
"station_ids": ["4f9b1c2e-6a70-4a3e-9a4f-2d8f5b7c0e11", "7c2d9e40-1b5f-4c8a-8d3e-6f0a9b4c2d55"],
"data_vars": ["ztd", "pwv"]
}'
Access control
Your API key is scoped to your organization. You can only access stations and measurement data for networks your organization is entitled to. Requests for stations outside your entitlements will return a 403 error.
Limits
The API returns all observations matching your query in a single response. If the estimated result exceeds 150 MB, the request returns 413. If a query runs past the processing deadline, it returns 408.
As a rough guide, querying all 7 variables for 50 stations over 30 days produces approximately 60 MB. At 100 stations with the same parameters and time range, you would approach the limit. Numeric-only queries (ztd, ztd_sigma, pwv) are much smaller and can cover more stations and longer time ranges in a single request.
If your query exceeds a limit, split it into several requests. Divide by time range, or by groups of stations, then combine the results on your side.
Insight dashboard
The Skyfora Insight dashboard also plots every measurement variable the API offers: Zenith Total Delay, Zenith Total Delay uncertainty, Precipitable Water Vapour, satellite elevation, satellite azimuth, and carrier-to-noise density ratio. Your organization needs access to the matching parameters. Insight applies the same default data-quality filter as the API.