SDX API Documentation

Storage Data eXchange • Version 1.0.0

Welcome to the official documentation for the Storage Data eXchange (SDX) API by Shulker. SDX is an advanced object storage technology that enables blazing-fast uploads to public nodes (buckets) distributed globally.

With SDX, you can upload files of up to 1TB using chunked uploads, create folders (sub-buckets) for better organization, and manage your objects through a comprehensive RESTful API. All responses are in standard JSON format.

Chunked Uploads (5MB chunks)
Resume Support
Folder Management
Up to 1TB Files

Authentication

The SDX API uses a simple key-based authentication system. Every request must include your unique key as a URL query parameter.

Authentication Parameter
?key=your_sdx_key_here

Security & Node Assignment

Your SDX key is tied to a specific node (e.g., in0). The API will verify that your key matches the node you're accessing. You can find your API endpoint URL in your SDX Management Panel.

Without a valid key, the API will return a 400 Bad Request error.

Endpoint URL

The API endpoint URL varies based on your assigned node (bucket). You can find your specific endpoint in your SDX Management Panel. Here's an example for the in0 node:

Example Endpoint (in0 node)
https://node-in0-bucket.shulker.in/

Important

Always use your actual endpoint URL from your management panel. The example above is for illustration purposes only.

API Endpoints

The SDX API provides comprehensive file management capabilities through various action endpoints. All endpoints use the action query parameter to specify the operation.

Initialize Upload

Initialize a chunked file upload. This endpoint validates storage space and prepares the system for receiving file chunks.

POST /?key=YOUR_KEY&action=upload-init&path=/

Parameters

Parameter Type Description
fileName String Name of the file to upload
fileSize Integer Total file size in bytes (max 1TB)
totalChunks Integer Number of chunks (5MB each)
mimeType String File MIME type (optional)

Example Requests

JavaScript
Python
cURL
async function initializeUpload(file, sdxKey, path = '/') {
    const totalChunks = Math.ceil(file.size / (5 * 1024 * 1024));
    
    const formData = new FormData();
    formData.append('fileName', file.name);
    formData.append('fileSize', file.size);
    formData.append('totalChunks', totalChunks);
    formData.append('mimeType', file.type);
    
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=upload-init&path=${path}`,
        {
            method: 'POST',
            body: formData
        }
    );
    
    return await response.json();
}
import requests
import math

def initialize_upload(file_path, sdx_key, path='/'):
    file_size = os.path.getsize(file_path)
    file_name = os.path.basename(file_path)
    total_chunks = math.ceil(file_size / (5 * 1024 * 1024))
    
    data = {
        'fileName': file_name,
        'fileSize': file_size,
        'totalChunks': total_chunks,
        'mimeType': 'application/octet-stream'
    }
    
    response = requests.post(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=upload-init&path={path}',
        data=data
    )
    
    return response.json()
curl -X POST "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=upload-init&path=/" \
  -F "fileName=example.mp4" \
  -F "fileSize=104857600" \
  -F "totalChunks=20" \
  -F "mimeType=video/mp4"

Success Response

JSON Response
{
    "success": true,
    "upload_id": "sdx_67890abcdef",
    "chunk_size": 5242880,
    "message": "Upload initialized successfully"
}

Upload Chunk

Upload individual file chunks. Each chunk should be 5MB (except the last chunk which may be smaller).

POST /?key=YOUR_KEY&action=upload-chunk

Headers

Header Description
X-Upload-ID Upload ID from init response
X-Chunk-Index Zero-based chunk index

Example Requests

JavaScript
Python
cURL
async function uploadChunk(file, uploadId, chunkIndex, sdxKey) {
    const CHUNK_SIZE = 5 * 1024 * 1024;
    const start = chunkIndex * CHUNK_SIZE;
    const end = Math.min(start + CHUNK_SIZE, file.size);
    const chunk = file.slice(start, end);
    
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=upload-chunk`,
        {
            method: 'POST',
            headers: {
                'X-Upload-ID': uploadId,
                'X-Chunk-Index': chunkIndex.toString()
            },
            body: chunk
        }
    );
    
    return await response.json();
}
def upload_chunk(file_path, upload_id, chunk_index, sdx_key):
    CHUNK_SIZE = 5 * 1024 * 1024
    
    with open(file_path, 'rb') as f:
        f.seek(chunk_index * CHUNK_SIZE)
        chunk_data = f.read(CHUNK_SIZE)
    
    headers = {
        'X-Upload-ID': upload_id,
        'X-Chunk-Index': str(chunk_index)
    }
    
    response = requests.post(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=upload-chunk',
        headers=headers,
        data=chunk_data
    )
    
    return response.json()
curl -X POST "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=upload-chunk" \
  -H "X-Upload-ID: sdx_67890abcdef" \
  -H "X-Chunk-Index: 0" \
  --data-binary "@chunk_0.bin"

Success Response

JSON Response
{
    "success": true,
    "chunk_index": 0,
    "uploaded_chunks": 1,
    "total_chunks": 20,
    "progress_percent": 5.0,
    "bytes_uploaded": 5242880,
    "bytes_remaining": 99614720
}

Complete Upload

Finalize the upload by merging all chunks into the final file. This validates chunk integrity and updates storage usage.

POST /?key=YOUR_KEY&action=upload-complete

Parameters

Parameter Description
uploadId Upload ID from init response

Example Requests

JavaScript
Python
cURL
async function completeUpload(uploadId, sdxKey) {
    const formData = new FormData();
    formData.append('uploadId', uploadId);
    
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=upload-complete`,
        {
            method: 'POST',
            body: formData
        }
    );
    
    return await response.json();
}
def complete_upload(upload_id, sdx_key):
    data = {'uploadId': upload_id}
    
    response = requests.post(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=upload-complete',
        data=data
    )
    
    return response.json()
curl -X POST "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=upload-complete" \
  -F "uploadId=sdx_67890abcdef"

Success Response

JSON Response
{
    "success": true,
    "message": "Upload completed successfully",
    "file_name": "example.mp4",
    "file_size": 104857600,
    "file_size_formatted": "100 MB",
    "path": "example.mp4",
    "full_path": "/your_key/example.mp4",
    "mime_type": "video/mp4",
    "checksum": "d41d8cd98f00b204e9800998ecf8427e",
    "upload_time_seconds": 45.32,
    "merge_time_seconds": 2.15,
    "average_speed_mbps": 2.21,
    "chunks_uploaded": 20,
    "started_at": "2025-10-15 12:30:00",
    "completed_at": "2025-10-15 12:30:45",
    "storage_used_gb": 0.0977,
    "storage_limit_gb": 100
}

Resume Upload

Check if an incomplete upload exists and get the list of already uploaded chunks to resume from where you left off.

POST /?key=YOUR_KEY&action=upload-resume&path=/

Example Requests

JavaScript
Python
cURL
async function resumeUpload(fileName, sdxKey, path = '/') {
    const formData = new FormData();
    formData.append('fileName', fileName);
    
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=upload-resume&path=${path}`,
        {
            method: 'POST',
            body: formData
        }
    );
    
    return await response.json();
}
def resume_upload(file_name, sdx_key, path='/'):
    data = {'fileName': file_name}
    
    response = requests.post(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=upload-resume&path={path}',
        data=data
    )
    
    return response.json()
curl -X POST "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=upload-resume&path=/" \
  -F "fileName=example.mp4"

Success Response

JSON Response
{
    "success": true,
    "can_resume": true,
    "upload_id": "sdx_67890abcdef",
    "uploaded_chunks": [0, 1, 2, 3, 4],
    "total_chunks": 20,
    "progress_percent": 25.0,
    "bytes_uploaded": 26214400,
    "bytes_remaining": 78643200
}

List Contents

List all files and folders in a specified directory path.

GET /?key=YOUR_KEY&action=list-contents&path=/

Example Requests

JavaScript
Python
cURL
async function listContents(sdxKey, path = '/') {
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=list-contents&path=${path}`
    );
    
    return await response.json();
}
def list_contents(sdx_key, path='/'):
    response = requests.get(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=list-contents&path={path}'
    )
    
    return response.json()
curl "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=list-contents&path=/"

Success Response

JSON Response
{
    "success": true,
    "path": "",
    "full_path": "/your_key/",
    "items": [
        {
            "name": "videos",
            "path": "videos",
            "type": "folder",
            "size": 0,
            "size_formatted": "-",
            "modified": 1697385600,
            "modified_formatted": "2025-10-15 12:00:00"
        },
        {
            "name": "example.mp4",
            "path": "example.mp4",
            "type": "file",
            "size": 104857600,
            "size_formatted": "100 MB",
            "modified": 1697385645,
            "modified_formatted": "2025-10-15 12:00:45",
            "mime_type": "video/mp4",
            "can_read": false
        }
    ],
    "total_items": 2,
    "folders": 1,
    "files": 1
}

Download File

Download a file from your SDX storage. Returns the file as a binary stream.

GET /?key=YOUR_KEY&action=download&path=/file.ext

Example Requests

JavaScript
Python
cURL
async function downloadFile(sdxKey, filePath) {
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=download&path=${filePath}`
    );
    
    const blob = await response.blob();
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filePath.split('/').pop();
    a.click();
}
def download_file(sdx_key, file_path, save_path):
    response = requests.get(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=download&path={file_path}',
        stream=True
    )
    
    with open(save_path, 'wb') as f:
        for chunk in response.iter_content(chunk_size=8192):
            f.write(chunk)
curl "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=download&path=/example.mp4" \
  -o example.mp4

Read File Content

Read the contents of a text-based file (max 100MB). Only works with readable file types.

GET /?key=YOUR_KEY&action=read-file&path=/file.txt

Example Requests

JavaScript
Python
cURL
async function readFile(sdxKey, filePath) {
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=read-file&path=${filePath}`
    );
    
    return await response.json();
}
def read_file(sdx_key, file_path):
    response = requests.get(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=read-file&path={file_path}'
    )
    
    return response.json()
curl "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=read-file&path=/config.json"

Success Response

JSON Response
{
    "success": true,
    "file_name": "config.json",
    "file_size": 1024,
    "mime_type": "application/json",
    "content": "{\"setting\": \"value\"}",
    "encoding": "UTF-8"
}

Delete File/Folder

Delete a file or folder (including all contents). This action is irreversible.

DELETE /?key=YOUR_KEY&action=delete&path=/file.ext

Example Requests

JavaScript
Python
cURL
async function deleteItem(sdxKey, itemPath) {
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=delete&path=${itemPath}`,
        {
            method: 'DELETE'
        }
    );
    
    return await response.json();
}
def delete_item(sdx_key, item_path):
    response = requests.delete(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=delete&path={item_path}'
    )
    
    return response.json()
curl -X DELETE "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=delete&path=/example.mp4"

Success Response

JSON Response
{
    "success": true,
    "message": "Deleted successfully",
    "path": "example.mp4",
    "size_freed": 104857600,
    "size_freed_formatted": "100 MB"
}

Rename File/Folder

Rename a file or folder to a new name within the same directory.

POST /?key=YOUR_KEY&action=rename&path=/oldname.ext

Parameters

Parameter Description
newName New name for the file or folder

Example Requests

JavaScript
Python
cURL
async function renameItem(sdxKey, oldPath, newName) {
    const formData = new FormData();
    formData.append('newName', newName);
    
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=rename&path=${oldPath}`,
        {
            method: 'POST',
            body: formData
        }
    );
    
    return await response.json();
}
def rename_item(sdx_key, old_path, new_name):
    data = {'newName': new_name}
    
    response = requests.post(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=rename&path={old_path}',
        data=data
    )
    
    return response.json()
curl -X POST "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=rename&path=/old.mp4" \
  -F "newName=new.mp4"

Success Response

JSON Response
{
    "success": true,
    "message": "Renamed successfully",
    "old_name": "old.mp4",
    "new_name": "new.mp4",
    "new_path": "new.mp4"
}

Create Folder

Create a new folder (sub-bucket) to organize your files better.

POST /?key=YOUR_KEY&action=create-folder&path=/

Parameters

Parameter Description
folderName Name of the folder to create

Example Requests

JavaScript
Python
cURL
async function createFolder(sdxKey, folderName, path = '/') {
    const formData = new FormData();
    formData.append('folderName', folderName);
    
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=create-folder&path=${path}`,
        {
            method: 'POST',
            body: formData
        }
    );
    
    return await response.json();
}
def create_folder(sdx_key, folder_name, path='/'):
    data = {'folderName': folder_name}
    
    response = requests.post(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=create-folder&path={path}',
        data=data
    )
    
    return response.json()
curl -X POST "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=create-folder&path=/" \
  -F "folderName=videos"

Success Response

JSON Response
{
    "success": true,
    "message": "Folder created successfully",
    "folder_name": "videos",
    "path": "videos"
}

Get File/Folder Info

Get detailed information about a specific file or folder including size, type, and modification date.

GET /?key=YOUR_KEY&action=info&path=/file.ext

Example Requests

JavaScript
Python
cURL
async function getInfo(sdxKey, itemPath) {
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=info&path=${itemPath}`
    );
    
    return await response.json();
}
def get_info(sdx_key, item_path):
    response = requests.get(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=info&path={item_path}'
    )
    
    return response.json()
curl "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=info&path=/example.mp4"

Success Response (File)

JSON Response
{
    "success": true,
    "name": "example.mp4",
    "path": "example.mp4",
    "type": "file",
    "modified": 1697385645,
    "modified_formatted": "2025-10-15 12:00:45",
    "size": 104857600,
    "size_formatted": "100 MB",
    "mime_type": "video/mp4",
    "checksum": "d41d8cd98f00b204e9800998ecf8427e",
    "can_read": false
}

Get Account Info

Retrieve information about your SDX account including storage usage and limits.

GET /?key=YOUR_KEY&action=account-info

Example Requests

JavaScript
Python
cURL
async function getAccountInfo(sdxKey) {
    const response = await fetch(
        `https://node-in0-bucket.shulker.in/?key=${sdxKey}&action=account-info`
    );
    
    return await response.json();
}
def get_account_info(sdx_key):
    response = requests.get(
        f'https://node-in0-bucket.shulker.in/?key={sdx_key}&action=account-info'
    )
    
    return response.json()
curl "https://node-in0-bucket.shulker.in/?key=YOUR_KEY&action=account-info"

Success Response

JSON Response
{
    "success": true,
    "account": {
        "sdx_key": "your_key_here",
        "owner": "[email protected]",
        "storage_used_gb": 10.5,
        "storage_limit_gb": 100,
        "storage_used_percent": 10.5,
        "storage_available_gb": 89.5,
        "billing_amount": "5.00",
        "billing_period": "monthly",
        "next_billing": "2025-11-15",
        "created_at": "2025-01-01 00:00:00"
    }
}

Error Handling

The SDX API uses standard HTTP status codes and returns detailed error messages in JSON format to help you diagnose issues quickly.

Status Code Meaning Common Causes
400 Bad Request Invalid SDX key, missing parameters, or data validation failed
401 Unauthorized Billing overdue or inactive account
403 Forbidden Node mismatch - key doesn't match the node being accessed
404 Not Found File or folder doesn't exist
500 Internal Server Error Database connection failed or server-side issue

Error Response Format

JSON Response
{
    "success": false,
    "error": "Insufficient storage space. Used: 95.5GB, Limit: 100GB, Required: 5GB",
    "timestamp": 1697385645
}

SDX API Tester

Try the Interactive API Tester

Want to test the SDX API without writing code? Use our interactive API tester tool to explore all endpoints, upload files, manage folders, and see real-time responses.

The tester provides a user-friendly interface to experiment with all API actions, view formatted responses, and learn by doing.

Open SDX API Tester

Need help or have questions? Contact Support

© 2025 Shulker SDX API v1.0.0