I'm using the WP-JSON API to import all my posts from my live site to my development site. It's working fine for posts, categories and authors, but when I upload my images, the API treats the files as having been uploaded that day (so for example, as we're in June 2020, the files all go to wp-content/uploads/2020/06), which results in broken image links. How can I upload files as if they're uploaded on the same date as the source file?

Here's what I have so far (where $MEDIA is a response from my production server to /wp-json/wp/v2/media to list all my media files):

# Loop through the JSON response (encoding as base64, so each object is on a seperate line)
for media in $(printf %s "$MEDIA" | jq -r ".[] | @base64")
  media_body=$(printf %s "$media" | base64 -D)
  # Get URL and destination path
  source_url=$(printf %s "$media_body" | jq .source_url | tr -d '"')
  destination_path=$(printf %s "$media_body" | jq .media_details.file | tr -d '"')

  filename=$(basename "$destination_path")

  # Download media file to tmp directory
  curl -s "$source_url" > "/tmp/$filename"

  # Upload the media file to my dev server (store the response as a variable so we can get the ID)
  response=$(curl --request POST "http://localhost/wp-json/wp/v2/media/" \
    -u admin:admin \
    -s \
    --header "cache-control: no-cache" \
    --header "content-disposition: attachment; filename=$filename" \
    --data-binary "@/tmp/$filename" \

  id=$(printf %s "$response" | jq -r ". | .id")
  body=$(printf %s "$media_body" | jq -r ". | {date: .date, date_gmt: .date_gmt, slug: .slug, status: \"publish\", title: .title.rendered}")

  # This outputs body eg {"date": "2020-05-27T12:12:53", "date_gmt": "2020-05-27T12:12:53", "slug": "cropped-shortcut-icon-png", "status": "publish", "title": "cropped-shortcut-icon.png" }

  # Update the image's metadata
  curl --location --request POST "http://localhost/wp-json/wp/v2/media/$id" \
    -u admin:admin \
    -s -o /dev/null \
    --header 'Content-Type: application/json' \
    --data-raw "$body"
  • According to the API docs you can update the date as you're doing using a POST to /media/$id. So you're doing it but it's not working? It would be very helpful to see what the body variable looks like before you send it, maybe something goes wrong in the line where you create this variable. EDIT: looks like maybe you're suppressing the output from curl too, have you checked that that second curl command runs successfully and what the output from it says? Maybe there's an error response from the WP API
    – mozboz
    Jun 30, 2020 at 9:59
  • @mozboz I've updated the code with an example of what the JSON looks like
    – Pezholio
    Jun 30, 2020 at 10:02
  • And what does the output from the second curl look like? any errors? or does it come back 200?
    – mozboz
    Jun 30, 2020 at 10:11
  • Yep, it comes back 200, and the response returns the right data, but the file is still in wp-content/uploads/2020/06
    – Pezholio
    Jun 30, 2020 at 10:15
  • Oh, sorry maybe I misunderstood the question - you can change the metadata ok, but the file just ends up in the wrong directory?
    – mozboz
    Jun 30, 2020 at 10:40

1 Answer 1


Don't think this is possible, however will do a bit more research.

Since the functionality to expose this isn't exposed by the server, you need to do something on the server side to enable this to happen. As you're doing everything through a client-side script it wouldn't be too hard to write a little plugin on the server side which you could call with your script:

  • Send it a media ID, and a destination path (i.e. the original URL)
  • It recevies that, changes the file location and then updates the media item path

You'd call it with e.g.:

curl POST "http://localhost/wp-json/wp/v2/movemymedia"

json: { mediaID: 1234, oldPath: "06/2018" }

or whatever.

Seems like a bit of work but would keep things neat in your existing structure.

Personally I prefer to do things like this on the server because the server knows all its local setup and could e.g. move files around easily. Maybe you want to consider flipping your script to work server side pulling the content instead of client side pushing it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.