WordPress media_handle_sideload for a Sume music mp3 attachment
Download the Sume artifact URL with download_url(), then media_handle_sideload() it into the Media Library. It returns an attachment id or a WP_Error.

To put a finished Sume track into the WordPress Media Library, fetch the artifact URL with download_url(), build a $file_array, and pass it to media_handle_sideload(). WordPress documents that it returns the attachment id, or a WP_Error on failure. It only works after you load three admin include files, which a REST route does not load for you.
What the function needs
The WordPress reference describes the call as media_handle_sideload( $file_array, $post_id, $desc, $post_data ).
| Item | Documented behavior |
|---|---|
| Download step | Use download_url() to fetch the remote file to a temp path |
| Arguments | $file_array, $post_id, $desc, $post_data |
| Return | Attachment id, or WP_Error |
| Includes | wp-admin/includes/media.php, file.php and image.php must be loaded |
From a Sume job to an attachment
The Music Router returns the audio in result.artifacts[] with type audio, on media.sume.com. Pull the URL from the job result in your webhook handler or a cron task. In a REST handler, the three includes are not there yet, so require them first.
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
function sume_sideload_track( string $url, int $post_id, string $title ) {
$tmp = download_url( $url, 60 );
if ( is_wp_error( $tmp ) ) {
return $tmp;
}
$file = array(
'name' => sanitize_file_name( $title ) . '.mp3',
'tmp_name' => $tmp,
);
$id = media_handle_sideload( $file, $post_id, $title );
if ( is_wp_error( $id ) ) {
@unlink( $tmp );
}
return $id;
}Check the extension and the type
The filename you give is the one WordPress uses to decide whether the upload is allowed. Sume's docs say the router audio is usually audio/mpeg, so .mp3 is the usual name; check the artifact content_type before you hard-code it, and fall back to the extension that matches. If WordPress returns a WP_Error about the file type, log the code and the content type, and do not retry blindly.
Idempotency on your side
Sume deduplicates the generation with the Idempotency-Key header, but it cannot know that your sideload ran. If a webhook is delivered twice, store the job id as post meta and skip when it already exists. A music generation costs a fixed $0.125, while a duplicate attachment only costs disk space, so the meta check matters most for tidiness.
Before you ship
- Run the sideload from a webhook handler or WP-Cron, not inside a page request.
- Store the Sume job id as post meta and skip duplicates.
- Log the WP_Error code and the artifact content type when a sideload fails.
- Delete the temp file when WordPress returns an error.
Sources
Related posts
More in Integrations
- X media upload APPEND: 5 MB chunks, and how to split a Sume MP4
The X API v2 APPEND step takes chunks of at most 5 MB. Count the segments for a Sume MP4 with a short script before you upload to the initialize endpoint.
- X media upload processing_info states: poll until succeeded
After FINALIZE on the X API v2, processing_info moves from pending to in_progress to succeeded or failed. Poll using check_after_secs, then post the Sume video.
- YouTube's Shorts help page says vertical, not 9:16: what to render
YouTube's Shorts help page states 3 minutes, vertical uploads and a 1080p maximum, but names no ratio. Render 1080x1920 with Sume Timeline 1.0 and probe it.
- Zapier MCP bills 2 tasks per success; retry Sume tools with one key
Zapier MCP charges 2 tasks per successful call and nothing for failures. A paid Sume tool needs an idempotency_key, and a repeat with the same key is safe.
Written by Sume