Hub Media Import API
30 min
overview the media import api provides a powerful endpoint for uploading, updating, and managing wordpress media attachments programmatically it supports both direct file uploads and url based imports, with advanced features like hash based deduplication and multilingual support endpoint post /wp json/purple/v3/import/media authentication required yes (bearer token) please take a look into the https //docs purplepublish com/editorial/hub import api#authentication for more information required capability edit posts table of contents /#quick start /#request parameters /#response format /#use cases examples /#deduplication modes /#error handling docid quick start upload a new image curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ f 'file=@/path/to/image jpg' \\ f 'metadata\[title]=my image' \\ f 'metadata\[alt]=image description' import from url curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ h 'content type application/json' \\ d '{ "fileurl" "https //example com/image jpg", "metadata" { "title" "remote image", "alt" "description" } }' request parameters file source (choose one) parameter type description file file direct file upload (multipart/form data) fileurl string url to download the file from note provide either file or fileurl , not both when an existing attachmentid or mediahash (see below) is provided, it is not necessary to provide one of these update existing attachment (optional) parameter type description attachmentid integer wordpress attachment id to update mediahash string sha 256 hash to identify attachment note if provided without a new file, only metadata is updated metadata (optional) field type description metadata\[title] string attachment title metadata\[alt] string alt text for images metadata\[caption] string caption text metadata\[description] string full description metadata\[focalpoint]\[x] integer focal point x metadata\[focalpoint]\[y] integer focal point y metadata\[acf] object advanced custom fields data multilingual support (polylang) parameter type description languageslug string language code (e g , 'en', 'de', 'fr') metadata\[duplicateassetsbylanguage] boolean enable language based deduplication post association (optional) parameter type description targetposts array post ids to associate with this media response format success response (200 ok) { "attachmentid" 123, "mediahash" "a7f3c9d2e8b1f4a6c5d8e9f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1", "url" "https //your site com/wp content/uploads/2024/01/image jpg" } error response { "code" "invalid file type", "message" "invalid file type file type not allowed by wordpress ", "data" { "status" 400 } } use cases & examples 1\ upload new image with metadata curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ f 'file=@product jpg' \\ f 'metadata\[title]=product photo' \\ f 'metadata\[alt]=red bicycle in store' \\ f 'metadata\[caption]=our new 2024 model' \\ f 'metadata\[description]=high quality mountain bike' \\ f 'metadata\[focalpoint]\[x]=60' \\ f 'metadata\[focalpoint]\[y]=40' 2\ import from external url curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ h 'content type application/json' \\ d '{ "fileurl" "https //cdn example com/images/product 123 jpg", "metadata" { "title" "product 123", "alt" "product photo", "caption" "imported from cdn" } }' 3\ update existing attachment update metadata only curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ h 'content type application/json' \\ d '{ "attachmentid" 123, "metadata" { "title" "updated title", "alt" "updated alt text" } }' replace file and update metadata curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ f 'attachmentid=123' \\ f 'file=@new image jpg' \\ f 'metadata\[title]=replaced image' 4\ update by media hash curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ h 'content type application/json' \\ d '{ "mediahash" "a7f3c9d2e8b1f4a6c5d8e9f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1", "metadata" { "caption" "updated via hash" } }' 5\ associate with multiple posts curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ f 'file=@shared image jpg' \\ f 'targetposts\[]=101' \\ f 'targetposts\[]=202' \\ f 'targetposts\[]=303' \\ f 'metadata\[title]=shared image' 6\ multilingual upload (polylang) upload english version curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ f 'file=@product jpg' \\ f 'languageslug=en' \\ f 'metadata\[duplicateassetsbylanguage]=true' \\ f 'metadata\[title]=english product' \\ f 'metadata\[alt]=english description' upload german version (reuses file!) curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ f 'file=@product jpg' \\ f 'languageslug=de' \\ f 'metadata\[duplicateassetsbylanguage]=true' \\ f 'metadata\[title]=deutsches produkt' \\ f 'metadata\[alt]=deutsche beschreibung' result two attachment posts, one physical file 7\ advanced custom fields (acf) curl x post 'https //your site com/wp json/purple/v3/import/media' \\ h 'authorization bearer your token' \\ h 'content type application/json' \\ d '{ "fileurl" "https //example com/image jpg", "metadata" { "title" "product image", "acf" { "photographer" "john doe", "license" "cc by sa", "shooting date" "2024 01 15" } } }' deduplication modes the api supports two deduplication strategies 1\ hash based deduplication (default) how it works calculates sha 256 hash of file content if hash exists → returns existing attachment prevents duplicate files globally best for single language sites preventing duplicate uploads saving disk space example \# first upload curl f 'file=@image jpg' \# response attachmentid 123 \# second upload (same file) curl f 'file=@image jpg' \# response attachmentid 123 (same!) 2\ language based deduplication how it works checks by filename + language if filename exists in same language → returns existing if filename exists in different language → creates new attachment, reuses file creates separate attachment posts per language all language variants share the same physical file best for multilingual sites (polylang) language specific metadata (alt text, captions) disk space efficiency example \# upload english version curl f 'languageslug=en' f 'metadata\[duplicateassetsbylanguage]=true' f 'file=@image jpg' \# response attachmentid 123, file /uploads/image jpg \# upload german version (same file content) curl f 'languageslug=de' f 'metadata\[duplicateassetsbylanguage]=true' f 'file=@image jpg' \# response attachmentid 124, file /uploads/image jpg (same file!) result ✅ two attachment posts (#123 en, #124 de) ✅ language specific metadata ✅ one physical file on disk ✅ no disk space waste when to use content with language specific alt text/captions pdfs with embedded text in different languages images with localized graphics/text error handling common error codes code http status description invalid file upload 400 missing or invalid file invalid file type 400 file type not allowed by wordpress file too large 400 file exceeds 50mb limit invalid url 400 invalid or malformed url ssrf protection 400 url points to private/reserved ip attachment not found 404 attachment id doesn't exist media hash not found 404 no attachment with that hash polylang required 400 duplicateassetsbylanguage set but polylang not active upload directory error 500 wordpress upload directory issue error response format { "code" "file too large", "message" "file too large maximum size is 50mb ", "data" { "status" 400 } }