Upload once .
Upload bytes once via POST /v1/media. Reference the returned mediaId from every post that uses it. Bytes move once, posts move many times. Required for video on every platform; recommended for any image you'll post more than once.
curl -X POST https://api.letmepost.dev/v1/media \ -H "Authorization: Bearer $LMP_KEY" \ -F "file=@./photo.jpg" \ -F "kind=image" # Returns 201 with { id: "med_01HXZ4N9..." } # Reference that id from posts.create.
Inline base64
- Bytes re-uploaded on every multi-target post
- 33% size overhead from base64 encoding
- Doesn't work for video, payloads exceed platform caps
- Slower publish wall-clock on every call
- No cross-platform variant generation
- No CDN-backed asset URLs you can reference elsewhere
letmepost Media API
- Upload once, reference forever (up to retention)
- S3-backed multipart upload, no base64 overhead
- Video uploads up to 500 MB, transcoded per platform
- Publish wall-clock unchanged regardless of media size
- Per-platform variants generated automatically
- CDN URL returned for use in your own UI
✓ Upload bytes once, post many times
Bytes hit our S3 bucket once. Subsequent POST /v1/posts calls reference the mediaId. Multi-target posts share the same upload — Bluesky + X + Pinterest publishing the same photo move three platforms' worth of metadata but only one set of bytes.
SUPPORTED TYPES
UPLOAD PIPELINE
Client uploads
POST /v1/media with multipart form-data. Single request for files ≤ 100 MB. Larger files use resumable upload with chunked PUTs.
S3 + virus scan
Bytes hit our S3 bucket, ClamAV scans on ingress, content-type sniffed from magic bytes (not the upload's Content-Type header).
Variants generated
Per-platform variants encoded ahead of time. Bluesky 976 KB-capped JPEGs, Pinterest cover frames, IG Reels H.264. Variants come from the source on demand.
Reference on publish
Pass mediaId to POST /v1/posts. We pick the right variant per target. Bytes move once, posts fan out.
FEATURES
One upload, many posts
Upload bytes once via POST /v1/media. Reference the returned id from media: [{ mediaId }] on every post that uses it.
Per-platform variants
We pre-encode platform-specific variants (Bluesky JPEG-cap, IG Reels H.264, Pinterest video covers) so the publish path stays fast.
Virus scan on ingress
ClamAV scans every upload before it lands in our active bucket. Failed scans return media_rejected_security with the threat name.
Video transcode pipeline
MP4 → per-platform H.264 variants. Pinterest cover frames extracted automatically. Threads container creation handled at publish time.
30-day retention free
Default 30 days. media.expiring webhook fires 7 days before GC. Pro extends to 90, Business to 365.
CDN-backed asset URLs
Every uploaded asset has a CDN URL — useful for preview UIs in your own dashboard, drag-and-drop reordering, etc.
CODE EXAMPLE
import { Letmepost } from '@letmepost/sdk'; import { readFileSync } from 'node:fs'; const lmp = new Letmepost({ apiKey: process.env.LMP_API_KEY }); // Step 1: upload the bytes (multipart). Bytes only move once. const media = await lmp.media.upload({ file: readFileSync('./photo.jpg'), kind: 'image', altText: 'Receipt-themed landing page', }); console.log('Got mediaId:', media.id); // 'med_01HXZ4N9...' // Step 2: reference it from any post that uses it const result = await lmp.posts.create({ targets: [ { platform: 'bluesky', accountId: 'acc_bsky_xyz' }, { platform: 'x', accountId: 'acc_x_xyz' }, { platform: 'pinterest', accountId: 'acc_pin_xyz' }, ], text: 'Same photo, three platforms, one upload.', media: [{ mediaId: media.id }], }); // Same uploaded bytes are referenced by all three posts. // Per-platform variants picked automatically.
COMMON QUESTIONS
Can I skip the Media API and inline-base64 small images?
Yes. For images under ~1 MB, inline media: [{ data: "base64...", kind: "image" }] works fine. For video and larger images, use the Media API — inline base64 will hit platform-specific payload caps.
How long are uploads kept?
Default 30 days, free. media.expiring webhook fires 7 days before garbage collection. Pro extends to 90 days, Business to 365.
Does the Media API count toward my post quota?
No. Uploads are free and unlimited. Only successful publishes meter against your quota.
Can I reference the same mediaId on multiple posts?
Yes. Reference forever (up to retention). Multi-target posts share the same upload automatically, bytes only move once.
What size limits apply?
Per upload: 8 MB image, 500 MB video. Platform constraints (e.g. Bluesky's 976 KB per image cap) are enforced at publish time, not upload time, so you can upload high-res once and we re-encode per platform.
How does video transcoding work?
Video uploads are stored as-is plus per-platform variants (H.264 MP4 at platform-specific bitrate caps). Pinterest video pins also get an auto-generated cover frame.
Can I delete an upload?
Yes. DELETE /v1/media/:id. Posts that already published to upstream platforms keep working (those bytes left our system); future references return 404.
OTHER SURFACES
LEARN MORE
READY TO UPLOAD?
Bytes once. Posts many. Free uploads, unlimited references, 30-day retention on the free tier.