# How to upload images via API with Node.js?

**URL:** https://meta.discourse.org/t/how-to-upload-images-via-api-with-node-js/172605
**Category:** Development
**Tags:** rest-api
**Created:** [December 8, 2020, 7:28am UTC](https://meta.discourse.org/t/how-to-upload-images-via-api-with-node-js/172605 "2020-12-08T07:28:36Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![jwulf](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jwulf/32/202597_2.png) [@jwulf](https://meta.discourse.org/u/jwulf)
#### Post date: [December 8, 2020, 7:28am UTC](https://meta.discourse.org/t/how-to-upload-images-via-api-with-node-js/172605/1 "2020-12-08T07:28:37Z")

</div>

This has been asked various times, but none of the solutions so far work for me.

I’m using Node.js to upload images for a post via the API.

I can create posts no problem, but images will not upload.

I convert the image (a png file) into a binary string.

Then I post an `application/json` request with the API creds in the headers, and a payload like this:

```plaintext
{
   type: "composer",
   synchronous: true,
   file: `${binary_string}`
}

```

I’ve tried both `file` as the field name for the file as the API docs say, and also `files[]` as [another post in the Forum suggested](https://meta.discourse.org/t/how-to-upload-image-using-discourse-api/148869/3).

Using `file`, I get a 422 with:

```plaintext
undefined method `tempfile' for #<String:0x00007fdfeba2b1d8>

```

Using `files[]`, I get a 422 error, with “Unprocessable Entity”.

As well as `application/json` as the docs say, I’ve also tried it as `multipart/form-data` as the Web UI does and [this poster did](https://meta.discourse.org/t/upload-avatar-image-with-api/55253/7).

For the form-data post, I did it like this:

```plaintext
 const form = new FormData();
 form.append("type", "composer");
 form.append("synchronous", "true");
 form.append("files[]", this.stringToBinary(file.data!), {
      contentType: file.mimetype,
 });

http.post("/uploads.json", form.getBuffer(), {
  headers: form.getHeaders(),
 }) // creds get added

```

With this one, with either `file` or `files[]`, I get a 422 with the error:

```plaintext
undefined method `tempfile' for #<String:0x00007fdfeba2b1d8>

```

Can anyone help?

---

<div class="post-metadata">

### Author: ![jwulf](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jwulf/32/202597_2.png) [@jwulf](https://meta.discourse.org/u/jwulf)
#### Post date: [December 8, 2020, 11:59am UTC](https://meta.discourse.org/t/how-to-upload-images-via-api-with-node-js/172605/2 "2020-12-08T11:59:59Z")

</div>

I got this to work, like this:

```plaintext
import Axios from "axios";
import FormData from "form-data";
import fs from "fs";
const http = Axios.create({
  baseURL: "https://forum.zeebe.io",
  headers: {
    "Api-Key":
      "...",
    "Api-Username": "...",
    "Content-Type": "application/json",
    Accept: "application/json",
  },
});
http.interceptors.request.use((config) => {
  if (config.data instanceof FormData) {
    Object.assign(config.headers, config.data.getHeaders());
  }
  return config;
});

const filename = "/Users/sitapati/Desktop/process.png";
const file = fs.readFileSync(filename);
const form = new FormData();
form.append("files[]", file, {
  filename,
});

http
  .post("/uploads.json", form, {
    params: {
      type: "composer",
      synchronous: true,
    },
  })
  .then(({ data }) => {
    console.info("Response from Discourse", JSON.stringify(data, null, 2));
    return {
      url: data.url,
    };
  })
  .catch((e) => {
    console.error(
      "Error uploading file to Discourse",
      JSON.stringify(e, null, 2)
    );
    throw e;
  });

```

It also works with a file retrieved from a remote URL, which needs to be retrieved like this:

```plaintext
Axios.get(file.slackUrl, {
   responseType: "arraybuffer",
   headers: { Authorization: "Bearer " + this.slackToken },
})

```

The key here is: `responseType: "arraybuffer"`.
