Bluesky image limits: 4 per post, 2 MB each, alt text required
A Bluesky post embeds up to 4 images of 2,000,000 bytes each, and each needs alt text. Make a JPEG under the cap with Sume Images and write the description.

The AT Protocol lexicon for app.bsky.embed.images allows up to 4 images per embed, each blob up to 2,000,000 bytes, and every image requires an alt string. The lexicon notes the cap was formerly 1 MB. For an AI image, export JPEG, check the byte size, and write real alt text.
What does the lexicon require?
The main object holds an images array with maxLength: 4. Each image object requires image and alt; aspectRatio is optional. The blob accepts image/* types with maxSize: 2000000.
| Item | Value |
|---|---|
| Images per embed | 4 |
| Max bytes per image | 2000000 |
| Required fields | image, alt |
| Optional | aspectRatio |
| Accepted type | image/* |
How do I stay under 2 MB?
Ask Sume for output_format jpeg and a moderate aspect ratio such as 4:5 or 1:1, then measure the file. If it is over 2,000,000 bytes, regenerate at a lower resolution tier. Sume does not offer a byte-size parameter, so the check belongs in your code.
import json, os, urllib.request
body = {
"model": "bytedance-seed/seedream-4.5",
"prompt": "a lighthouse at dusk, painterly, calm sea",
"aspect_ratio": "4:5",
"output_format": "jpeg"
}
req = urllib.request.Request(
"https://api.sume.com/v1/images",
data=json.dumps(body).encode(),
headers={
"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json",
},
method="POST",
)
print(urllib.request.urlopen(req).read().decode())Why does alt text matter here?
The schema makes it required, so a post without it fails. Describe the picture plainly; the lexicon sets no length cap in the part read, but keep it concise. Providing aspectRatio helps clients reserve space.
What should I verify?
Check the live lexicon, since limits have changed before. The images guide lists Sume's parameters.
Sources
Related posts
More in Integrations
- Bun.serve webhook receiver for Sume: raw body, verify, dedupe
A 24-line Bun.serve receiver for Sume job webhooks: read the raw body first, verify sume-v1, dedupe on job_id, answer 204 before the work. Tested on Bun 1.4.
- Claude Code 2.1.286 prompt count '2 of 5': parallel Sume calls
Claude Code 2.1.286 shows a count like 2 of 5 on stacked permission prompts, oldest first. Five parallel Sume calls make five prompts; script_run is one.
- Claude Code 2.1.287 large MCP results: Sume's include_results answer
Claude Code 2.1.287 fixed paging of large MCP results saved as JSON. For Sume job waves, use jobs_wait include_results and read omitted ids once.
- Claude Code MCP whitespace warning: a pasted Sume key with a newline
Claude Code warns when an MCP header or url has leading or trailing whitespace, often a pasted token with a newline. It does not trim it. Fix a Sume entry.
Written by Sume