How to Upload a File or Image Using the Notion API
Finn Greig
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!":
Upload an image to a tool like this file to base64 converter (make sure you select "Data URI" as the output format)
Copy the output. It should look something like this:
data:file/plain;base64,SGVsbG8gV29ybGQh
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.