Bulk exports
Exports are for data too large for a paged query. You create a job, poll it, then download its files. The request fields and response shapes are in the API reference; this page explains the workflow and what to expect.
Create a job
H="Authorization: Bearer $VEINMESH_API_KEY"
API=https://data.cyberun.cloud
curl -s -H "$H" -H "Content-Type: application/json" \
-X POST "$API/v2/exports" \
-d '{
"dataset": "book.snapshot",
"symbols": ["SHFE.rb2701", "SHFE.rb2705"],
"from_day": "2026-09-01",
"to_day": "2026-10-20",
"format": "parquet"
}' | jq '{export_id, status}'
The answer is a job with an export_id and a status: queued, running,
done, failed or expired. The job belongs to the key that created it.
Follow it
curl -s -H "$H" "$API/v2/exports/<export_id>" | jq '{status, rows, files, error}'
While the job is running, pending shows the instrument-days still to read.
Poll a few seconds apart; do not create the same job repeatedly.
When it is done, the response lists:
rows: total rows written;files: one or more files with their index, row count and SHA-256;partitions: the partition versions the job read, for reproducibility.
Download
GET /v2/exports/{export_id}/files/{file_index}
Files are streamed through the gateway; you never receive a bucket URL. Use the file index from the job response.
- If the job is still running, the download answers
503 data_pending. - If the job has expired, files answer
404 not_found. - If the file index is outside the job's file list,
404 not_found.
Formats and size
parquet: typed columns, decimals asDECIMAL(38,9), timestamps in UTC nanoseconds.csv: one header row; list fields become one column per level (bid_px_1,bid_px_2, …).
A large job is split into several files. Download every file; the row counts in the job are the authoritative total. Exports stay available for a limited time after they complete; see Limits.
What you can export
The job's dataset, symbols and range are validated when you create it:
- the dataset must be one the instrument has;
- the symbols must resolve on the range's
as_ofday; a continuous symbol (.main,.cN) is resolved per trading day into contract segments (use one continuous symbol per export; instant ranges are not accepted). Rows keep the continuoussymbol;instrument_idis the resolved contract and changes at a roll; - the range must be within the export limits.
See Limits for symbol counts, range and retention.
Python
job = client.export("book.snapshot", ["SHFE.rb2701", "SHFE.rb2705"],
from_day="2026-09-01", to_day="2026-10-20", format="parquet")
df = job.wait().to_pandas() # downloads and combines the files
files = job.download("./data") # or keep the files
job.wait() polls until the job is done; client.get_export(id) reopens a job
from another process. to_pandas(exact=True) keeps Decimal values.
Failures
A failed job carries an error string. Submit it again if the range is still
needed; a failed job does not retry itself. A not_found for the job means the
id is wrong or the key does not own it.