How to Upload a File or Image Using the Notion API

Want to add your own file or image to a database or page in Notion using their API? Unfortunately this is not (officially) supported yet:

"For files and URLs hosted outside of Notion, we support retrieving the link as well as updating it to a different link. We don't currently support uploading files to Notion through the API, however, for files already uploaded to Notion, we support retrieving the file URL." - https://developers.notion.com/reference/file-object#externally-hosted-files-vs-files-hosted-by-notion

However, there is a workaround we could use - base64 data URIs. If those work for page icons, then there's no reason why they can't work for file uploads right? Unfortunately this is not the case. When I tried using a base64 data URI directly in their API this is what I got back:

{ "object": "error", "status": 400, "code": "validation_error", "message": "Content creation Failed. Fix the following: \nInvalid image url." } 

There's a workaround we can do however, which uses a low-code integration platform called Pipedream, which is similar to Zapier or Make (formerly Integromat).

Here's the workflow I'm using:

The code is available here.

Here's an example of how I did it using a text file that contains "Hello World!":

  1. Upload an image to a tool like this file to base64 converter (make sure you select "Data URI" as the output format)

  2. Copy the output. It should look something like this:

    data:file/plain;base64,SGVsbG8gV29ybGQh 
  3. Perform your API request with the data URI wrapped up with your Pipedream URL:

    curl 'https://api.notion.com/v1/pages' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \ -H "Content-Type: application/json" \ -H "Notion-Version: 2022-02-22" \ --data '{ "parent": { "database_id": "d9824bdc84454327be8b5b47500af6ce" }, "properties": { "Name": { "title": [ { "text": { "content": "Test" } } ] } }, "children": [ { "object": "block", "type": "file", "file": { "type": "external", "external": { "url": "https://eoz4qft7xt8bz0.m.pipedream.net/?uri=data:file/plain;base64,SGVsbG8gV29ybGQh" } } } ] }' 

You should get a 200 OK:

{ "object": "page", "id": "3d86e8d5-dd14-407d-a9b2-fed49233cf8d" } 

And your file should be on your page:

While the file name isn't pretty and this won't work for files that aren't small (URL length constraints), it's an easy way to get a file into Notion using only their API without touching the web application. Keep in mind however that when this file is accessed a request with the data will be made to an external server - this may or may not be suitable for your purposes.

Let me know your thoughts down in the comments section below 👇

Comments