Skip to main content
Upload the image for an ad creative. The endpoint returns a file_id, which you then pass as creative.file_id when creating an ad. A file_id is a stable storage path — upload once, reference it on as many ads as you like.
Accepted formats are PNG, JPEG, and WebP. The maximum size is 5 MB. The format is detected from the image bytes — the filename and Content-Type you send are never trusted to set it.

Upload Image

POST /v1/upload Send the image one of two ways:
  • multipart/form-data with a file part — upload raw bytes directly.
  • application/json with {"image_url": "https://..."} — have Thrad fetch the image from a URL you control.
Send exactly one. If neither is present, the request fails with a 400.

Authorization

Authorization
string
required
Your advertiser API key as a Bearer token: Bearer ak_.... One active key per organization, created in the Thrad Platform dashboard under Settings → API keys.

Multipart body

file
file
required
The image to upload, as a multipart/form-data part. Must be a PNG, JPEG, or WebP no larger than 5 MB. Required unless you send image_url instead.

JSON body

image_url
string
required
An absolute http(s) URL that Thrad fetches the image from. Required unless you upload a file instead.
The fetch is SSRF-guarded: the URL must be an absolute http(s) address whose host resolves only to public, globally-routable IPs. Hosts that resolve to loopback, private, link-local (cloud metadata), or other reserved ranges are rejected with invalid_image_url. Redirects are not followed. The fetched bytes must pass the same format and size checks as a direct upload.
curl https://api.thrad.ai/v1/upload \
  -H "Authorization: Bearer $THRAD_ADS_API_KEY" \
  -F "file=@./creative.png"
{
  "file_id": "uploads/2026/06/3f8c1a2b9d7e4f0a8c6b5d4e3f2a1b0c.png"
}

Response

file_id
string
The storage path of the uploaded image (e.g. uploads/2026/06/<hex>.png). Pass this value as creative.file_id when creating an ad. Treat it as an opaque token.
Reuse a file_id across multiple ads instead of re-uploading the same image. Each ad that references it creates its own creative asset from the stored bytes.

Errors

The endpoint returns a bare error object on failure. A missing or unreadable image, or an image that fails validation, returns a 400.
StatuscodeMeaning
400invalid_valueNeither a file part nor an image_url was supplied.
400invalid_fileThe bytes are missing, unreadable, or not a decodable image.
400file_too_largeThe image exceeds the 5 MB limit.
400unsupported_mimetypeThe image is not PNG, JPEG, or WebP.
400invalid_image_urlimage_url is empty, not an absolute http(s) URL, or its host is unresolvable or not publicly routable (SSRF guard).
400image_fetch_failedFetching image_url failed — network error, timeout, or a non-success HTTP status.
400too_many_redirectsimage_url returned a redirect (redirects are not followed).
401Missing or invalid API key.
429Rate limit exceeded (1000 requests/hour per key).