A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developers.notion.com/docs/uploading-small-files below:

Uploading small files

The Direct Upload method lets you securely upload private files to Notion-managed storage via the API. Once uploaded, these files can be reused and attached to pages, blocks, or database properties.

This guide walks you through the upload lifecycle:

  1. Create a file upload object
  2. Send the file content to Notion
  3. Attach the file to content in your workspace

💡 Tip: Upload once, attach many times. You can reuse the same file_upload ID across multiple blocks or pages.

Before uploading any content, start by creating a File Upload object. This returns a unique id and upload_url used to send the file.

🧠 Tip: Save the id — You’ll need it to upload the file in Step 2 and attach it in Step 3.

This snippet sends a POST request to create the upload object.

curl --request POST \
  --url 'https://api.notion.com/v1/file_uploads' \
  -H 'Authorization: Bearer ntn_****' \
  -H 'Content-Type: application/json' \
  -H 'Notion-Version: 2022-06-28' \
  --data '{}'
import json
import requests

payload = {
    "filename": file_name,
    "content_type": "image/png"
}

file_create_response = requests.post("https://api.notion.com/v1/file_uploads", json=payload, headers={
    "Authorization": f"Bearer {NOTION_KEY}",
    "accept": "application/json",
    "content-type": "application/json",
    "Notion-Version": "2022-06-28"
})

if file_create_response.status_code != 200:
    raise Exception(
        f"File creation failed with status code {file_create_response.status_code}: {file_create_response.text}"
    )

file_upload_id = json.loads(file_create_response.text)['id']

{
  "object": "file_upload",
  "id": "a3f9d3e2-1abc-42de-b904-badc0ffee000",
  "created_time": "2025-04-09T22:26:00.000Z",
  "last_edited_time": "2025-04-09T22:26:00.000Z",
  "expiry_time": "2025-04-09T23:26:00.000Z",
  "upload_url": "https://api.notion.com/v1/file_uploads/a3f9d3e2-1abc-42de-b904-badc0ffee000/send",
  "archived": false,
  "status": "pending",
  "filename": null,
  "content_type": null,
  "content_length": null,
  "request_id": "b7c1fd7e-2c84-4f55-877e-d3ad7db2ac4b"
}

Next, use the upload_url or File Upload object id from Step 1 to send the binary file contents to Notion.

Tips:

This uploads the file directly from your local system.

curl --request POST \
  --url 'https://api.notion.com/v1/file_uploads/a3f9d3e2-1abc-42de-b904-badc0ffee000/send' \
  -H 'Authorization: Bearer ntn_****' \
  -H 'Notion-Version: 2022-06-28' \
  -H 'Content-Type: multipart/form-data' \
  -F "file=@path/to-file.gif"
// Open a read stream for the file
const fileStream = fs.createReadStream(filePath)

// Create form data with the (named) file contents under the `file` key.
const form = new FormData()
form.append('file', fileStream, {
	filename: path.basename(filePath)
})

// HTTP POST to the Send File Upload API.
const response = await fetch(
	`https://api.notion.com/v1/file_uploads/${fileUploadId}/send`,
	{
		method: 'POST',
		body: form,
		headers: {
			'Authorization': `Bearer ${notionToken}`,
			'Notion-Version': notionVersion,
		}
	}
)

// Rescue validation errors. Possible HTTP 400 cases include:
// - content length greater than the 20MB limit
// - FileUpload not in the `pending` status (e.g. `expired`)
// - invalid or unsupported file content type
if (!response.ok) {
	const errorBody = await response.text()
	console.log('Error response body:', errorBody)
	throw new Error(`HTTP error with status: ${response.status}`)
}

const data = await response.json()
// ...

file_name = "test.png"

with open(file_name, "rb") as f:
		# Provide the MIME content type of the file as the 3rd argument.
    files = {
        "file": (file_name, f, "image/png")
    }

    response = requests.post(
        f"https://api.notion.com/v1/file_uploads/{file_upload_id}/send",
        headers={
            "Authorization": f"Bearer {NOTION_KEY}",
            "Notion-Version": "2022-06-28"
        },
        files=files
    )

    if response.status_code != 200:
        raise Exception(
            f"File upload failed with status code {response.status_code}: {response.text}")

{
  "object": "file_upload",
  "id": "a3f9d3e2-1abc-42de-b904-badc0ffee000",
  "created_time": "2025-04-09T22:26:00.000Z",
  "last_edited_time": "2025-04-09T22:27:00.000Z",
  "expiry_time": "2025-04-09T23:26:00.000Z",
  "archived": false,
  "status": "uploaded",
  "filename": "Really funny.gif",
  "content_type": "image/gif",
  "content_length": "4435",
  "request_id": "91a4ee8c-61f6-4c27-bd41-09aa35299929"
}

Reminder

Files must be attached within 1 hour of upload or they’ll be automatically moved to an archived status.

Once the file’s status is uploaded, it can be attached to any location that supports file objects using the File Upload object id.

This step uses standard Notion API endpoints; there’s no special upload-specific API for attaching. Just pass a file object with a type of file_upload and include the id that you received earlier in Step 1.

You can use the file upload id with the following APIs:

  1. Create a page
  2. Update page properties
  3. Append block children
  4. Update a block

This example uses the Append block children API to create a new image block in a page and attach the uploaded file.

curl --request PATCH \
	--url "https://api.notion.com/v1/blocks/$PAGE_OR_BLOCK_ID/children" \
	-H "Authorization: Bearer ntn_*****" \
	-H 'Content-Type: application/json' \
	-H 'Notion-Version: 2022-06-28' \
	--data '{
		"children": [
			{
				"type": "image",
				"image": {
					"caption": [],
					"type": "file_upload",
					"file_upload": {
						"id": "'"$FILE_UPLOAD_ID'""
					}
				}
			}
		]
	}'
# Append image to desired block (this could be a page,
# or a block within a page)
url = f"https://api.notion.com/v1/blocks/{append_block_id}/children"

payload = {
    "children": [
        {
            "object": "block",
            "type": "image",
            "image": {
                "type": "file_upload",
                "file_upload": {
                    "id": file_upload_id
                }
            }
        }
    ]
}

response = requests.patch(url, headers={
    "Authorization": f"Bearer {NOTION_KEY}",
    "accept": "application/json",
    "content-type": "application/json",
    "Notion-Version": "2022-06-28"
}, data=json.dumps(payload))

if response.status_code != 200:
    raise Exception(
        f"Block append failed with status code {response.status_code}: {response.text}")

example uses the Append block children API to create a new file block in a page and attach the uploaded file.

curl --request PATCH \
  --url "https://api.notion.com/v1/blocks/$PAGE_OR_BLOCK_ID/children" \
  -H "Authorization: Bearer ntn_*****" \
  -H 'Content-Type: application/json' \
  -H 'Notion-Version: 2022-06-28' \
  --data '{
	  "children": [
		  {
			  "type": "file",
			  "file": {
				  "type": "file_upload",
				  "file_upload": {
					  "id": "'"$FILE_UPLOAD_ID"'"
				  }
			  }
		  }
	  ]
  }'

This example uses the Update page properties API to ad the uploaded file to a files property on a page that lives in a Notion database.

curl --request PATCH \
  --url "https://api.notion.com/v1/pages/$PAGE_ID" \
  -H 'Authorization: Bearer ntn_****' \
  -H 'Content-Type: application/json' \
  -H 'Notion-Version: 2022-06-28' \
  --data '{
    "properties": {
      "Attachments": {
        "type": "files",
        "files": [
          {
            "type": "file_upload",
            "file_upload": { "id": "9a8b7c6d-1e2f-4a3b-9e0f-a1b2c3d4e5f6" },
            "name": "logo.png"
          }
        ]
      }
    }
  }'

This example uses the Update page properties API to add the uploaded file as a page cover.

curl --request PATCH \
  --url "https://api.notion.com/v1/pages/$PAGE_ID" \
  -H 'Authorization: Bearer ntn_****' \
  -H 'Content-Type: application/json' \
  -H 'Notion-Version: 2022-06-28' \
  --data '{
	  "cover": {
		  "type": "file_upload",
		  "file_upload": {
			  "id": "'"$FILE_UPLOAD_ID"'"
		  }
	  }
  }'

✅ You’ve successfully uploaded and attached a file using Notion’s Direct Upload method.

When a file is first uploaded, it has an expiry_time, one hour from the time of creation, during which it must be attached.

Once attached to any page, block, or database in your workspace:

Even if the original content is deleted, the file_upload ID remains valid and can be reused to attach the file again.

Currently, there is no way to delete or revoke a file upload after it has been created.

Attaching a file upload gives you access to a temporary download URL via the Notion API.

These URLs expire after 1 hour.

To refresh access, re-fetch the page, block, or database where the file is attached.

📌 Tip: A file becomes persistent and reusable after the first successful attachment — no need to re-upload.

Updated about 2 months ago


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4