Upload Flow

Uploading files to Terabox uses a sophisticated protocol designed for reliability and efficiency. It consists of three distinct phases: Pre-create, Upload, and Create.

This flow supports: * Rapid Upload: If a file with the same MD5 hash already exists on Terabox servers (even from another user), it is instantly added to your drive without re-uploading the data. * Resumable Uploads: Large files are split into 4MB blocks, allowing you to retry failed chunks individually.


Step 1: Pre-create (Rapid Check)

Endpoint: POST /rest/2.0/xpan/file

In this step, you send the file's metadata and the MD5 hash of each 4MB block. Terabox checks if these blocks already exist.

Parameters: * method: precreate * bdstoken: Required.

Body Data: * path: Remote destination path. * size: Total file size in bytes. * block_list: A JSON array of MD5 hashes for every 4MB chunk of the file. * autoinit: 1. * rtype: 1.

Code Examples

=== "cURL"

```bash
# Check if a file (represented by MD5 hashes) exists
curl -X POST "https://1024terabox.com/rest/2.0/xpan/file?method=precreate&bdstoken=TOKEN&jsToken=TOKEN" \
  -d "path=/file.mp4&size=10485760&autoinit=1&block_list=[\"MD5_CHUNK_1\",\"MD5_CHUNK_2\"]&rtype=1"
```

=== "Python"

```python
import json

# 1. Calculate MD5 of your file in 4MB chunks
block_list = ["md5_chunk_1", "md5_chunk_2"] 
total_size = 10485760

data = {
    'path': '/remote_path.mp4',
    'size': str(total_size),
    'autoinit': '1',
    'block_list': json.dumps(block_list),
    'rtype': '1',
    'jsToken': js_token
}

resp = session.post(url, params={'method': 'precreate', 'bdstoken': bdstoken}, data=data)
result = resp.json()

# RESPONSE HANDLING:
# If result['errno'] == 0:
#   uploadid = result['uploadid']
#   needed_blocks = result.get('block_list', [])
#   if not needed_blocks:
#       print("Rapid Upload Success!")
#       # Skip to Step 3 or Done
```

=== "Node.js"

```javascript
const qs = require('qs');

const data = qs.stringify({
    path: '/remote_path.mp4',
    size: 10485760,
    autoinit: 1,
    block_list: JSON.stringify(['MD5_1', 'MD5_2']),
    rtype: 1,
    jsToken: 'TOKEN'
});

const resp = await client.post('/rest/2.0/xpan/file', data, {
    params: { method: 'precreate', bdstoken: 'TOKEN' }
});

const uploadid = resp.data.uploadid;
// Check resp.data.block_list to see which chunks to upload
```

Step 2: Upload Chunks (PCS)

Endpoint: POST https://{node}.1024terabox.com/rest/2.0/pcs/superfile2

If Step 1 returned a list of blocks in block_list (meaning they don't exist on the server), you must upload the binary data for those specific chunks.

Note: You must send this request to a PCS (Personal Cloud Storage) upload node (e.g., szb-cdata.1024terabox.com or dm-c-all.terabox.com). You can often reuse the host found in network traffic logs.

Parameters: * method: upload * app_id: 250528 * uploadid: The ID returned from Step 1. * path: Remote path. * partseq: The index of the chunk (0, 1, 2...). * uploadsign: 0.

Body: * Multipart/Form-Data with a field named file containing the binary data.

Code Examples

=== "cURL"

```bash
# Uploading chunk #0
curl -X POST "https://szb-cdata.1024terabox.com/rest/2.0/pcs/superfile2?method=upload&app_id=250528&uploadid=ID&path=/file.mp4&partseq=0&uploadsign=0" \
  -F "file=@chunk0.bin"
```

=== "Python"

```python
# Uploading Chunk #0
chunk_0_bytes = b'...' # Read 4MB from file
files = {'file': ('blob', chunk_0_bytes, 'application/octet-stream')}

params = {
    'method': 'upload',
    'app_id': '250528',
    'uploadid': uploadid,
    'path': '/remote_path.mp4',
    'partseq': '0',
    'uploadsign': '0'
}

# Ensure you are posting to the upload domain
pcs_url = "https://szb-cdata.1024terabox.com/rest/2.0/pcs/superfile2"
resp = session.post(pcs_url, params=params, files=files)

# Success response: {"md5": "calculated_md5_of_chunk"}
```

=== "Node.js"

```javascript
const FormData = require('form-data');
const form = new FormData();
form.append('file', chunkBuffer, { filename: 'blob' });

await client.post('https://szb-cdata.1024terabox.com/rest/2.0/pcs/superfile2', form, {
    params: {
        method: 'upload',
        app_id: '250528',
        uploadid: uploadid,
        path: '/remote_path.mp4',
        partseq: 0,
        uploadsign: 0
    },
    headers: form.getHeaders()
});
```

Step 3: Create (Finalize)

Endpoint: POST /rest/2.0/xpan/file

After all chunks are uploaded (or if they were already present), this step tells the server to assemble the file.

Parameters: * method: create * bdstoken: Required.

Body Data: * path: Remote path. * size: Total size. * uploadid: The ID from Step 1. * block_list: JSON list of ALL chunk MD5s (in order). * isdir: 0 * rtype: 1

Code Examples

=== "cURL"

```bash
curl -X POST "https://1024terabox.com/rest/2.0/xpan/file?method=create&bdstoken=TOKEN&jsToken=TOKEN" \
  -d "path=/file.mp4&size=10485760&uploadid=ID&block_list=[\"MD5_1\",\"MD5_2\"]&isdir=0&rtype=1"
```

=== "Python"

```python
data = {
    'path': '/remote_path.mp4',
    'size': str(total_size),
    'uploadid': uploadid,
    'block_list': json.dumps(block_list), # Must include ALL chunks
    'isdir': '0',
    'rtype': '1',
    'jsToken': js_token
}

resp = session.post(url, params={'method': 'create', 'bdstoken': bdstoken}, data=data)

# Success if errno == 0
# Response contains the new file's metadata
```

=== "Node.js"

```javascript
const data = qs.stringify({
    path: '/remote_path.mp4',
    size: 10485760,
    uploadid: uploadid,
    block_list: JSON.stringify(['MD5_1', 'MD5_2']),
    isdir: 0,
    rtype: 1,
    jsToken: 'TOKEN'
});

await client.post('/rest/2.0/xpan/file', data, {
    params: { method: 'create', bdstoken: 'TOKEN' }
});
```