Upload images via presigned URLs.

Upload

Uploading is a two-step process: get a presigned URL, upload the file directly to storage, then confirm.

Step 1: Initiate upload

POST /images/projects/{projectId}/upload
FieldTypeRequiredDescription
filenamestringYesOriginal filename (1–255 chars)
contentTypestringYesMIME type (must start with image/)
fileSizeintegerYesFile size in bytes (max 50MB)
curl -X POST \
  -H "Authorization: Bearer spronta_img_..." \
  -H "Content-Type: application/json" \
  -d '{"filename": "hero.jpg", "contentType": "image/jpeg", "fileSize": 2048576}' \
  https://app.spronta.com/api/images/projects/123e4567-.../upload

Response 201

{
  "imageId": "987fcdeb-51a2-3b4c-d567-890123456789",
  "uploadUrl": "https://storage.example.com/presigned-url...",
  "r2Key": "123e4567/987fcdeb/hero.jpg"
}

Upload your file to uploadUrl using a PUT request:

curl -X PUT \
  -H "Content-Type: image/jpeg" \
  --data-binary @hero.jpg \
  "https://storage.example.com/presigned-url..."

Error 403 — Image limit reached for your plan:

{
  "error": "Image limit reached",
  "limit": 100,
  "current": 100,
  "upgrade": true
}

Step 2: Confirm upload

POST /images/projects/{projectId}/upload/confirm
FieldTypeRequiredDescription
imageIdstring (uuid)YesThe imageId from step 1
widthintegerNoOverride auto-detected width
heightintegerNoOverride auto-detected height
curl -X POST \
  -H "Authorization: Bearer spronta_img_..." \
  -H "Content-Type: application/json" \
  -d '{"imageId": "987fcdeb-51a2-3b4c-d567-890123456789"}' \
  https://app.spronta.com/api/images/projects/123e4567-.../upload/confirm

Response 200

Spronta computes the blurhash, detects dimensions, and returns the confirmed image with its CDN URL:

{
  "id": "987fcdeb-51a2-3b4c-d567-890123456789",
  "filename": "hero.jpg",
  "contentType": "image/jpeg",
  "fileSize": 2048576,
  "width": 1920,
  "height": 1080,
  "blurhash": "LEHV6nWB2yk8pyo0adR*.7kCMdnj",
  "uploadStatus": "confirmed",
  "url": "https://cdn.spronta.com/my-project/987fcdeb-..."
}