Binary inputs
Private direct uploads
Image, audio, and video inputs never travel through an arbitrary remote URL. Your server declares the file, uploads it directly to a short-lived private location, completes verification, and then sends the verified upload_id to an eligible engine.
Upload identifiers are owned by the API key that created them. Another key receives a not-found or validation response even if it knows the identifier.
Step 1: calculate exact metadata
Calculate the byte length and lowercase SHA-256 hash from the exact bytes that will be uploaded. Do not hash a resized preview and upload a different file.
# Linux/macOS
BYTES=$(wc -c < input.png | tr -d ' ')
SHA256=$(sha256sum input.png | cut -d ' ' -f1)
# PowerShell
$bytes = (Get-Item -LiteralPath input.png).Length
$sha256 = (Get-FileHash -Algorithm SHA256 -LiteralPath input.png).Hash.ToLower()Step 2: create an upload
curl "$URTHEPRODUCT_BASE_URL/v1/uploads" -X POST -H "Authorization: Bearer $URTHEPRODUCT_API_KEY" -H "Idempotency-Key: upload-create-001" -H "Content-Type: application/json" -d '{"purpose":"image_input","filename":"input.png","mime_type":"image/png","size_bytes":123456,"sha256":"64-lowercase-hex-characters"}'| Field | Required | Contract |
|---|---|---|
purpose | Yes | image_input, video_input, or audio_input; must match the purchased operation. |
filename | Yes | 1–180 characters; metadata only, never used as a storage path. |
mime_type | Yes | JPEG, PNG, WebP, MP3, WAV, M4A, MP4, or WebM from the documented allowlist. |
size_bytes | Yes | Positive integer, maximum 100 MB globally and possibly lower for the purchased package. |
sha256 | Yes | Exactly 64 lowercase hexadecimal characters. |
Step 3: PUT bytes to the returned URL
# Read upload_url and required_headers from the create response.
curl "$UPLOAD_URL" -X PUT -H "Content-Type: image/png" -H "x-upsert: false" --data-binary @input.pngUse the exact upload_url, HTTP method, and headers returned by the API. Do not log the signed URL or reuse it after its 30-minute expiry. A signed upload is private and cannot overwrite an existing object.
Step 4: complete verification
curl "$URTHEPRODUCT_BASE_URL/v1/uploads/$UPLOAD_ID/complete" -X POST -H "Authorization: Bearer $URTHEPRODUCT_API_KEY" -H "Idempotency-Key: upload-complete-001" -H "Content-Type: application/json" -d '{"sha256":"the-same-64-character-sha256"}'Completion checks ownership, expiry, declared size, calculated checksum, MIME, and file magic bytes. A mismatch rejects and removes the object. Only status: verified may be used for generation.
Step 5: use the verified identifier
{
"prompt": "Place the supplied authorized product on a neutral studio background.",
"input_upload_id": "upl_example_identifier",
"output_format": "png"
}Common upload failures
| Failure | Meaning | Fix |
|---|---|---|
| 403 forbidden | The key operation cannot accept that purpose. | Use the correct purchased engine; do not relabel file content. |
| 409 conflict | The idempotency key declared different metadata or the upload cannot resume. | Reuse the original exact declaration or create a new logical upload. |
| 422 checksum mismatch | Declared, uploaded, and completed bytes differ. | Recalculate metadata from the exact file and create a new upload. |
| 422 file-signature mismatch | Extension/MIME does not match magic bytes. | Export a supported real file; renaming an extension is insufficient. |
| 404 expired | Upload ownership or 30-minute window failed. | Create and upload a new asset with a new logical idempotency key. |