Bluesky uploads raw image bytes (blob) and embeds them; LinkedIn/Instagram/Threads are URL-only today. Instagram cannot post without an image, so this is a hard gap for that network.
Scope
- LinkedIn: register upload → upload asset → attach to the share (LinkedIn Assets API)
- Instagram: the Graph API needs a public image URL — either host uploaded bytes at a public URL, or require URL and document it
- Threads: media container flow with uploaded media
- Composer already sends
imagebytes (multipart); wire each service'spublishToPostto consume them - Shared
PublishContent.mediaalready carriesbytes/url— thread it through per driver
Notes
- Instagram is the blocker case — text-only IG posts already fail by design.
- Services:
app/Services/Social/{LinkedIn,Instagram,Threads}Service.ts.