Download files with the pCloud API

2.7k Views Asked by At

I am trying to make friends with the pCloud API, using curl in Bash,

Once I create a pCloud app and get its $clientid and $clientsecret, I can obtain a temporary access token accepting the request at:

echo "https://my.pcloud.com/oauth2/authorize?client_id=$clientid&response_type=code"

And given the $temptok token, I obtain the permanent bearer token with:

permtok=$(curl "https://api.pcloud.com/oauth2_token?client_id=$clientid&client_secret=$clientsecret&code=$temptok" | jq -r '.access_token')

At this point, I can use their API methods, published here.
For example, the userinfo or the listfolder method, which give:

curl "https://api.pcloud.com/userinfo?access_token=$permtok"
curl "https://api.pcloud.com/listfolder?access_token=$permtok&path=/"   

However, I am unable to download files. Based on my understanding, I need to use a combination of file_open and file_read, and the latter needs the file size. When I open a file, I get an output similar to what follows:

curl "https://api.pcloud.com/file_open?access_token=$permtok&path=/foo.txt&flags=0x0040"                      
{
    "result": 0,
    "fd": 1,
    "fileid": 1234567890
}

When using the file descriptor for file_size method:

curl "https://api.pcloud.com/file_size?access_token=$permtok&fd=1"

I get the error:

{
    "result": 1007,
    "error": "Invalid or closed file descriptor."
}

What is the correct way to download files?

2

There are 2 best solutions below

0
antonio On BEST ANSWER

The solution proposed by @Bench Vue creates a public link for the file to download. So it is not suitable for private files. Also, once you have a public download link, leveraging the API, with the related authentication steps, might be overkilling.

Here is the solution for private files, which should not be publicly shared.

Obtain your permanent bearer oauth2 as described here, which is permanent.

# Input pars
permtok="....."
source="/foo bar.pdf"
dest="foo bar.pdf"
endpoint="https://api.pcloud.com"
 
# Encode source path
encsource=$(printf %s "$source" |jq -sRr @uri)
 
# Get file size 
size=$(curl -H "Connection: keep-alive" \
       "$endpoint/file_open?access_token=$permtok&path=$encsource&flags=64" \
       "$endpoint/file_size?access_token=$permtok&fd=1" \
       | jq -s '.[1] | .size')
 
# Download
curl -H "Connection: keep-alive" \
       "$endpoint/file_open?access_token=$permtok&path=$encsource&flags=64" \
       "$endpoint/file_read?access_token=$permtok&fd=1&count=$size" > "$dest"
       

Use listfolder method to find the correct source path, which might be relative to your application folder.

curl "$endpoint/listfolder?access_token=$permtok&path=/"   

$endpoint can change depending on your region.

The API server is HTTP 1.1, therefore "Connection: keep-alive" is necessary.

6
Bench Vue On

Overview Order to download a file enter image description here

I can download a file by Browser with getfolderpublink link.

The curl can download file. But it is not documented in pCloud web site. I found it by browser debugging window (F12).

I realize the download API is also not real download. It just get the file meta data for file.

https://api.pcloud.com/getfilelink?fileid={my-file-id}&auth={my-auth}'

Download file by Curl

curl -o {download-file-name} -L -X GET 'https://p-def7.pcloud.com/{full path of my file}' \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer $token"

Demo

1 Get Auth ID

https://my.pcloud.com/oauth2/authorize?client_id={my_client_id}&response_type=code

enter image description here

2 Get Access Token & Auth code

https://u.pcloud.com/oauth2/authorize?client_id=9xxxxxx7&response_type=code&auth={auth_id}

enter image description here Auth code is important and Access Token

auth=wt9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgX

enter image description here

Get access token with code.

curl -L -X POST 'https://api.pcloud.com/oauth2_token' \
-H 'Content-Type: application/json; charset=utf-8' \
--form 'client_id="9xxxxxxx7"' \
--form 'client_secret="4xxxxxxxxxxxxxxxxX"' \
--form 'code="lKxxxxxxxxxxxxxxxxxxX"'

response

{
    "result": 0,
    "userid": 18905223,
    "locationid": 1,
    "token_type": "bearer",
    "access_token": "lKxxxxxxxxxxxxxx-My-Token-xxxxxxxxxxxxxxxxxG7"
}

3 Assign environment variable with token name at terminal

$ token="lKxxxxxxxxxxxxxx-My-Token-xxxxxxxxxxxxxxxxxG7"

4 Get file information by get list-folder API

I will down load one of file Getting started with pCloud.pdf I need to get fileid from JSON response. The "fileid" is 43338896472

curl -L -X GET 'https://api.pcloud.com/listfolder?path=/' \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer $token" | jq
{
  "result": 0,
  "metadata": {
    "path": "/",
    "name": "/",
    "created": "Sat, 17 Sep 2022 23:58:07 +0000",
    "ismine": true,
    "thumb": false,
    "modified": "Sat, 17 Sep 2022 23:58:07 +0000",
    "id": "d0",
    "isshared": false,
    "icon": "folder",
    "isfolder": true,
    "folderid": 0,
    "contents": [
.... other three default directories
      {
        "name": "Getting started with pCloud.pdf",
        "created": "Sat, 17 Sep 2022 23:58:07 +0000",
        "videocodec": "",
        "thumb": false,
        "modified": "Sat, 17 Sep 2022 23:58:07 +0000",
        "size": 16371465,
        "audiobitrate": 0,
        "fps": "0.00",
        "comments": 0,
        "isfolder": false,
        "height": 0,
        "rotate": 0,
        "fileid": 43338896472,
        "videobitrate": 0,
        "width": 0,
        "hash": 3096725505949383000,
        "duration": "0.00",
        "path": "/Getting started with pCloud.pdf",
        "category": 4,
        "audiosamplerate": 0,
        "id": "f43338896472",
        "isshared": false,
        "ismine": true,
        "audiocodec": "mp3",
        "parentfolderid": 0,
        "contenttype": "application/pdf",
        "icon": "document"
      }
    ]

5 Get file information by stat API (include file size)

curl -L -X GET 'https://api.pcloud.com/stat?fileid=43338896472' \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer $token" | jq
{
  "result": 0,
  "metadata": {
    "name": "Getting started with pCloud.pdf",
    "created": "Sat, 17 Sep 2022 23:58:07 +0000",
    "videocodec": "",
    "thumb": false,
    "modified": "Sat, 17 Sep 2022 23:58:07 +0000",
    "size": 16371465,
    "audiobitrate": 0,
    "fps": "0.00",
    "comments": 0,
    "isfolder": false,
    "height": 0,
    "rotate": 0,
    "fileid": 43338896472,
    "videobitrate": 0,
    "width": 0,
    "hash": 3096725505949383000,
    "duration": "0.00",
    "category": 4,
    "audiosamplerate": 0,
    "id": "f43338896472",
    "isshared": false,
    "ismine": true,
    "audiocodec": "mp3",
    "parentfolderid": 0,
    "contenttype": "application/pdf",
    "icon": "document"
  }
}

6 Get getfilepublink API

  • get link information in JSON response
"link": "https://u.pcloud.link/publink/show?code=XZ9xxxxxxxxxxsss6Sk"
curl -L -X GET 'https://api.pcloud.com/getfilepublink?fileid=43338896472' \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer $token" | jq
{
  "code": "XZ9bBhVZ0lSVBSVb4jJKDXJAJBBJ0FIOs6Sk",
  "created": "Sun, 18 Sep 2022 01:15:38 +0000",
  "downloadenabled": true,
  "type": 1,
  "modified": "Sun, 18 Sep 2022 01:15:38 +0000",
  "downloads": 1,
  "link": "https://u.pcloud.link/publink/show?code=XZ9xxxxxxxxxxsss6Sk", <- I modified the code
  "result": 0,
  "linkid": 60017201,
  "haspassword": false,
  "traffic": 16371465,
  "views": 20,
  "metadata": {
    "name": "Getting started with pCloud.pdf",
    "created": "Sat, 17 Sep 2022 23:58:07 +0000",
    "videocodec": "",
    "thumb": false,
    "modified": "Sat, 17 Sep 2022 23:58:07 +0000",
    "size": 16371465,
    "audiobitrate": 0,
    "fps": "0.00",
    "comments": 0,
    "isfolder": false,
    "height": 0,
    "rotate": 0,
    "fileid": 43338896472,
    "videobitrate": 0,
    "width": 0,
    "hash": 3096725505949383000,
    "duration": "0.00",
    "category": 4,
    "audiosamplerate": 0,
    "id": "f43338896472",
    "isshared": false,
    "ismine": true,
    "audiocodec": "mp3",
    "parentfolderid": 0,
    "contenttype": "application/pdf",
    "icon": "document"
  }
}

7 Get download metadata API - same result of Step 6's part

8 Get file path and host URL

Host name array will be different depends on file's attribute(offical default file or personal file)

curl -L -X GET 'https://api.pcloud.com/getfilelink?fileid=43338896472&auth=wt9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgX' \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer $token"
{
    "result": 0,
    "dwltag": "GYYEgtilNwytpYulbsh1UB",
    "hash": 3096725505949383041,
    "size": 16371465,
    "expires": "Sun, 18 Sep 2022 10:53:50 +0000",
    "path": "\/cfZRj4OT2Zwk45bAZlKxxxxxxxxxxxxxxxxxxZbRZlJZ0JZKXZmpZSHZY7ZsFZzpZS5ZLa6pViVfwjfcge2gksnF08W9Qwi7\/Getting%20started%20with%20pCloud.pdf",
    "hosts": [
        "p-def7.pcloud.com",
        "c432.pcloud.com"
    ]
}

9 Finally I can download with Step 8 host name and path

full URL = Host[0] name + path (remove first two characters \ /)

curl -o guide.pdf -L -X GET 'https://p-def7.pcloud.com/cfZRj4OT2Zwk45bAZlKxxxxxxxxxxxxxxxxxxZbRZlJZ0JZKXZmpZSHZY7ZsFZzpZS5ZLa6pViVfwjfcge2gksnF08W9Qwi7\/Getting%20started%20with%20pCloud.pdf' \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer $token"

enter image description here

I can download by browser two. enter image description here