• Plans & Pricing
  • Log in
  • Get started
  • WordPress Hosting
  • WordPress for Agencies
  • Become an Affiliate
  • Domain Names
  • AI Website Builder
  • Website Builder
  • Create a Blog
  • Newsletter
  • Professional Email
  • Website Design Services
  • Commerce
  • WordPress Studio
  • Enterprise WordPress 
  • Overview
  • WordPress Themes
  • WordPress Plugins
  • WordPress Patterns
  • Google Apps
  • Support Center
  • WordPress News
  • Business Name Generator
  • Logo Maker
  • Discover New Posts
  • Popular Tags
  • Blog Search
Get started
  • Sign up
  • Log in
About
  • Plans & Pricing
Products
  • WordPress Hosting
  • WordPress for Agencies
  • Become an Affiliate
  • Domain Names
  • AI Website Builder
  • Website Builder
  • Create a Blog
  • Newsletter
  • Professional Email
  • Website Design Services
  • Commerce
  • WordPress Studio
  • Enterprise WordPress  
Features
  • Overview
  • WordPress Themes
  • WordPress Plugins
  • WordPress Patterns
  • Google Apps
Resources
  • Support Center
  • WordPress News
  • Business Name Generator
  • Logo Maker
  • Discover New Posts
  • Popular Tags
  • Blog Search
Jetpack App
  • Learn more
  • Support Center
  • Guides
  • Courses
  • Forums
  • Contact
Search
  • Support Center
  • Guides
  • Courses
  • Forums
  • Contact
Forums / WordPress API media/new returns empty media array despite successful 200 resp

WordPress API media/new returns empty media array despite successful 200 resp

  • Unknown's avatar
    12ftgurushogun · Member · Sep 20, 2025 at 5:22 pm
    • Copy link Copy link
    • Add topic to favorites Add topic to favorites

    Working on an application for WordPress (Progressive web app, hosted on Vercel) and the WordPress.com REST API /rest/v1/sites/{site_id}/media/new endpoint consistently returns {"media": [], "errors": []} (empty media array) despite:

    – Correct OAuth scope permissions (posts,media)
    – Valid 200 HTTP response codes
    – Proper FormData structure per documentation
    – Correct file data and headers
    – No CORs errors
    – Posts are created as expected but not images

    The application is intended to upload media to my account and create posts. This is a Premium account hosted on WordPress.com https://johneclark.wordpress.com

    At this point, my questions are:

    1. **Are there undocumented restrictions** on media uploads for certain account types or site configurations?

    2. **Is the posts,media OAuth scope sufficient** for the /rest/v1/sites/{site_id}/media/new endpoint?

    3. **Are there rate limiting or size restrictions** that return 200 but don’t process files?

    4. **Should we be using a different endpoint** for WordPress.com hosted sites vs self-hosted WordPress?

    5. **Are there required headers or request format specifics** not covered in the current documentation?

    6. **Is there additional authentication or site setup** required beyond OAuth token with media scope?

    —————————————————-

    This is the TLDR with all the icky bicky details from the Markdown file I have been keeping:

    # WordPress.com REST API Media Upload Bug Report

    **Date:** September 20, 2025

    **Reporter:** John E Clark

    **Issue:** WordPress.com REST API v1 consistently returns empty media array despite successful 200 responses

    ## Issue Summary

    The WordPress.com REST API /rest/v1/sites/{site_id}/media/new endpoint consistently returns {"media": [], "errors": []} (empty media array) despite:

    – Correct OAuth scope permissions (posts,media)

    – Valid 200 HTTP response codes

    – Proper FormData structure per documentation

    – Correct file data and headers

    ## Environment Details

    – **API Endpoint:** https://public-api.wordpress.com/rest/v1/sites/{site_id}/media/new

    – **Authentication:** OAuth 2.0 with posts,media scope

    – **Site ID:** 166975198 (verified accessible with provided token)

    – **Platform:** Node.js serverless function (Vercel)

    – **Client:** React web application

    ## Request Details

    ### OAuth Configuration

    `javascript</p> <p>scope: ‘posts media'</p> <p>client_id: [VALID_CLIENT_ID]</p> <p>response_type: ‘token'</p> <p>`

    **Token Verification:** ✅ Token successfully grants access to site information and other API endpoints

    ### Request Format

    `javascript</p> <p>// FormData structure</p> <p>const formData = new FormData();</p> <p>formData.append(‘media[]’, fileBuffer, filename);</p> <p>formData.append(‘attrs[0][caption]‘, caption);</p> <p>formData.append(‘attrs[0][alt]’, caption);</p> <p>// Request headers</p> <p>{</p> <p>’Authorization’: ‘BEARER [valid_token]’,</p> <p>’Content-Type’: ‘multipart/form-data; boundary=[auto-generated]'</p> <p>}</p> <p>`

    ### File Details

    – **File Type:** image/jpeg

    – **File Size:** 486332 bytes (valid size, under limits)

    – **Filename:** photo_1_1758071062577.jpg

    – **MIME Type:** image/jpeg

    – **File Data:** Valid JPEG buffer confirmed

    ## Expected vs Actual Behavior

    ### Expected Response

    `json</p> <p>{</p> <p>”media”: [</p> <p>{</p> <p>”ID”: 12345,</p> <p>”URL”: “https://example.wordpress.com/wp-content/uploads/file.jpg”,</p> <p>”title”: “photo_1_1758071062577”,</p> <p>”caption”: “Photo caption”</p> <p>}</p> <p>],</p> <p>”errors”: []</p> <p>}</p> <p>`

    ### Actual Response

    `json</p> <p>{</p> <p>”media”: [],</p> <p>”errors”: []</p> <p>}</p> <p>`

    – **HTTP Status:** 200 OK ✅

    – **Response Time:** ~80ms ✅

    – **Media Array:** Empty ❌

    – **Errors Array:** Empty (no error messages) ❌

    ## Troubleshooting Steps Attempted

    ### 1. OAuth Scope Verification

    – ✅ **Tested:** global scope (too broad, requires additional permissions)

    – ✅ **Tested:** posts,media scope (correct for media uploads per documentation)

    – ✅ **Verified:** Token successfully authenticates and grants site access

    ### 2. Request Format Variations

    – ✅ **Tested:** media[] array format (per documentation)

    – ✅ **Tested:** media singular format

    – ✅ **Tested:** Stream vs Buffer vs Blob data types

    – ✅ **Tested:** Various FormData option structures

    – ✅ **Tested:** With and without attrs metadata

    ### 3. File Format Testing

    – ✅ **Tested:** Multiple JPEG files (various sizes: 345KB – 486KB)

    – ✅ **Tested:** Valid MIME types (image/jpeg)

    – ✅ **Tested:** Proper file extensions (.jpg)

    – ✅ **Tested:** Files under size limits (all < 10MB)

    ### 4. API Endpoint Verification

    – ✅ **Tested:** /rest/v1/sites/{site_id}/media/new (documented endpoint)

    – ✅ **Tested:** /wp/v2/sites/{site_id}/media (returns 403, requires global scope)

    – ✅ **Verified:** Site ID correctness via /rest/v1/sites/{site_id} endpoint

    ### 5. Request Structure Validation

    `javascript</p> <p>// Tested approach based on WordPress REST API documentation</p> <p>formData.append(‘media[]’, fileBuffer, {</p> <p>filename: filename,</p> <p>contentType: ‘image/jpeg'</p> <p>});</p> <p>// Tested simplified approach based on community articles</p> <p>formData.append(‘media[]’, fileBuffer, filename);</p> <p>// Tested with various attribute formats</p> <p>formData.append(‘attrs[0][caption]‘, caption);</p> <p>formData.append(‘caption’, caption);</p> <p>`

    ## Code Implementation

    ### Complete Working Example

    `javascript</p> <p>export default async function handler(req, res) {</p> <p>try {</p> <p>// Parse multipart form data</p> <p>const form = formidable({ maxFileSize: 10 * 1024 * 1024 });</p> <p>const [fields, files] = await form.parse(req);</p> <p>const accessToken = fields.accessToken[0];</p> <p>const siteId = fields.siteId[0]; // “166975198”</p> <p>const filename = fields.filename[0];</p> <p>const caption = fields.caption[0];</p> <p>const mediaFile = files.media[0];</p> <p>const fileBuffer = fs.readFileSync(mediaFile.filepath);</p> <p>// FormData as per documentation</p> <p>const formData = new FormData();</p> <p>formData.append(‘media[]’, fileBuffer, filename);</p> <p>if (caption) {</p> <p>formData.append(‘attrs[0][caption]‘, caption);</p> <p>formData.append(‘attrs[0][alt]’, caption);</p> <p>}</p> <p>// API request</p> <p>const response = await fetch(</p> <p>https://public-api.wordpress.com/rest/v1/sites/${siteId}/media/new,</p> <p>{</p> <p>method: ‘POST’,</p> <p>headers: {</p> <p>’Authorization’: BEARER ${accessToken},</p> <p>…formData.getHeaders()</p> <p>},</p> <p>body: formData</p> <p>}</p> <p>);</p> <p>const result = await response.json();</p> <p>// result = {“media”: [], “errors”: []}</p> <p>} catch (error) {</p> <p>console.error(‘Upload failed:’, error);</p> <p>}</p> <p>}</p> <p>`

    ## Diagnostic Information

    ### Network Logs

    `</p> <p>POST https://public-api.wordpress.com/rest/v1/sites/166975198/media/new</p&gt; <p>Status: 200 OK</p> <p>Response-Time: ~80ms</p> <p>Content-Type: application/json</p> <p>`

    ### Request Headers

    `</p> <p>Authorization: BEARER [valid_token]</p> <p>Content-Type: multipart/form-data; boundary=—-formdata-node-…</p> <p>Content-Length: [calculated]</p> <p>`

    ### Response Headers

    `</p> <p>HTTP/1.1 200 OK</p> <p>Content-Type: application/json</p> <p>Server: nginx</p> <p>`

    ## Questions for WordPress Team

    1. **Are there undocumented restrictions** on media uploads for certain account types or site configurations?

    2. **Is the posts,media OAuth scope sufficient** for the /rest/v1/sites/{site_id}/media/new endpoint?

    3. **Are there rate limiting or size restrictions** that return 200 but don’t process files?

    4. **Should we be using a different endpoint** for WordPress.com hosted sites vs self-hosted WordPress?

    5. **Are there required headers or request format specifics** not covered in the current documentation?

    6. **Is there additional authentication or site setup** required beyond OAuth token with media scope?

    ## Impact

    This issue prevents programmatic media uploads to WordPress.com sites, limiting integration capabilities for applications that need to:

    – Upload user-generated content

    – Create posts with embedded images

    – Automate content publishing workflows

    – Provide seamless WordPress publishing experiences

    ## Workaround

    Currently implementing fallback simulation mode that generates WordPress-compatible post content without actual media uploads, allowing users to manually upload images later.

    ## Additional Context

    – **Site Type:** Standard WordPress.com hosted site

    – **Account Type:** [Please specify your account type]

    – **Site URL:** https://johneclark.wordpress.com

    – **API Documentation Referenced:** https://developer.wordpress.com/docs/api/1.1/post/sites/%24site/media/new/

    ## Request for Assistance

    We would appreciate:

    1. **Confirmation** if this is expected behavior or a bug

    2. **Alternative approaches** if the current method is incorrect

    3. **Additional debugging steps** to identify the root cause

    4. **Timeline** for any potential fixes if this is a known issue

    Thank you for your assistance in resolving this media upload issue.

    The blog I need help with is: (visible only to logged in users)

  • The topic ‘WordPress API media/new returns empty media array despite successful 200 resp’ is closed to new replies.

Tags

  • account
  • currency
  • design
  • images
  • modlook
  • payment

About this topic

  • In: Support
  • 1 participant
  • 0 replies
  • Last activity 3 months
  • Latest reply from 12ftgurushogun

Couldn't find what you needed?

Contact us

Contact us

Get answers from our AI assistant, with access to 24/7 expert human support on paid plans.

Browse our guides

Browse our guides

Find step-by-step solutions to common questions in our comprehensive guides.

WordPress.com

Products
  • WordPress Hosting
  • WordPress for Agencies
  • Become an Affiliate
  • Domain Names
  • AI Website Builder
  • Website Builder
  • Create a Blog
  • Professional Email
  • Website Design Services
  • WordPress Studio
  • Enterprise WordPress
Features
  • Overview
  • WordPress Themes
  • WordPress Plugins
  • WordPress Patterns
  • Google Apps
Resources
  • WordPress.com Blog
  • Business Name Generator
  • Logo Maker
  • WordPress.com Reader
  • Accessibility
  • Remove Subscriptions
Help
  • Support Center
  • Guides
  • Courses
  • Forums
  • Contact
  • Developer Resources
Company
  • About
  • Press
  • Terms of Service
  • Privacy Policy
  • Do Not Sell or Share My Personal Information
  • Privacy Notice for California Users
DeutschEspañolFrançaisBahasa IndonesiaItalianoNederlandsPortuguês do BrasilSvenskaTürkçeРусскийالعربيةעִבְרִית日本語한국어简体中文繁體中文English

Mobile Apps

  • Download on the App Store
  • Get it on Google Play

Social Media

  • WordPress.com on Facebook
  • WordPress.com on X (Twitter)
  • WordPress.com on Instagram
  • WordPress.com on YouTube

Automattic

Automattic
Work With Us
    • WordPress.com Forums
    • Sign up
    • Log in
    • Copy shortlink
    • Report this content
    • Manage subscriptions