Skip to main content
Hcfs • 2 mins read

Folder lifecycle

Folder lifecycle

Three endpoints for the folder registry: register a new folder, list a user's folders, unregister (and delete) a folder. Folder registration is what makes folder_label show up in /list_folders and /search_files; files can still be uploaded to an unregistered folder_hash, they just surface with folder_label = "".


POST /register_folder

Declare a new sync folder under an SS58 address.

Authentication

Authorization: Bearer <token> matching ss58_address in the request body. See auth.md.

Request

POST /register_folder
Content-Type: application/json
Authorization: Bearer <token>
{
"ss58_address": "5Grw...",
"folder_hash": "abc1234567890def",
"label": "My Documents",
"device_name": "laptop-home"
}
FieldTypeNotes
ss58_addressstringOwner's SS58 (accepts alias user_id)
folder_hash16-char hexFirst 16 chars of SHA-256(label) — the client computes this
labelstringHuman-readable folder name
device_namestring | nullOptional — records which device first registered this folder

Response — success (200)

{ "Success": { "status": "registered" } }

Response — errors

Statuserror codeCause
400invalid_manifestBody malformed or required field missing
401unauthorizedMissing / bad bearer token
403forbiddenToken resolves to a different SS58 than ss58_address
409conflictA folder with this folder_hash is already registered for this user
500database_errorTransient

Example

curl -X POST "$SERVER/register_folder" \
-H "Authorization: Bearer $SS58" \
-H "Content-Type: application/json" \
-d '{
"ss58_address": "'"$SS58"'",
"folder_hash": "abc1234567890def",
"label": "My Documents",
"device_name": "laptop-home"
}'

GET /list_folders/{base_address}

Enumerate every folder a user has registered, with per-folder file count and total size.

Authentication

Authorization: Bearer <token> matching {base_address}.

Request

GET /list_folders/{base_address}
Authorization: Bearer <token>

Response — success (200)

{
"Success": {
"base_address": "5Grw...",
"folders": [
{
"label": "My Documents",
"folder_hash": "abc1234567890def",
"file_count": 142,
"total_bytes": 943718400,
"created_at": 1713139200,
"updated_at": 1713225600,
"device_name": "laptop-home"
}
]
}
}
RemoteFolderInfo fieldTypeNotes
labelstringHuman-readable folder name from registration
folder_hash16-char hexUse this in path parameters of other endpoints
file_countu64Files currently in the folder
total_bytesu64Sum of plaintext sizes
created_ati64Unix seconds when the folder was registered
updated_ati64Unix seconds when a file in the folder last changed
device_namestring"" when the folder was registered without one

Response — errors

Statuserror codeCause
400invalid_user_idbase_address malformed
401unauthorizedMissing / bad bearer token
403forbiddenToken resolves to a different SS58 than {base_address}

Example

curl -H "Authorization: Bearer $SS58" \
"$SERVER/list_folders/$SS58"

DELETE /unregister_folder

Remove a folder and every file it owns. Storage blobs for every file in the folder are scheduled for deletion.

Authentication

Authorization: Bearer <token> matching ss58_address in the request body.

Request

DELETE /unregister_folder
Content-Type: application/json
Authorization: Bearer <token>
{ "ss58_address": "5Grw...", "folder_hash": "abc1234567890def" }

Response — success (200)

{
"Success": {
"status": "unregistered",
"files_deleted": 142
}
}

Response — errors

Statuserror codeCause
400invalid_manifestBody malformed
401unauthorizedMissing / bad bearer token
403forbiddenSS58 mismatch
404not_foundNo folder registered at this folder_hash for this user
500database_errorTransient

Example

curl -X DELETE "$SERVER/unregister_folder" \
-H "Authorization: Bearer $SS58" \
-H "Content-Type: application/json" \
-d '{ "ss58_address": "'"$SS58"'", "folder_hash": "abc1234567890def" }'

Notes

  • folder_hash is deterministic: same label always produces the same hash. This lets multiple devices register the same folder without coordination — the second caller gets 409 conflict and can proceed assuming the folder exists.
  • Unregistering is destructive and irreversible. To delete a single file instead, use /delete.
  • You can upload files to a folder_hash that was never registered — they will show up in /get_state but with folder_label = "" in /search_files results. Registering after-the-fact adds the label.