# How to get uploaded image url using the Discourse API?

**URL:** https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800
**Category:** Development
**Tags:** rest-api
**Created:** [1월 12, 2016, 3:51오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800 "2016-01-12T03:51:27Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![sleep](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sleep/32/48342_2.png) [@sleep](https://meta.discourse.org/u/sleep)
#### Post date: [1월 12, 2016, 3:51오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/1 "2016-01-12T03:51:27Z")

</div>

If I use this api:

```shell
curl -X POST -F username="john" -F type="image" -F file="@image.png" -F synchronous="true" "http://localhost:3000/uploads?api_key=SOMETHING&api_username=SOMEONE"

```

I just can get a response with “`{"success":"OK"}`”. But I want to get the image url .

I see the topic to solve how to get image url:

[https://meta.discourse.org/t/using-the-discourse-api-to-post-with-uploaded-files/29833/23](https://meta.discourse.org/t/using-the-discourse-api-to-post-with-uploaded-files/29833/23)

new api:

```shell
curl -X POST -F type=composer -F client_id=1234b591bb4848dd899b6e6ee0feaff9 -F 'files[]=@12HourDate.kmmacros' 'http://forum.keyboardmaestro.com/uploads.json?api_key=APIKEY&synchronous=1'

```

I can’t understand how to get the `client_id`? If I add the param “`synchronous=1`” in url. No return value!

---

<div class="post-metadata">

### Author: ![sleep](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sleep/32/48342_2.png) [@sleep](https://meta.discourse.org/u/sleep)
#### Post date: [1월 12, 2016, 9:02오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/2 "2016-01-12T09:02:54Z")

</div>

Nobody can help me ?  
😭😭😭

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [1월 12, 2016, 9:52오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/3 "2016-01-12T09:52:43Z")

</div>

client\_id is assigned randomly, but you should not need it if synchronous 1 is enabled.

---

<div class="post-metadata">

### Author: ![sleep](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sleep/32/48342_2.png) [@sleep](https://meta.discourse.org/u/sleep)
#### Post date: [1월 12, 2016, 10:15오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/4 "2016-01-12T10:15:00Z")

</div>

So I can write client\_id randomly?  
But incorrectly when I write the client\_id randomly.  
why…

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [1월 12, 2016, 10:16오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/5 "2016-01-12T10:16:26Z")

</div>

client\_id is used for asynchronous uploads, we notify that client via the message bus that an upload was processed once it is process, which is why it should not matter if synchronous is enabled. There is no messaging.

---

<div class="post-metadata">

### Author: ![sleep](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sleep/32/48342_2.png) [@sleep](https://meta.discourse.org/u/sleep)
#### Post date: [1월 13, 2016, 7:54오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/6 "2016-01-13T07:54:51Z")

</div>

Thank you.😛

> [@Discourse REST API Documentation](https://meta.discourse.org/t/discourse-rest-api-documentation/22706/1):
>
> Upload Image from File
> 
> POST /uploads
> 
> Parameters
> 
> username  
> type  
> file  
> synchronous
> 
> Example

```shell
curl -X POST -F username="john" -F type="image" -F file="@image.png" -F synchronous="true" "http://localhost:3000/uploads?api_key=SOMETHING&api_username=SOMEONE"

```

I write a php fucntion to test this upload api.

```php
public function upload_file($user) {
  $url = 'http://hostname/uploads?api_key=api_key&api_username=api_username';
  $poststr = http_build_query(array('username' => $user, 'type' => 'image', 'file' => '/uploads/file/filename', 'synchronous' => 'true');
  $data = _curl($url, $poststr)); // _curl() : a custom function 
  return $data;
}

```

$data is empty. Why is it empty? It’s not supposed to return a url.

if I remove a parammeter : synchronous, it will return the response of “{“success”:“OK”}”.

---

<div class="post-metadata">

### Author: ![sleep](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sleep/32/48342_2.png) [@sleep](https://meta.discourse.org/u/sleep)
#### Post date: [1월 13, 2016, 3:25오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/8 "2016-01-13T15:25:01Z")

</div>

Thanks.  
But I want to put the photos uploaded to the discourse server

---

<div class="post-metadata">

### Author: ![calmh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/calmh/32/115466_2.png) [@calmh](https://meta.discourse.org/u/calmh)
#### Post date: [1월 14, 2016, 12:25오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/9 "2016-01-14T12:25:57Z")

</div>

> [@sleep](#):
>
> ```php
> $url = 'http://hostname/uploads?api_key=api_key&api_username=api_username';
> $poststr = http_build_query(array('username' => $user, 'type' => 'image', 'file' => '/uploads/file/filename', 'synchronous' => 'true');
> $data = _curl($url, $poststr)); // _curl() : a custom function
> 
> ```

This may just be a really weird PHP API, but where do you shuffle the actual file data to the server? I don’t know your `_curl()`, but it looks like it just gets a URL and some query parameters.

---

<div class="post-metadata">

### Author: ![sleep](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sleep/32/48342_2.png) [@sleep](https://meta.discourse.org/u/sleep)
#### Post date: [1월 15, 2016, 1:59오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/10 "2016-01-15T01:59:30Z")

</div>

```php
function _curl($url,$poststr='',$httpheader=array(),$usecookie=false){
        $ch = curl_init();
        $SSL = substr($url, 0, 8) == "https://" ? true : false;
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        if ( $SSL ) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
        }
        if( $poststr!='' ){
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $poststr);
        }
        if( $httpheader ){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
        }
        if( $usecookie ){
        	$cookie_jar = APPPATH.'cache/logs/curl_cookie_'.md5($url).'.log';
        	curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);
        }
        
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

```

Curl is a tool and libcurl is a library for transferring data with URL syntax. It not just gets a URL and some query parameters  
Before, I can use this curl function to submit data to discourse server when I create a new topic.

Look down a successful example to create a new topic using the api.

```php
public function create_topic($params) {
        $url = 'http://hostname/posts?api_key=api_key&api_username=api_username';
        $poststr = http_build_query(array('raw' => $params['raw'], 'title' => $params['title'], 'category' => $params['category']));
        $result = array('success' => false, 'msg' => 'failed');
        if(($data=_curl($url, $poststr)) && ($json = json_decode($data, true))) {
            if( !empty($json)) {
                if(isset($json['errors'])) {
                    $result['msg'] = $json['errors'][0];
                }
                else {
                    $result['success'] = true;
                }
            }
        }
        return $result;
    }

```

Thank you.😛

---

<div class="post-metadata">

### Author: ![calmh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/calmh/32/115466_2.png) [@calmh](https://meta.discourse.org/u/calmh)
#### Post date: [1월 15, 2016, 2:20오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/11 "2016-01-15T14:20:45Z")

</div>

Oh, I know what curl is. I’m just pointing out that I don’t see where you’re sending the actual contents of the file you are supposedly uploading to Discourse. Without contents I don’t expect Discourse to be happy with the upload, so I wouldn’t expect a successful result.

---

<div class="post-metadata">

### Author: ![sleep](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sleep/32/48342_2.png) [@sleep](https://meta.discourse.org/u/sleep)
#### Post date: [1월 16, 2016, 2:21오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/12 "2016-01-16T14:21:52Z")

</div>

Get rid of the function http\_build\_query, we can upload image successfully!

```php
public function upload_file($user) {
  $url = 'http://hostname/uploads?api_key=api_key&api_username=api_username';
  $poststr = http_build_query(array('username' => $user, 'type' => 'image', 'file' => '/uploads/file/filename', 'synchronous' => 'true')); // get rid of the function http_build_query, we can upload image successfully!
  $data = _curl($url, $poststr)); // _curl() : a custom function 
  return $data;
}

```

After change

```php
  $poststr = array('username' => $user, 'type' => 'image', 'file' => '/uploads/file/filename', 'synchronous' => 'true'); // get rid of the function http_build_query, we can upload image successfully!

```

In summary, when we submit data to discourse server using curl, we may use three method to post parameters. You should try more methods when you encounter problems.

one: json  
two: http\_query\_query  
three: array

There may be more.🙂

---

<div class="post-metadata">

### Author: ![stefanm](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefanm](https://meta.discourse.org/u/stefanm)
#### Post date: [1월 12, 2017, 3:42오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/13 "2017-01-12T15:42:58Z")

</div>

hi all,

i am trying to upload image using ajax, and getting 400 bad request.  
but there is no message so i can see what is going on.  
Have my csrf token, and also logged in but still nothing.

code looks something like this

```
 $.ajax({
                    headers: { 'X-CSRF-Token': data.csrf },
                    url: '/forum/uploads.json?synchronous=1',
                    type: 'POST',
                    data: formData,
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function (xhr) {
                   
                    },
                });

```

i guess it is maybe because i am using formData, if it is can you please tell me in which format i need to send image?

Thanks

---

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [1월 12, 2017, 4:48오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/14 "2017-01-12T16:48:45Z")

</div>

I’m not really sure what all you will need to do to get it to work via ajax (api key, csrf, cors, etc?), but here is how you can get an upload to work via the api (this is for an avatar upload, but it is the same endpoint, you probably just need to change the type):

 ![](https://global.discourse-cdn.com/meta/original/3X/b/a/ba32ec39a999a71997c3d025cc50e56744eb834d.png)

---

<div class="post-metadata">

### Author: ![stefanm](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefanm](https://meta.discourse.org/u/stefanm)
#### Post date: [1월 12, 2017, 4:53오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/15 "2017-01-12T16:53:33Z")

</div>

i actually want to first upload image, and than with that image to make a post.  
i made posts without api\_key and api\_username since i have csrf token and cookie,  
so i guess i don’t need for this upload too.

this is my call for creating post :

```
                headers: { 'X-CSRF-Token': data.csrf },
                data: JSON.stringify({
                    raw: this.get('comment'),
                    topic_id: this.get('topicId')
                }),
                contentType: 'application/json',

```

so as you can see, without api\_key and api\_username.

but can you tell me more about this type, what should i put if i want to upload image before post?  
and user\_id, i don’t have user id, and i didn’t use it for any of the for any calls until now.

so only cookie and csrf

---

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [1월 12, 2017, 4:59오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/16 "2017-01-12T16:59:50Z")

</div>

sorry the `user_id` is only if the type is `avatar`.

I’m pretty sure you will need a post\_id though if you are uploading it to a post.

I’m not sure off the top of my head, but you can:

> [@Reverse engineer the Discourse API](https://meta.discourse.org/t/how-to-reverse-engineer-the-discourse-api/20576):
>
> Discourse is backed by a complete JSON api. Anything you can do on the site you can also do using the JSON api. The API is documented at [docs.discourse.org](https://docs.discourse.org). You can also use the [discourse\_api](https://github.com/discourse/discourse_api) Ruby gem as a client library. However, not every endpoint is documented. To determine how to do something with the JSON API here are some steps you can follow. Example: recategorize a topic. Go to a topic and start editing a category: Open Chrome dev tools, switch to the Network tab, select …

The current issue you will run into though is that we don’t return the `upload_id`:

> [@Upload avatar image with API](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/2):
>
> The problem I found is that this just returns { “success”: “OK” } and doesn’t return the upload\_id?

---

<div class="post-metadata">

### Author: ![stefanm](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefanm](https://meta.discourse.org/u/stefanm)
#### Post date: [1월 12, 2017, 5:05오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/17 "2017-01-12T17:05:01Z")

</div>

exactly, that’s where i am stuck right now 🙂

so, i made a call, uploaded picture, but there is no url to the picture in the response, only success : OK.  
is there a way to get url to the image in the response?

thanks

---

<div class="post-metadata">

### Author: ![stefanm](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefanm](https://meta.discourse.org/u/stefanm)
#### Post date: [1월 13, 2017, 9:46오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/18 "2017-01-13T09:46:01Z")

</div>

i saw here: [https://meta.discourse.org/t/using-the-discourse-api-to-post-with-uploaded-files/29833/23](https://meta.discourse.org/t/using-the-discourse-api-to-post-with-uploaded-files/29833/23)  
that there is a way to get the link in response,  
but i am using this synchronous param set to 1 and still nothing but success : OK

---

<div class="post-metadata">

### Author: ![stefanm](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefanm](https://meta.discourse.org/u/stefanm)
#### Post date: [1월 16, 2017, 10:09오전 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/19 "2017-01-16T10:09:14Z")

</div>

this was more a question. So is there a clean a way, proposed by discourse to upload image via API, and retrieve image in response?

Or maybe to make upload and then request again for image link?

Thanks!

---

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [1월 16, 2017, 2:20오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/20 "2017-01-16T14:20:27Z")

</div>

> [@stefanm](#):
>
> type: ‘POST’,

One of the issues you are having has to do with the `type` parameter being set to ‘POST’ in all caps. It needs to be a value that complies with this rule:

> <https://github.com/discourse/discourse/blob/887e9af84ffbfdfe1925164947af9892f9f2bbec/app/controllers/uploads_controller.rb#L8>

Besides being used for determining if you are uploading an “avatar”, I’m not totally sure yet what all `type` is used for. So I would just set it to some all lowercase string like “upload”.

Here is an example file upload request and response API call:

 ![](https://global.discourse-cdn.com/meta/original/3X/4/e/4e0c47ffc8952e7e4f749862d082fbb2f9081021.png)

---

<div class="post-metadata">

### Author: ![stefanm](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@stefanm](https://meta.discourse.org/u/stefanm)
#### Post date: [1월 16, 2017, 3:02오후 UTC](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800/21 "2017-01-16T15:02:02Z")

</div>

i did everything u said :

```
    formData.append('type', 'upload');
    formData.append('post_id', '6640');
    formData.append('files', imageFile);
    formData.append('synchronous', true);

 $.ajax({
                headers: { 'X-CSRF-Token': data.csrf },
                url: '/forum/uploads',
                type: 'post',
                data: formData,
                async: false,
                cache: false,
                contentType: false,
                processData: false,
                success: function (status, xhr, msg) {
                    if (status) {
                     
                    }
                },

                error: function (status) {
                    if (status) {
                  
                    }
                }
            });

```

and still nothing but success : OK.

do you have maybe any other idea, what it can be?

[Next page](https://meta.discourse.org/t/how-to-get-uploaded-image-url-using-the-discourse-api/37800.md?page=2)
