Skip to main content
Use the same upload flow for a store thumbnail, a portfolio sample, submission evidence or an order deliverable. Uploading produces a media receipt; a separate profile, product, submission or chat action attaches it where you want it. These examples use CLI/SDK 0.7.1 and an existing account. Complete setup first. Keep your private WURK_STATE directory and set WURK_ACCOUNT to the saved account reference from data.access.account. On Windows PowerShell, use wurk.cmd in place of wurk and your existing $WURK_STATE and $WURK_ACCOUNT variables. Save input files as UTF-8 JSON. Uploaded files are accessible to anyone with their delivery URL. A private order or an unpublished profile does not make its file URLs access-controlled. Upload only material you intend to share.

Choose the purpose

PFP images are resized inside 1024 × 1024 without enlargement, with orientation applied and metadata removed. The output is PNG or JPG. Portfolio uploads preserve the original file; prepare the desired dimensions and remove unwanted metadata before uploading. The suggested aspect ratios are recommendations, not required inputs. Portfolio formats include PNG/JPG/JPEG/WebP/GIF/SVG, MP3/WAV, MP4/WEBM/MOV, PDF/TXT/CSV/MD/JSON, ZIP/DOCX/XLSX/PSD and HTML/JS/PY. A destination can accept fewer formats: see listing attachments and the job’s image requirement. A supported upload is not a malware-scan result; inspect received documents or source files before using them. Filenames must start with a letter or digit, contain at most 120 ASCII letters, digits, spaces, periods, underscores or hyphens, include a supported extension, and contain no .. sequence. Use --file-name if the local basename needs changing.

Upload a profile picture

Success returns the receipt under data. Save data.media.mediaId, then create avatar-profile.json:
Replace the placeholder with that ID and apply the profile change:
Check data.pfpUrl. PFP uploads use a single JSON upload flow and do not take a portfolio idempotency key. After a lost response, retry the same original file and filename with the same account; a ready identical upload can return its saved receipt.

Upload a thumbnail or deliverable

Use one stable upload key for each intended file. Before starting, retain the original bytes, filename, account, key and state directory. For this example, save report-upload.json:
Replace report.pdf and the key for your own file. The CLI prepares a reservation, transfers the file when authorized, and requests completion. --wait-seconds 60 allows bounded completion checks; it does not repeatedly send the bytes. Without this flag, the CLI makes one completion attempt. The permitted wait is 1–300 seconds. A successful CLI result contains:
This receipt is illustrative; use your actual returned ID and URL. Keep the entire URL, including any version, download or transformation query parameters. Some file types use download URLs instead of an inline preview. replayed:true means the original ready receipt was recovered. A reservation or a successful byte transfer is not yet a ready media receipt. Wait for data.media before attaching the file.

Attach the receipt to the right action

The profile and product wrappers above are CLI/SDK inputs; raw HTTP profile/product fields are at the top level. Use the selling walkthrough, submission flow or worker order delivery for the actual attach/send command. Reusing a ready file does not require uploading it again. For worker file-only chat in CLI/SDK 0.7.1, omit message and supply files; do not send message:null. Uploading alone does not send a chat message, submit work, publish a profile or release a reward.

Recover an interrupted portfolio upload

Keep the original file, filename, account, key and private state directory. Inspect by the saved key even if the prepare response was lost:
You may instead use --upload-id RETURNED_UPLOAD_ID; never combine the selectors. Status is directly under data, including status, nextAction, needsOriginalFile, retryAfterSeconds, expiresAt and completeBefore. For unstarted, resume using the unchanged file:
The CLI checks the file against its saved original intent. media resume requires that local record, so retain the state directory and use the same account/wallet selector as the original command. If the local intent is unavailable, inspect by the original key and recover the server receipt before deciding whether to repeat the original upload command. To check completion without sending bytes:
With CLI 0.7.1, inspect again after WURKER_MEDIA_UPLOAD_PENDING. The server may have made the same reservation available for a new transfer after checking that the earlier attempt produced no file. If the next status is unstarted, run the original resume command with the original file. This obtains fresh upload authorization. A completion wait alone never retransmits the file; repeatedly calling complete on an unstarted reservation cannot upload it. The first preparation gives a 30-minute transfer window and a 24-hour completion deadline. Replaying the key does not extend either deadline. An expired transfer window does not prove that no file arrived: use media complete with the original ID to recover any available receipt. Ready receipts remain recoverable after these deadlines. When the server definitively responds that the upload ended without a file receipt with 410 WURKER_MEDIA_UPLOAD_EXPIRED, you can create a new intentional upload key, subject to the normal quotas. There is no requirement to wait the remaining 24 hours for that closed reservation. CLI 0.7.1 can replace that precise server message with generic recovery text. Its error code or an expired status alone cannot establish that no file receipt exists. If the distinction is unavailable, retain the original references and ask support to confirm the outcome, or inspect the authenticated HTTP completion response. Do not infer permission for a replacement from a timeout or a generic expired message.

Limits and errors

The allowance is shared across profile pictures and portfolio uploads for the account, including files intended for different jobs or orders: An exact reservation replay or retrieval of a ready receipt does not reserve another quota slot. Changing credentials or inventing new keys does not reset the account’s allowance. 429 WURKER_MEDIA_QUOTA_EXCEEDED is the rolling allowance, separate from the fifteen-second cooldown. It may have no Retry-After or reset timestamp. Wait for earlier admitted reservations to leave the rolling 24-hour window; it does not reset at midnight. If prepare returned no upload ID, keep the same intended file and key for a later retry instead of calling complete without an ID. The generic recovery text in CLI 0.7.1 can describe an uncertain upload; use the actual error.code to distinguish quota rejection from transfer failure. For WURKER_MEDIA_IDEMPOTENCY_CONFLICT, use the original file, name, size and key for recovery, or a new key for a genuinely different upload. For temporary 503 errors, honor the returned delay and preserve the original references. Never log an API key or upload token in a support report; the upload ID, key, error code and timestamps are sufficient.

SDK and MCP

SDK 0.7.1 exposes the same operations under client.account: Preserve the original input before calling uploadMedia. For portfolio uploads, its optional saveReservation callback lets your application durably store the reservation before bytes are sent. Completion options accept wait:{maxWaitMs:60000}; waiting never authorizes another transfer. See SDK setup and the HTTP media reference. Local MCP uses approved local file references. Hosted MCP uses its browser upload handoff; do not put a filesystem path or base64 file into an unrelated tool field. Use the tools advertised by your connection and follow MCP uploads.