image_id. Use the image_id as
the source image of a Magic Edit,
img2img,
variations,
resize,
upscale,
background removal,
vectorization, or an
image-to-video generation. The MCP server has the
same flow as two tools, prepare_image_upload and complete_image_upload — see
MCP tools.
Uploads are free — they cost no credits.
The three steps
1
Prepare
Call
POST /images/uploads/prepare with the
filename, the content_type, and the exact file size in size_bytes. The
response gives you the image_id and a presigned upload_url.2
PUT the file
PUT the raw file bytes to upload_url with the same Content-Type. Do not
send an Authorization header to this URL.3
Complete
Call
POST /images/uploads/{image_id}/complete
within the hour. Samsa verifies the file and returns the image with its measured
width and height. The image_id is usable from now on.curl --data-binary @file sends the real file length, so it always matches
size_bytes when you measured the same file.
Limits
The file must be the format you declared in
content_type. width and height are
optional hints at prepare: Samsa uses them only to refuse an image over 32 MP early.
The stored dimensions are always measured from the uploaded bytes. An upload that is
never completed is discarded after its URL expires.
Lifecycle and errors
- Not usable before complete. Until complete succeeds, the
image_idreturns404 not_foundeverywhere. - Complete is idempotent. Calling it again returns the same result and changes
nothing. A later
PUTto the sameupload_urldoes not replace a completed image. 422 validation_error— there is no file yet, or the file is empty, has a different size thansize_bytes, is too large, cannot be read, is a different format, or is over 32 MP. Samsa discards a refused file:PUTa valid file to the sameupload_urlwhile it is still valid, then call complete again.404 not_found— theimage_idis unknown, expired, belongs to another user, or was not created by prepare.409 upload_in_progress— another complete call for the same upload is running. Retry in a few seconds; if it continues for minutes, prepare a new upload.429 too_many_pending_uploads— you have 20 uploads awaiting completion. Complete them, or wait until unfinished ones expire (seeRetry-After).
Scope and ownership
Both endpoints accept a key with any one of theimages.edit,
images.transform, or videos.generate scopes — the scopes of the operations that
take a source image_id. There is no separate upload scope, so existing keys work.
A key with none of the three gets
403 missing_scope.
The uploaded image belongs to the calling user — the API key’s creator, or the
user of an OAuth token. Other members of your organization cannot use its
image_id.