Notion audio block from a Sume music URL: the extension check
Notion's external audio block lists .mp3, .wav, .ogg, .oga and .m4a. Check that the Sume artifact URL path ends in one; if not, use Notion's File Upload.

You can add a Sume track to a Notion page as an audio block with an external URL, but Notion documents the accepted file extensions: .mp3, .wav, .ogg, .oga and .m4a. Sume's Music Router returns the audio as an artifact, usually audio/mpeg, on media.sume.com. Look at the URL path first. If it does not end in one of those extensions, upload the file through Notion's File Upload API instead of linking it.
What Notion documents
The block reference describes the audio block and the rule for external files.
| Topic | Notion documents |
|---|---|
| Block type | audio, with an external or uploaded file |
| External URL extensions | mp3, wav, ogg, oga, m4a |
| Alternative | The File Upload API, which accepts a wider set of types |
Create the block
A Music Router job costs a fixed $0.125 and returns the file in result.artifacts[] with type audio. Read the URL from the job result, test the path, and only then append the block to the page.
import json, os, urllib.request
from urllib.parse import urlparse
OK = (".mp3", ".wav", ".ogg", ".oga", ".m4a")
def add_audio(page_id: str, url: str) -> None:
if not urlparse(url).path.lower().endswith(OK):
raise ValueError("extension not in Notion's list: use File Upload")
body = {"children": [{"object": "block", "type": "audio",
"audio": {"type": "external", "external": {"url": url}}}]}
req = urllib.request.Request(
"https://api.notion.com/v1/blocks/%s/children" % page_id,
data=json.dumps(body).encode(), method="PATCH",
headers={"Authorization": "Bearer " + os.environ["NOTION_TOKEN"],
"Notion-Version": os.environ["NOTION_VERSION"],
"Content-Type": "application/json"})
urllib.request.urlopen(req, timeout=10).read()Why the check is worth it
The rule is about the file name in the link, not the bytes. A URL can serve a valid mp3 and still fail a name-based test. Sume does not promise a specific file name or extension for artifacts, so treat the name as something to inspect. The NOTION_VERSION value is read from the environment in the sample because the header value belongs to your integration setup; use the version your integration targets.
Limits
An external link is not a copy. If the track must outlive the source URL, download it and upload it through Notion, and keep the Sume job id beside it for provenance. Notion's page does not state a size limit for external audio; do not invent one in your own docs.
Before you ship
None of this needs a Sume webhook: poll the job envelope until it says terminal, or use webhook mode and add the block from your receiver once the job completes.
- Check the artifact URL path before you create the block.
- Keep the job id in a Notion property.
- Use the File Upload route when the URL has no audio extension.
- Do not store the API key in a Notion property.
Sources
Related posts
More in Integrations
- Obsidian plugin: call Sume with requestUrl and embed the image
Obsidian's requestUrl skips CORS limits, so a plugin can POST to Sume's /v1/images. Save the file with createBinary and insert an embed. Handle the 202 case.
- Odysee 16 GB upload limit vs a 1800-second Sume source
Odysee caps uploads at 16 GB. A 1800-second Sume source would need about 71 Mbps to reach it. Worked sizes at 8, 25 and 50 Mbps, with a Python check.
- Odysee 8 Mbps bitrate warning and Sume's missing bitrate field
Odysee warns above 8 Mbps and suggests 720p if 1080p at 30 fps runs high. Sume trim has no bitrate field, so use width, height and fps, then probe the average.
- Odysee needs H264 and AAC MP4: what Sume trim exact outputs
Odysee wants MP4 with H264 video and AAC audio, or the video has no sound. Sume trim in exact mode re-encodes to libx264 with AAC audio. Check it with a probe.
Written by Sume