# JCS-pub API **Back to [README.md](../README_en.md)** ## 1 Bucket Operations ### 1.1 Create Bucket
| Request | ||
|---|---|---|
| POST | application/json | /v1/bucket/create |
| Query | None | |
| Body |
{
"userID": 1,
"name": "bkt1" // Bucket name
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"bucket": {
"bucketID": 1, // Bucket ID
"name": "bkt1" // Bucket name
}
}
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/bucket/getByName |
| Query |
- name:string // Bucket name |
|
| Body | None | |
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"bucket": {
"bucketID": 1, // Bucket ID
"name": "bkt1" // Bucket name
}
}
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/bucket/listAll |
| Query | None | |
| Body | None | |
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"buckets": [{
"bucketID": 1, // Bucket ID
"name": "bkt1" // Bucket name
}]
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/bucket/delete |
| Query | None | |
| Body |
{
"bucketID":1
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": null
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/package/create |
| Query | None | |
| Body |
{
"bucketID":1,
"name": "" // Package name
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"package": {
"packageID": 32,
"name": "t1",
"bucketID": 1,
"createTime": "2025-06-24T16:31:28.5148754+08:00"
}
}
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/package/getByFullName |
| Query |
- bucketName:string // Bucket name - packageName:string // Package name |
|
| Body | None | |
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"package": {
"packageID": 32,
"name": "t1",
"bucketID": 1,
"createTime": "2025-06-24T16:31:28.5148754+08:00"
}
}
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/package/listBucketPackages |
| Query |
- bucketID:int64 // Bucket ID |
|
| Body | None | |
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"packages":[{
"packageID": 32,
"name": "t1",
"bucketID": 1,
"createTime": "2025-06-24T16:31:28.5148754+08:00"
}]
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/package/delete |
| Query | None | |
| Body |
{
"packageID":1
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": null
}
|
||
| Request | ||
|---|---|---|
| POST | multipart/form-data; boundary=xxxxxxx | /v1/object/upload |
| Query | None | |
| Body |
Afterwards, the request body is split into multiple parts using the boundary. The first part must have the name info and follow this JSON format: {
"packageID": 1, // Package ID, obtained from the response of the Create Package API
"affinity": 1 // Preferred storage space for uploading the file (optional)
}
Each subsequent part is a file. The name should be files, and the filename should be the file path (must be URL-encoded). Example: POST /object/upload HTTP/1.1
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: c12fa8b5-d902-46f3-b104-028effa0d531
Host: localhost:7890
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: multipart/form-data; boundary=-----------------------------818270992847011232305151
Content-Length: 1649
-----------------------------818270992847011232305151
Content-Disposition: form-data; name="info"
{
"userID": 1,
"packageID": 1
}
-----------------------------818270992847011232305151
Content-Disposition: form-data; name="files"; filename="test.txt"
Content-Type: text/plain
testdata
-----------------------------818270992847011232305151
Content-Disposition: form-data; name="files"; filename="a%2Fb%2Ftest2.txt"
testdata2
-----------------------------818270992847011232305151--
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"uploadeds": [
{
"objectID": 7,
"packageID": 1,
"path": "test.txt",
"size": "123456",
"fileHash": "xxxxxxxxxx",
"redundancy": {
"type": "none"
},
"createTime": "2024-11-05T11:06:28+08:00",
"updateTime": "2025-01-10T09:15:39.4452196+08:00"
},
{
"objectID": 8,
"packageID": 1,
"path": "a/b/test2.txt",
"size": "123456",
"fileHash": "xxxxxxxxxx",
"redundancy": {
"type": "none"
},
"createTime": "2024-11-05T11:06:28+08:00",
"updateTime": "2025-01-10T09:15:39.4452196+08:00"
}
]
}
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/object/download |
| Query |
- objectID:int64 - offset:int64 - length:int64 // Length to read. If not provided, the entire object will be read. |
|
| Body | None | |
| Response Example | ||
|
If the request is successful, the {
"code": "OperationFailed",
"message": "xxxxxxxx",
"data": null
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/object/downloadByPath |
| Query |
- path:string - offset:int64 - length:int64 // Length to read. If not provided, the entire object will be read. |
|
| Body | None | |
| Response Example | ||
|
If the request is successful, the {
"code": "OperationFailed",
"message": "xxxxxxxx",
"data": null
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/object/listByPath |
| Query |
- packageID:int64 - path:string - isPrefix:bool // If true, perform a prefix search using the path parameter - noRecursive:bool // If true, when performing a prefix search, the results will separate objects and "directories" like a directory listing - maxKeys:int // Maximum number of results returned in this query (the total number of items in commonPrefixes + objects) - continuationToken:string // Start this query from the position specified by the token; leave empty to start from the beginning. This value should be the same as the corresponding field from the previous response. |
|
| Body | None | |
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"nextContinuationToken": "123456", // Used for the next paginated query
"isTruncated": false, // If true, it indicates more results are available for the next query
"commonPrefixes": [
"a/b/",
"a/c/"
],
"objects": [
{
"objectID": 617,
"packageID": 12,
"path": "a/1.txt",
"size": "1293",
"fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
"redundancy": {
"type": "none"
},
"createTime": "2024-11-19T16:02:25+08:00",
"updateTime": "2024-11-19T16:02:25+08:00"
},
{
"objectID": 618,
"packageID": 12,
"path": "a/2.txt",
"size": "1293",
"fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
"redundancy": {
"type": "none"
},
"createTime": "2024-11-19T16:02:25+08:00",
"updateTime": "2024-11-19T16:02:25+08:00"
}
]
}
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/object/getPackageObjects |
| Query |
- packageID:int64 |
|
| Body | None | |
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"objects": [
{
"objectID": 617,
"packageID": 12,
"path": "a/1.txt",
"size": "1293",
"fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
"redundancy": {
"type": "none"
},
"createTime": "2024-11-19T16:02:25+08:00",
"updateTime": "2024-11-19T16:02:25+08:00"
},
{
"objectID": 618,
"packageID": 12,
"path": "a/2.txt",
"size": "1293",
"fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
"redundancy": {
"type": "none"
},
"createTime": "2024-11-19T16:02:25+08:00",
"updateTime": "2024-11-19T16:02:25+08:00"
}
]
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/object/move |
| Query | None | |
| Body |
{
"movings":[
{
"objectID":4, // Original object ID
"packageID":3, // Target package ID after moving
"path":"trace2.txt" // Target path after moving
}
]
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"successes": [ // IDs of successfully moved objects
4
]
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/object/delete |
| Query | None | |
| Body |
{
"objectIDs":[
4
]
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": null
}
The response code will be OK even if the file does not exist. |
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/object/clone |
| Query | None | |
| Body |
{
"clonings": [
{
"objectID": 4, // Original object ID
"newPath": "trace3.txt", // The new object's path
"newPackageID": 3 // The new object's package ID
}
]
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"objects":[{
"objectID": 5,
"packageID": 3,
"path": "trace3.txt",
"size": "1293",
"fileHash": "Full4E69A8B8CD9F42EDE371DA94458BADFB2308AFCA736AA393784A3D81F4746377",
"redundancy": {
"type": "none"
},
"createTime": "2024-11-19T16:02:25+08:00",
"updateTime": "2024-11-19T16:02:25+08:00"
}]
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/object/newMultipartUpload |
| Query | None | |
| Body |
{
"packageID": 3,
"path": "multi" // The object's path
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"object": {
"objectID": 1039,
"packageID": 3,
"path": "obj.txt",
"size": "0",
"fileHash": "Full0000000000000000000000000000000000000000000000000000000000000000",
"redundancy": {
"type": "multipartUpload"
},
"createTime": "2025-03-04T16:03:18+08:00",
"updateTime": "2025-03-11T15:20:44.5182982+08:00"
}
}
}
The created object can be found using the query interface. |
||
| Request | ||
|---|---|---|
| POST | multipart/form-data; boundary=xxxxxxx | /v1/object/uploadPart |
| Query | None | |
| Body |
Similar to the object upload interface, the request must contain two parts: {
"objectID": 1, // The Object ID obtained from the Create Multipart Upload API
"index": 1 // The part number used for merging later. Parts with the same index will overwrite the old data.
}
The |
|
| Response Example | ||
{
"code": "OK",
"message": ""
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/object/completeMultipartUpload |
| Query | None | |
| Body |
{
"objectID": 1039, // The Object ID to be merged
"indexes": [2,3,1] // The list of part numbers. Duplicate part numbers are allowed; parts will be merged in the specified order. Unused parts will be discarded.
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"object": {
"objectID": 1039,
"packageID": 3,
"path": "obj.txt",
"size": "30",
"fileHash": "FullB7660EB37969EDC68202258A1838B89493B4C77EA006B1640768D20CEF7A7CD2",
"redundancy": {
"type": "none"
},
"createTime": "2025-03-04T16:03:18+08:00",
"updateTime": "2025-03-11T15:42:03+08:00"
}
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/userSpace/create |
| Query | None | |
| Body |
{
"name": "test1",
"storage": { // Storage system type
"type": "OBS",
"region": "",
"endpoint": "",
"bucket": "",
"projectID": ""
},
"credential": { // Permission information required to access the storage system
"type": "OBS",
"accessKeyId": "",
"secretAccessKey": ""
},
"shardStore": { // Configuration for shard storage; if null, shard storage is disabled
"maxSize":1024
},
"features": [], // Configuration of feature functions for the storage system
"workingDir": "" // Root directory for storing data of various components, including shard storage
}
- The content of |
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"userSpace": {
"userSpaceID": 1,
"name": "test1",
"storage": {
"type": "OBS",
"region": "",
"endpoint": "",
"bucket": "",
"projectID": ""
},
"credential": {
"type": "OBS",
"accessKeyId": "",
"secretAccessKey": ""
},
"shardStore": {
"maxSize": 1024
},
"features": [],
"workingDir": "",
"revision": 1
}
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/userSpace/update |
| Query | None | |
| Body |
{
"userSpaceID": 1,
"name": "test1", // New name
"credential": { // New credential information
"type": "OBS",
"accessKeyId": "",
"secretAccessKey": ""
}
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"userSpace": {
"userSpaceID": 1,
"name": "test1",
"storage": {
"type": "OBS",
"region": "",
"endpoint": "",
"bucket": "",
"projectID": ""
},
"credential": {
"type": "OBS",
"accessKeyId": "",
"secretAccessKey": ""
},
"shardStore": {
"maxSize": 1024
},
"features": [],
"workingDir": "",
"revision": 1
}
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/userSpace/delete |
| Query | None | |
| Body |
{
"userSpaceID": 1
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": null
}
The response code will be OK even if the file does not exist. |
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/userSpace/get |
| Query |
- userSpaceID: int64 |
|
| Body | None | |
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"userSpace": {
"userSpaceID": 1,
"name": "test1",
"storage": {
"type": "OBS",
"region": "",
"endpoint": "",
"bucket": "",
"projectID": ""
},
"credential": {
"type": "OBS",
"accessKeyId": "",
"secretAccessKey": ""
},
"shardStore": {
"maxSize": 1024
},
"features": [],
"workingDir": "",
"revision": 1
}
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/userSpace/test |
| Query | None | |
| Body |
{
"storage": {
"type": "OBS",
"region": "",
"endpoint": "",
"bucket": "",
"projectID": ""
},
"credential": {
"type": "OBS",
"accessKeyId": "",
"secretAccessKey": ""
},
"workingDir": ""
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": null
}
The OK response indicates the configuration is valid and connected to the storage system. |
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/userSpace/createPackage |
| Query | None | |
| Body |
{
"userSpaceID": 1,
"path": "", // Path within the user's storage space. Can be a folder or a file. Note: WorkingDir is not prepended.
"bucketID": 1, // bucketID of the newly created package
"name": "", // Name of the newly created package
"spaceAffinity": 0 // Preferred storage space for uploading files. 0 means no preference.
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"package": {
"packageID": 32,
"name": "t1",
"bucketID": 1,
"createTime": "2025-06-24T16:31:28.5148754+08:00"
}
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/userSpace/downloadPackage |
| Query | None | |
| Body |
{
"userSpaceID": 1,
"packageID": 1,
"rootPath": "", // Root path for storing downloaded files
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": null
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/spaceSyncer/createTask |
| Query | None | |
| Body |
{
"trigger": { // Sync task trigger condition
"type": "Interval",
"interval": 30
},
"mode": { // Sync mode
"type": "Diff",
"includeSize": false,
"includeModTime": true
},
"filters": [ // Filter rules
{
"type": "Size",
"minSize": 10,
"maxSize": 20000
}
],
"options": { // Options
"noEmptyDirectories": false
},
"srcUserSpaceID": 1, // Source storage space ID
"srcPath": "space1/cli", // Path within source storage space
"destUserSpaceIDs": [ // Destination storage space IDs
2
],
"destPathes": [ // Paths within destination storage spaces
"space2/svr"
]
}
The contents of |
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"task": {
"taskID": 1,
"trigger": {
"type": "Interval",
"interval": 30
},
"mode": {
"type": "Diff",
"includeSize": false,
"includeModTime": true
},
"filters": [
{
"type": "Size",
"minSize": 10,
"maxSize": 20000
}
],
"options": {
"noEmptyDirectories": false
},
"srcUserSpaceID": 1,
"srcPath": "space1/cli",
"destUserSpaceIDs": [
2
],
"destPathes": [
"space2/svr"
]
}
}
}
|
||
| Request | ||
|---|---|---|
| GET | application/json | /v1/spaceSyncer/getTask |
| Query |
- taskID: int64 |
|
| Body | None | |
| Response Example | ||
{
"code": "OK",
"message": "",
"data": {
"task": {
"taskID": 1,
"trigger": {
"type": "Interval",
"interval": 30
},
"mode": {
"type": "Diff",
"includeSize": false,
"includeModTime": true
},
"filters": [
{
"type": "Size",
"minSize": 10,
"maxSize": 20000
}
],
"options": {
"noEmptyDirectories": false
},
"srcUserSpaceID": 1,
"srcPath": "space1/cli",
"destUserSpaceIDs": [
2
],
"destPathes": [
"space2/svr"
]
}
}
}
|
||
| Request | ||
|---|---|---|
| POST | application/json | /v1/spaceSyncer/cancelTask |
| Query | None | |
| Body |
{
"taskID": 1
}
|
|
| Response Example | ||
{
"code": "OK",
"message": "",
"data": null
}
|
||