Download File / Folder
Download files from your shard node by specifying the path as a query parameter. Folders can only be downloaded as zip archives.
GET
/fso
FSO stands for "file system object" - in this case, a file or folder
Important Notes
- • All paths must start with
/(absolute paths only) - • Folders can only be downloaded as zip archives (use
/fsosendpoint)
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| x-user-api-key | string | Yes | Your authentication API key |
| Content-Type | application/octet-stream | Optional | MIME type for binary data |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| path | string | Yes | Absolute path of the file to download (must start with /) |
Example Request
func DownloadFile(pathOnShard string, localFilePath string) {
url := fmt.Sprintf("%s/fso?path=%s", SHARD_NODE_URL, url.QueryEscape(pathOnShard))
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
panic(fmt.Errorf("could not create download request: %w", err))
}
req.Header.Set("x-user-api-key", API_KEY)
req.Header.Set("Content-Type", "application/octet-stream") // optional
client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
panic(fmt.Errorf("error downloading file: %w", err))
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
panic(fmt.Sprintf("Download failed with status %d: %s", resp.StatusCode, string(body)))
}
file, err := os.Create(localFilePath)
if err != nil {
panic(fmt.Sprintf("Could not create file on local disk %w", err))
}
defer file.Close()
_, err = io.Copy(file, resp.Body)
if err != nil {
panic(fmt.Sprintf("Could not copy resp body into disk %w", err))
}
}
async function downloadFile(pathOnShard: string, localFilePath: string): Promise<void> {
const url = `${SHARD_NODE_URL}/fso?path=${encodeURIComponent(pathOnShard)}`;
const res = await fetch(url, {
method: 'GET',
headers: {
'x-user-api-key': API_KEY,
'Content-Type': 'application/octet-stream'
}
});
if (res.status !== 200) {
const body = await res.text();
throw new Error(`Download failed with status ${res.status}: ${body}`);
}
const data = await res.arrayBuffer();
await fs.promises.writeFile(localFilePath, new Uint8Array(data));
}
Response Status Codes
| Code | Status | Description |
|---|---|---|
| 200 | Success | File downloaded successfully |
| 400 | Bad Request | Invalid request parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 404 | Not Found | File doesn't exist at path |
| 5xx | Server Error | Internal server error - check response body for details |
Download Multiple Files/Folders as Zip
Download multiple files or folders as a single zip archive by specifying paths in the request.
GET
/fsos
Download multiple FSOs (file system objects) as a zip archive
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| paths | string | Yes | List of absolute paths to download separated by null terminator (\x00) |
| archiveName | string | No | Name for the resulting zip file (default: "archive.zip") |
Example Request
func DownloadFilesAsZip(paths []string, localZipPath string) {
pathsParam := strings.Join(paths, "\x00")
url := fmt.Sprintf("%s/fsos?paths=%s",
SHARD_NODE_URL,
url.QueryEscape(pathsParam))
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
panic(fmt.Errorf("could not create download zip request: %w", err))
}
req.Header.Set("x-user-api-key", API_KEY)
client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
panic(fmt.Errorf("error downloading zip file: %w", err))
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
panic(fmt.Sprintf("Download zip failed with status %d: %s", resp.StatusCode, string(body)))
}
file, err := os.Create(localZipPath)
if err != nil {
panic(fmt.Sprintf("Could not create zip file on local disk: %w", err))
}
defer file.Close()
_, err = io.Copy(file, resp.Body)
if err != nil {
panic(fmt.Sprintf("Could not copy zip data to disk: %w", err))
}
}
async function downloadFilesAsZip(paths: string[], localZipPath: string): Promise<void>{
const pathsParam = paths.join("\x00");
const url = `${SHARD_NODE_URL}/fsos?paths=${encodeURIComponent(pathsParam)}}`;
const res = await fetch(url, {
method: 'GET',
headers: { 'x-user-api-key': API_KEY }
});
if (res.status !== 200) {
const body = await res.text();
throw new Error(`Download zip failed with status ${res.status}: ${body}`);
}
const data = await res.arrayBuffer();
await fs.promises.writeFile(localZipPath, new Uint8Array(data));
}
Response Status Codes
| Code | Status | Description |
|---|---|---|
| 200 | Success | Zip file downloaded successfully |
| 400 | Bad Request | Invalid request parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 404 | Not Found | One or more files don't exist |
| 5xx | Server Error | Internal server error - check response body for details |