# Frames Puts screenshots in realistic Apple device bezels and returns transparent PNGs. No API key or account is needed. Uploads are deleted as soon as the request ends. ## Frame a screenshot Send one PNG or JPEG. The device is detected from the image size: curl -sS -o shot_framed.png -w '%{http_code}\n' \ -H 'Accept: image/png' \ -F images=@shot.png \ https://frames.pushtomain.de/api/frame The command prints the HTTP status. On 200, the output file is the framed PNG. On any other status, the output file holds JSON like {"error": "..."} instead of an image, so read the error and delete the file. For several screenshots, run the command once per file, one at a time. Keep the originals and name each result _framed.png. ## Choose a device or color Add an options field holding JSON. Every key is optional: -F 'options={"device":"iPhone 17 Pro Portrait","color":"Silver"}' - device: a name from /api/schema, or "auto" (default) - color: one of that device's colors, "default" (default), or "random" - merge: true combines 2 or more screenshots side by side into one image - spacing: pixels between merged screenshots, 0 to 400 (default 60) GET https://frames.pushtomain.de/api/schema returns JSON with the current device names, the colors of each device and the limits. Its "devices" list is the source of truth, so look names up there. If the user names a device or color loosely, match it to the closest entry. If a screenshot fails with an error saying its size doesn't match any device, tell the user. It isn't a screenshot from a supported device, or it was cropped or resized. ## Merge screenshots Repeat the images field. Up to 10 images go in one request, and the result is one PNG: curl -sS -D headers.txt -o merged_framed.png -w '%{http_code}\n' \ -H 'Accept: image/png' \ -F images=@one.png -F images=@two.png \ -F 'options={"merge":true}' \ https://frames.pushtomain.de/api/frame If some images couldn't be included, the response has an X-Frames-Warning header. Tell the user. ## Errors - 400: bad options, or several images sent without merge. Fix the request. - 413, 415: an image is too large, or isn't a PNG or JPEG. Each file can be up to 25 MB and 25 megapixels. - 422: the image couldn't be framed. The error says why. - 429 without a Retry-After header: the server is busy. Wait a few seconds and retry, up to about 5 times. - 429 with a Retry-After header: you hit the rate limit. Retrying sooner won't work, so wait that many seconds or tell the user. - 503: try again later, or send smaller images. ## Without Accept: image/png The default response is multipart/form-data, meant for the web page. It has a "meta" JSON part plus one part per framed image, and lets one request carry up to 10 images. Use it only if you can parse multipart responses.