Personal operations
Read owned content, upload artwork, and submit edits through the protected API.
Connect your app, then send requests from your server to
https://api.mediux.io with Authorization: Bearer ACCESS_TOKEN. Keep tokens
and upload bytes out of logs and browser state; do not send account cookies.
Responses use private, no-store for browser and edge caches, with no
stale-while-revalidate.
Jump to metadata edits, single-file uploads, Set creation, Set edits, or recovery.
Available operations
Section titled “Available operations”Scopes grant permissions, not ownership. Each request checks the connection, resource ownership, and any required revision.
Read owned content
Section titled “Read owned content”| Route | Scope |
|---|---|
GET /me/assets/{assetId} |
assets:write or assets:replace |
GET /me/sets/{setId} |
sets:write |
GET /me/groups/{groupId} |
groups:write |
GET /me/upload-destinations |
sets:write for talent_set/media_set; groups:write for boxset |
For destinations, set kind to talent_set, media_set, or boxset. Optional
family=game selects game destinations; the default is media. Use q to
search. Results contain compatible owned destinations and are limited.
Upload and edit artwork
Section titled “Upload and edit artwork”| Route | Scope | Action |
|---|---|---|
POST /me/assets |
assets:write to add; assets:replace to replace |
Upload standalone artwork |
POST /me/sets/{setId}/assets |
assets:write to add; assets:replace to replace |
Upload artwork to an owned Set |
POST /me/groups/{groupId}/poster |
Asset scope above plus groups:write |
Upload a Boxset or Loadout poster |
GET /me/asset-uploads/{clientMutationId} |
assets:write or assets:replace |
Check an upload’s outcome |
POST /me/assets/{assetId}/metadata |
assets:write |
Change language or edition |
POST /me/assets/{assetId}/preview |
assets:replace |
Select an animated preview frame |
Organize artwork and relationships
Section titled “Organize artwork and relationships”| Route | Scope | Action |
|---|---|---|
POST /me/groups |
groups:write |
Create a Boxset or Loadout |
POST /me/groups/{groupId} |
groups:write |
Edit group metadata or membership |
POST /me/grouping-sets |
sets:write |
Create a Talent, Brand, or Category Set |
POST /me/grouping-sets/{setId}/assets |
sets:write |
Assign owned standalone artwork |
GET /me/relationships |
relationships:write |
Read follows and hides |
POST /me/relationships |
relationships:write |
Follow, hide, or clear a relationship |
Content deletion and account management are not available through this API. Set creation and grouped edit routes are described below.
Sparse metadata edits
Section titled “Sparse metadata edits”Read the Asset, then pass its exact updatedAt as expectedUpdatedAt. Include
only changed fields; omitted fields stay unchanged. Use null only for fields
that allow clearing.
const { data: asset } = await privateClient.getAsset(ASSET_ID);const receipt = await privateClient.updateAssetMetadata(asset.id, { expectedUpdatedAt: asset.updatedAt, languageCode: "fr",});This calls POST /me/assets/{assetId}/metadata with a JSON body. On a stale
revision (409), reload and review the edit before submitting again. See the
SDK guide to create privateClient.
One raw Asset upload
Section titled “One raw Asset upload”Send one file as the raw body, not multipart data:
API=https://api.mediux.ioMUTATION_ID=01957988-4c76-7e58-bb68-3a3ad37603a5UPLOAD_SHA256=$(sha256sum movie-poster.png | cut -d ' ' -f 1)
curl --fail-with-body --request POST \ "$API/me/assets?operation=add&clientMutationId=$MUTATION_ID&slot=poster&targetId=603&targetKind=movie&languageCode=en" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H 'Content-Type: image/png' \ -H 'X-Upload-Filename: movie-poster.png' \ -H "X-Upload-SHA256: $UPLOAD_SHA256" \ --data-binary @movie-poster.pngUse a unique UUID for clientMutationId and a lowercase SHA-256 digest of the
file. Keep both for recovery. The body length must match Content-Length,
which curl sets for this file. Mediux validates the actual file, size,
dimensions, and target compatibility.
To replace artwork, use operation=replace, add previousAssetId=ASSET_ID,
and request assets:replace. For Set artwork, use
/me/sets/{setId}/assets and the Set’s target fields. For a group poster, use
/me/groups/{groupId}/poster with the additional groups:write scope.
The SDK’s upload methods calculate the digest. A receipt identifies the saved
Asset; publicationStatus: pending means public reads have not yet caught up.
Create a Media Set
Section titled “Create a Media Set”All four routes require sets:write and assets:write:
| Step | Route |
|---|---|
| Declare the Set and files | POST /me/set-uploads |
| Upload each file | POST /me/set-uploads/{submissionId}/assets?itemId={itemId} |
| Check progress | GET /me/set-uploads/{submissionId} |
| Complete the submission | POST /me/set-uploads/{submissionId}/complete with {} |
The initial request fixes the Set metadata and file declarations. Replace
34845 below with the actual file size in bytes:
SUBMISSION_CLIENT_ID=01957988-4c76-7e58-bb68-3a3ad37603b4ITEM_ID=01957988-4c76-7e58-bb68-3a3ad37603b5
curl --fail-with-body --request POST \ "$API/me/set-uploads" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H 'Content-Type: application/json' \ --data @- <<JSON{ "clientMutationId": "$SUBMISSION_CLIENT_ID", "setKind": "media_set", "entryTargetKind": "movie", "entryTargetId": 603, "titleBase": "My Movie Set", "description": null, "languageCode": "en", "editionId": null, "finalised": false, "destination": null, "declaredFiles": [ { "itemId": "$ITEM_ID", "position": 0, "targetKind": "movie", "targetId": 603, "slot": "poster", "filename": "movie-poster.png", "contentType": "image/png", "contentLength": 34845, "selectedSourceFrame": null } ]}JSONRead submission.submissionId from the admission response, then transfer the
file with exactly the frozen declaration:
SUBMISSION_ID=replace-with-submission-submissionId
curl --fail-with-body --request POST \ "$API/me/set-uploads/$SUBMISSION_ID/assets?itemId=$ITEM_ID" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H 'Content-Type: image/png' \ -H 'Content-Length: 34845' \ -H 'X-Upload-Filename: movie-poster.png' \ --data-binary @movie-poster.png
curl --fail-with-body \ "$API/me/set-uploads/$SUBMISSION_ID" \ -H "Authorization: Bearer $ACCESS_TOKEN"
curl --fail-with-body --request POST \ "$API/me/set-uploads/$SUBMISSION_ID/complete" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H 'Content-Type: application/json' \ --data '{}'Complete after all file outcomes are terminal. The SDK’s createMediaSet
combines these steps with bounded upload concurrency and status checks.
Its outcomes are succeeded, partial, rolled_back, failed, or
unresolved. For partial, keep successful Asset IDs and inspect each failed
item. Correct failed items with a new mutation only after the submission is
terminal. unresolved means the client could not confirm the result; it does
not cancel server work.
Grouped Set edits
Section titled “Grouped Set edits”Stage several changes together while the public Set remains unchanged, then complete the submission to save successful changes.
| Route | SDK method |
|---|---|
POST /me/sets/{setId}/updates |
admitSetUpdate(input) |
POST /me/set-updates/{submissionId}/assets?itemId={itemId} |
uploadSetUpdateItem(id, itemId, file) |
GET /me/set-updates/{submissionId} |
getSetUpdate(id) |
POST /me/set-updates/{submissionId}/complete with {} |
completeSetUpdate(id) |
These routes require sets:write. The initial request also requires
assets:write for additions or Asset metadata edits, and assets:replace
for replacements.
Include clientMutationId, setId, setKind, the Set’s exact
expectedUpdatedAt, sparse changes, and up to 300 items. Supported
setKind values are media_set, talent_set, brand_set, and category_set.
Omitted metadata stays unchanged; omitted Assets are never removed.
Each item needs a unique itemId, position, targetKind, targetId, and
slot, plus the fields for its operation:
| Operation | Additional fields |
|---|---|
add |
declaredFile |
replace |
declaredFile, expectedPreviousAssetId, expectedAssetUpdatedAt |
assign |
existingAssetId, expectedAssetUpdatedAt |
asset_metadata |
existingAssetId, expectedAssetUpdatedAt, sparse changes for languageCode and/or editionId |
Set unused identity fields to null. Non-file items use declaredFile: null.
File declarations contain filename, contentType, contentLength, and
selectedSourceFrame (or null). Upload raw bytes with matching headers.
editSet(admission, [{ itemId, file }], options) combines these calls and returns
succeeded, partial, failed, or unresolved. An uploaded item can remain
processing until completion. If replacements fail but metadata succeeds,
completion saves the metadata and keeps the previous artwork.
Retain submission and item IDs, successful Asset IDs, and errors. Processing
can be terminal while publicationStatus is still pending. Resolve stale
revision conflicts by reviewing current data; correct terminal failed items
with a new edit.
Reconcile before retrying
Section titled “Reconcile before retrying”After a timeout or lost response, retain the original identity:
| Request | Recovery |
|---|---|
| Granular Asset upload | GET /me/asset-uploads/{clientMutationId} |
| Set creation | GET /me/set-uploads/{submissionId} |
| Grouped Set edit | GET /me/set-updates/{submissionId} |
If the initial Set request returned no submission ID, send the identical
body with the same clientMutationId to recover its receipt. Never change the
declared intent or create a new identity to retry an uncertain request. For an
uncertain file transfer, read the submission’s item status first.
Granular upload status returns data.processingStatus (processing,
succeeded, or failed), publicationStatus (not_required, pending, or
succeeded), available mutation and Asset IDs, retryable: false, and an
optional { code, message } error. Pending publication does not justify a
second upload; neither does a failed status justify a blind replay.
| Response | Recovery |
|---|---|
401 |
Renew credentials explicitly if the connection permits it; reconcile the mutation before retrying. |
403 |
Check required scopes and current ownership. |
409 |
Reload the resource or reconcile the conflicting file declaration. |
503 with set_creation_upload.outcome_unresolved |
Keep submission and item IDs; retrieve status first. |
Structured errors
Section titled “Structured errors”{ "error": { "code": "asset.file.maxSize", "message": "Filesize too large", "details": { "maxBytes": 20971520 }, "issues": [ { "code": "asset.file.maxSize", "message": "Filesize too large", "path": ["file"] } ] }}Branch on code, not message text. Preserve details and issues[*].path
to show the affected field or item. Keep tokens, request headers, and internal
exceptions out of your app’s error responses.