# Upload avatar image with API

**URL:** https://meta.discourse.org/t/upload-avatar-image-with-api/55253
**Category:** Development
**Tags:** rest-api
**Created:** [January 6, 2017, 1:31am UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253 "2017-01-06T01:31:43Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![adam\_beers](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@adam\_beers](https://meta.discourse.org/u/adam_beers)
#### Post date: [January 6, 2017, 1:31am UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/1 "2017-01-06T01:31:43Z")

</div>

I’m trying to upload an avatar image with the API as follows. I’m getting back a 500 error and I don’t see anything in the Error Logs on the server, via the Admin user.

I’ve attached a picture with the data from a Postman POST.

Of note is that I had this working at one time but then something changed and it stopped working. I’m not sure what changed, besides an update to Discourse and Docker.

 ![](https://global.discourse-cdn.com/meta/original/3X/3/1/31e1dc5838bb28a11a238d4478271ef38ad2f538.PNG)

---

<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: [January 6, 2017, 12:45pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/2 "2017-01-06T12:45:33Z")

</div>

So in order to change the avatar via the api you will need to make 2 api requests.

```
POST {{base_url}}/uploads.json
form-data:
  api_key: {{api_key}}
  api_username: {{api_username}}
  type: avatar
  user_id: 1
  files[]: file

```

The problem I found is that this just returns `{ "success": "OK" }` and doesn’t return the `upload_id`?

Then you need to make a request with the `upload_id`:

```
PUT {{base_url}}/users/{{api_username}}/preferences/avatar/pick
form-data:
  api_key: {{api_key}}
  api_username: {{api_username}}
  upload_id: 2
  type: uploaded

```

---

<div class="post-metadata">

### Author: ![adam\_beers](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@adam\_beers](https://meta.discourse.org/u/adam_beers)
#### Post date: [January 6, 2017, 4:12pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/3 "2017-01-06T16:12:15Z")

</div>

Yep, that’s what I found. I can’t figure out how to get the upload\_id. Anybody know how to do that?

Like I said, this was working before the Discourse and Docker were updated.

---

<div class="post-metadata">

### Author: ![adam\_beers](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@adam\_beers](https://meta.discourse.org/u/adam_beers)
#### Post date: [January 17, 2017, 4:48am UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/4 "2017-01-17T04:48:09Z")

</div>

How would I find the changelog around the upload API? This worked before I did an update of Discourse. The update was large, as it was about a year old.

Previously I did it this way:  
POST to `{base_url}/users/{username}/preferences/user_image?api_key={key}&api_username={username}`  
followed by  
POST to `{base_url}/users/{username}/preferences/avatar/pick?upload_id={id}api_key={key}&api_username={username}`

The upload\_id was returned by the first POST. This flow is not working anymore. Does anybody know what might have changed? Or how I can get it working again?

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [January 17, 2017, 10:20am UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/5 "2017-01-17T10:20:54Z")

</div>

> [@blake](#):
>
> The problem I found is that this just returns { “success”: “OK” } and doesn’t return the upload\_id?

You need to connect to the message-bus and listen on `/uploads` - BEFORE sending the upload - just in case the resize operation takes a long time.

I think you also need to send your message bus client\_id with the upload, too.

---

<div class="post-metadata">

### Author: ![adam\_beers](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@adam\_beers](https://meta.discourse.org/u/adam_beers)
#### Post date: [January 17, 2017, 8:23pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/6 "2017-01-17T20:23:46Z")

</div>

Is that available via API web calls?

There is supposed to be a synchronous option with uploads API as well and I can’t get that to work either. The synchronous option was supposed to return the upload\_id. At least that is what I gathered from other posts here.

---

<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: [January 17, 2017, 9:12pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/7 "2017-01-17T21:12:21Z")

</div>

Okay I just verified that I got this to work. You just need to add the `synchronous: true` value to get the id.

 ![](https://global.discourse-cdn.com/meta/original/3X/9/6/967594b1071c072f553730cb020327557062aba2.png)

now that we have the id: `17` we can then make one more request:

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

---

<div class="post-metadata">

### Author: ![adam\_beers](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@adam\_beers](https://meta.discourse.org/u/adam_beers)
#### Post date: [January 17, 2017, 9:23pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/8 "2017-01-17T21:23:26Z")

</div>

Thanks!! I will try it tonight, when I get home.

I noticed in your screenshot, that you have something in “Pre-request Script.” What is in there?

Your headers also should indicate multi-part, correct?

---

<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: [January 17, 2017, 9:48pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/9 "2017-01-17T21:48:00Z")

</div>

I don’t have anything in my headers.

My “Pre-request script” isn’t being used in these calls, but I use it to generate a random string with {{str}}:

```
postman.setEnvironmentVariable("str", Math.random().toString(36).slice(1, 16).replace(/\W/g, ''));

```

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [January 17, 2017, 10:02pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/10 "2017-01-17T22:02:06Z")

</div>

synchronous upload is only available for staff users. Non-staff users have to use the message bus method.

---

<div class="post-metadata">

### Author: ![adam\_beers](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@adam\_beers](https://meta.discourse.org/u/adam_beers)
#### Post date: [January 17, 2017, 10:07pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/11 "2017-01-17T22:07:07Z")

</div>

I’m guessing the message bus method is not available via the API calls?

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [January 17, 2017, 10:27pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/12 "2017-01-17T22:27:18Z")

</div>

It is, but it’s a very different API.  
Here’s the client code:

> <https://github.com/discourse/message_bus/blob/main/assets/message-bus.js>

It’s possible to implement it in a PHP script for sure. I think I’ve either seen it done or done it myself before (don’t remember which).

Goes something like this:

- start a new thread that posts to the message bus to register
- back in main thread, once that kicks off, start the upload
- 2nd thread loops until it gets the upload id, passes ID back to main thread, exits
- main thread waits to get the ID from the bus thread (could be a thread.join())

---

<div class="post-metadata">

### Author: ![adam\_beers](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@adam\_beers](https://meta.discourse.org/u/adam_beers)
#### Post date: [January 18, 2017, 12:57am UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/13 "2017-01-18T00:57:35Z")

</div>

I got that to work with a non-staff member. Not sure what I was doing wrong, but I had tried basically the same thing several times to no avail. One thing that I did different was I had some headers defined for “Accept” and “Content-Type”

Thanks for the help!!

---

<div class="post-metadata">

### Author: ![AntiMetaman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/antimetaman/32/186978_2.png) [@AntiMetaman](https://meta.discourse.org/u/AntiMetaman)
#### Post date: [August 12, 2020, 3:18pm UTC](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/14 "2020-08-12T15:18:12Z")

</div>

I was wondering if it’s possible for an application to send a discord auth token to discourse to upload / download a file from discourse?

That is, currently users by default can upload up to 4096 KB for avatar pics. I have discord oauth already setup and working. Can an app communicate and send the same request (maybe via SSO?) to discourse to upload or download a file?

If so, how would that request from the app work?
