Satellite Data Access Developer Guide
This guide is intended for developers building applications that depend on satellite data. It explains how to retrieve the available filters from the satellite data service platform, query the latest or historical data, and download the actual data files through the platform API.
Public platform URL:
https://sat-eslab.dgut.edu.cn/data-dashboardWorkflow Overview
- Sign in to the satellite data service platform.
- Create an API key from the user profile page.
- Call the platform API to retrieve the available filters.
- Call the platform API to query the data list.
- Read the
idfrom the response. - Call the platform download API with the
idto get a temporary download URL for the file.
The platform API returns data metadata rather than the contents of satellite data files. The actual files are accessed through the platform download API, which provides temporary download URLs.
Request an API Key
- Open the platform:
https://sat-eslab.dgut.edu.cn/data-dashboard- Sign in to your account.
- Open the user profile page.
- Click
Createin theAPI Keyssection. - Save the complete API key immediately after it is displayed. The complete key is shown only once.
- Include the API key in the HTTP header of subsequent requests:
Authorization: Bearer <YOUR_API_KEY>An API key is a long-lived credential. Store it as you would any other secret and do not commit it to a source code repository. Its permissions are inherited from the role of the user account that created it. Data types that the user is not authorized to access will not be returned by the API.
Retrieve Available Filters
Endpoint:
GET https://sat-eslab.dgut.edu.cn/data-dashboard/api/filtersExample:
curl \
-H "Authorization: Bearer <YOUR_API_KEY>" \
"https://sat-eslab.dgut.edu.cn/data-dashboard/api/filters"The response contains the currently available query filters, such as satellite, sensor, product, region, resolution, and file type. The type options are filtered according to the current user's permissions.
Example response:
[
{
"key": "satellite",
"options": ["FY4B"]
},
{
"key": "type",
"options": ["L0", "L1"]
}
]Query the Data List
Endpoint:
GET https://sat-eslab.dgut.edu.cn/data-dashboard/api/rawCommonly used query parameters:
| Parameter | Description |
|---|---|
satellite | Satellite, for example FY4B |
sensor | Sensor |
type | Data level, for example L0 or L1 |
product | Product type |
region | Region |
resolution | Resolution |
extension | File extension |
start_time | Query start time in ISO 8601 format |
end_time | Query end time in ISO 8601 format |
offset | Pagination offset |
limit | Number of items returned per request |
Example:
curl \
-H "Authorization: Bearer <YOUR_API_KEY>" \
"https://sat-eslab.dgut.edu.cn/data-dashboard/api/raw?satellite=FY4B&type=L1&start_time=2026-05-01T00:00:00.000Z&end_time=2026-05-02T00:00:00.000Z&offset=0&limit=100"Example response:
[
{
"id": 123,
"file_key": "path/to/object/file.HDF",
"satellite": "FY4B",
"sensor": "AGRI",
"type": "L1",
"product": "FDI",
"region": "DISK",
"resolution": "4000M",
"extension": "HDF",
"start_time": "2026-05-01T00:00:00.000Z",
"end_time": "2026-05-01T00:15:00.000Z"
}
]Note: The file_key in the response is an S3 object key, not a public URL that can be downloaded directly.
Poll for the Latest Data
Polling causes more repeated queries and requires the client to maintain time windows and deduplication state. It is not recommended for continuous data delivery. Use /api/raw polling only as a compatibility option when the runtime cannot maintain an SSE connection.
Compatibility strategy:
- Record the greatest timestamp already processed locally, such as
start_timeorend_time. - Query a new time window at a fixed interval.
- Keep a small overlap between query windows to avoid missing records that are written to the backend with a delay.
- Deduplicate records using
idorfile_key. - Update the local checkpoint after each successful processing cycle.
Example time window:
Last processed through: 2026-05-01T10:00:00.000Z
Next query: start_time=2026-05-01T09:55:00.000Z&end_time=current timeWith a five-minute overlap, data that reaches the backend late can still be collected. The client must deduplicate results using id or file_key.
Python polling example:
import time
from datetime import datetime, timedelta, timezone
import requests
BASE_URL = "https://sat-eslab.dgut.edu.cn/data-dashboard"
API_KEY = "<YOUR_API_KEY>"
headers = {
"Authorization": f"Bearer {API_KEY}",
}
seen_file_keys = set()
checkpoint = datetime.now(timezone.utc) - timedelta(hours=1)
while True:
start_time = checkpoint - timedelta(minutes=5)
end_time = datetime.now(timezone.utc)
params = {
"satellite": "FY4B",
"type": "L1",
"start_time": start_time.isoformat().replace("+00:00", "Z"),
"end_time": end_time.isoformat().replace("+00:00", "Z"),
"offset": 0,
"limit": 100,
}
response = requests.get(
f"{BASE_URL}/api/raw",
headers=headers,
params=params,
timeout=30,
)
response.raise_for_status()
items = response.json()
for item in items:
file_key = item["file_key"]
if file_key in seen_file_keys:
continue
seen_file_keys.add(file_key)
print("new data:", file_key)
item_time = datetime.fromisoformat(
item["end_time"].replace("Z", "+00:00")
)
checkpoint = max(checkpoint, item_time)
time.sleep(60)Choose a polling interval that suits your use case and never issue requests continuously without a delay. Migrate to SSE when possible. For large historical backfills, use pagination and retrieve data in segments using larger time windows.
Query Historical Data
Historical and latest-data queries use the same /api/raw endpoint. Specify the required start_time and end_time values.
Example: query all data for May 1, 2026.
curl \
-H "Authorization: Bearer <YOUR_API_KEY>" \
"https://sat-eslab.dgut.edu.cn/data-dashboard/api/raw?start_time=2026-05-01T00:00:00.000Z&end_time=2026-05-02T00:00:00.000Z&offset=0&limit=100"Use pagination when the result set is large:
offset=0&limit=100
offset=100&limit=100
offset=200&limit=100
...Continue until the endpoint returns an empty array or fewer items than limit.
Download Data Files
The file_key returned by the query endpoint can be used to obtain a file download URL. No S3 credentials are required; the platform generates temporary download URLs on your behalf.
Single File Download
Endpoint:
GET https://sat-eslab.dgut.edu.cn/data-dashboard/api/download/single?id=<ID>Example:
curl \
-H "Authorization: Bearer <YOUR_API_KEY>" \
"https://sat-eslab.dgut.edu.cn/data-dashboard/api/download/single?id=123"Example response:
{
"url": "https://s3.prod.eslab.org.cn/..."
}The returned url is a temporary download link valid for 1 hour. GET this link directly to download the file.
Python download example:
import requests
BASE_URL = "https://sat-eslab.dgut.edu.cn/data-dashboard"
API_KEY = "<YOUR_API_KEY>"
file_id = "123"
resp = requests.get(
f"{BASE_URL}/api/download/single",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"id": file_id},
)
resp.raise_for_status()
download_url = resp.json()["url"]
# Download the file
file_resp = requests.get(download_url)
with open("file.HDF", "wb") as f:
f.write(file_resp.content)Migration Guide: From S3 Direct Access to Platform API
S3 direct access is being deprecated. Please migrate to the platform download API as soon as possible. S3 credentials will be removed in a future release.
If your code uses boto3 to access S3 directly, follow these steps to migrate:
Before (direct S3 access):
import boto3
s3 = boto3.client(
"s3",
endpoint_url="https://s3.prod.eslab.org.cn",
aws_access_key_id="...",
aws_secret_access_key="...",
)
s3.download_file("satellite-dataset-eslab", "path/to/file.HDF", "file.HDF")After (platform API):
import requests
BASE_URL = "https://sat-eslab.dgut.edu.cn/data-dashboard"
API_KEY = "<YOUR_API_KEY>"
# 1. Query data to get the id
resp = requests.get(
f"{BASE_URL}/api/raw",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"satellite": "FY4B", "type": "L1", "limit": 1},
)
items = resp.json()
file_id = items[0]["id"]
# 2. Get download URL
resp = requests.get(
f"{BASE_URL}/api/download/single",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"id": file_id},
)
download_url = resp.json()["url"]
# 3. Download the file
with open("file.HDF", "wb") as f:
f.write(requests.get(download_url).content)Key changes:
| Item | Old approach | New approach |
|---|---|---|
| Dependency | boto3 | requests (or any HTTP client) |
| Credentials | S3 access_key + secret_key | Platform API Key |
| File identifier | file_key (S3 object key) | id (database record ID) |
| Download flow | Direct S3 access | Get temporary URL, then download |
FAQ:
-
Q: I'm still using
file_key, what should I do? A: When querying/api/raw, the response includes bothidandfile_key. Switch to usingidwith/api/download/single. -
Q: Do I need to migrate batch downloads too? A: Yes. Use
/api/get-download-file-urlsfor batch downloads. The returned URLs can be downloaded directly with GET, no S3 credentials needed. -
Q: My code has hardcoded S3 credentials. What do I change? A: Remove all S3-related code and credentials. Use the platform API Key instead. It's more secure and easier to maintain.
Common Status Codes
| Status code | Description |
|---|---|
200 | Request succeeded |
401 | No valid authenticated session or API key was provided |
403 | The current user's role is not authorized to access the requested data type |
5xx | Backend service error; retry later |
Notes
- API key permissions follow the user's role, so the visible data scope may differ between accounts.
/api/rawreturns a list of metadata, not file contents.- Download URLs returned by
/api/download/singleexpire after 1 hour; request a new one when needed. Use theidfrom/api/rawresponse. - Polling clients must deduplicate records; use
file_keyorid. - Paginate historical bulk retrievals to avoid oversized requests.
- Use UTC ISO 8601 timestamps consistently, for example
2026-05-01T00:00:00.000Z.