Image posts & carousels
Ballad writes the words and caption for image posts and carousels, compositing them from a text-free background in your colours, font and logo.
Some things land better as a picture. A hard number, a before-and-after, five steps worth swiping through: a wall of text buries all of them.
Ballad picks the visual idea, writes the words on the slide and the caption underneath, then makes the image in your colours and checks every word on it. You download the slides and post them.
What a visual post is
Two parts:
- The caption: the text you paste into the composer, written in your voice like any other post.
- The slides: one image for a card, two to ten for a carousel. Each slide carries a headline, an optional second line, and alt text.
Everything renders at 1080×1080. Square is the one ratio LinkedIn, X, Bluesky, Threads and Instagram all accept without cropping.
Concepts
Every image post starts from an idea, not a background. A headline over a quiet wash is legible and on-brand, and after a week it's also the same post every day. So each post is built on one of eight concepts:
| Concept | What it looks like | Made |
|---|---|---|
| Visual metaphor | one object or scene that is the idea | drawn whole |
| Annotated diagram | a few boxes and arrows, hand-lettered | drawn whole |
| Before and after | a split frame, the old way beside the new | drawn whole |
| Whiteboard sketch | a marker doodle, the headline in the same hand | drawn whole |
| Single panel | one dry comic panel with a line of dialogue | drawn whole |
| Typographic poster | the phrase itself as the artwork | drawn whole |
| Object still life | one everyday object, lit like a product shot | layered |
| One number | a single real figure, huge, only when the post has one | layered |
Concepts rotate. A new post never reuses any of the voice's last four concepts, and they're weighted by what you've done with them before: each approval nudges a concept up, each decline nudges it down. A concept you keep declining isn't banned, but it only comes up when nothing else is left. "One number" is never picked for a post without a real figure to show, so Ballad never invents a statistic to fill it.
Drawn whole, or layered
The concept decides how the image is made. There's no setting to pick one; each post gets whichever its concept calls for.
- Layered. The image is generated text-free, and the renderer typesets your words on top in your brand font. The text on the slide is exactly the text you approved, because it was never part of the generated image.
- Drawn whole. The image model draws the entire card, words included, so the lettering can be part of the idea: chalk on the whiteboard, a stencil on the poster. Ballad draws only the footer (name, handle or logo) over it.
Image models are still unreliable at typography. They invent letters and swap one for another. So every drawn card is read back before it reaches you: a second model is told exactly which words should be on it, transcribes what's actually lettered, and judges it letter for letter and for legibility at feed size. A stencilled "SHIP" that came out "SKIP" fails.
If the read-back fails, the post falls back to layered: same concept, a text-free image, your words typeset on top. Review shows that it fell back and why, so a misspelt headline never reaches the Inbox. You can try again or move to another concept.
Carousels are always layered. Drawn-whole is for single cards. A carousel only uses the concepts that hold up slide after slide (still life, whiteboard, poster). Every slide in it shares one background image, which keeps it looking like a set rather than a pile and means a ten-slide carousel costs the same to generate as a single card.
Turning it on
For LinkedIn, X, Bluesky and Threads, enable the Image posts & carousels format on a voice under Settings → Voices → that voice → Formats. Visual posts then ride the normal channel lane, the way a thread does on X; they don't get a separate cadence to manage.
Settings → Voices is people. The company's own voice has its own page, so wherever this guide says Settings → Voices → that voice, read Settings → Brand for the brand voice: same sections underneath.
For Instagram, just switch the channel on. There's no format toggle, because Instagram is nothing but visual posts.
Each channel caps how many images a post can carry (X and Bluesky take four; LinkedIn, Threads and Instagram take ten), and Ballad enforces the cap rather than leaving it to you. The generator is given the channel's limit, so it never drafts a carousel that won't fit, and a longer one written by hand or submitted by an agent is rejected at validation with a "too many slides" notice before it can reach approval.
Your brand look
One look for the whole workspace, set once at the top of Settings → Brand. Every voice renders in it (image posts, carousels, and card-style opening images), and the footer still names whoever is speaking, so a teammate's post looks like the company without pretending to be someone else.
| Setting | What it does |
|---|---|
| Three colours | background, headline, and an accent used for the rule, slide counter and handle |
| Font | Space Grotesk, Inter, or Instrument Serif |
| Logo | PNG, JPEG, SVG or WebP up to 1 MB; replaces the initials in the footer |
| Show handle | whether your @handle appears on the last slide |
A live sample updates as you change them, so you're not approving a look you haven't seen.
The theme is snapshotted onto each post when it renders. Changing your colours restyles new posts; it doesn't silently restyle everything you've already approved.
Reviewing
A visual post arrives rendered, not as a script to imagine. Review is the same gate as any other post:
The review shows which concept the post is built on, whether it was drawn whole or layered, and whether it fell back.
- Edit the words on a slide and that slide re-renders. Only the slide you changed; the others are untouched.
- Regenerate the image if the art direction missed. Edit the direction or leave it, and get a new image with the same words.
- Try another concept if the idea itself is wrong. Ballad moves to a different concept, art-directs from scratch and renders again, drawn whole or layered as the new concept calls for.
- Approve once every slide is right. What you approve and decline is what teaches the rotation which concepts suit this voice.
Publishing
On X, Ballad posts it. Connect the voice's X account under Settings → Voices → that voice → Accounts & look and an approved image post goes out from that account on its slot, or straight away if you asked for it now, up to the four images X carries, which is the cap Ballad already keeps it inside.
Everywhere else it's assisted. Ballad renders, you post:
- Open the publish step.
- Download each slide.
- Copy the caption.
- Post in the composer, attaching the slides in order.
Instagram is from your phone. Ballad does not use the Instagram Graph API: that needs a Business account linked to a Facebook Page and a review process, which is a lot of setup to post an image. Download the slides, then post from the Instagram app.
Order matters on a carousel: the first slide is the hook that stops the scroll, the last one carries the call to action.
What it costs
Cheap enough not to think about:
| Per post | |
|---|---|
| Art direction | ~$0.001 |
| Layered image | ~$0.01–0.04, once per post regardless of slide count |
| Drawn-whole card | a few cents more: a higher-quality image plus the read-back, about 20s |
| Slide rendering | no model, about 0.3s a slide |
Still pocket change at a visual post per batch per channel.
With image generation off, nothing breaks. Drawn-whole concepts fall back to layered, the background falls back to a two-stop gradient in your brand colours, and the post carries on. Same words, same layout, no model cost.
From an agent
// Cards — one image
generate({ kind: "linkedin_image" })
generate({ kind: "x_image" })
generate({ kind: "bluesky_image" })
generate({ kind: "threads_image" })
generate({ kind: "instagram_image" })
// Carousels. X and Bluesky have no carousel kind — but create_draft below
// takes a two-to-four-slide carousel on either.
generate({ kind: "linkedin_carousel" })
generate({ kind: "threads_carousel" })
generate({ kind: "instagram_carousel" })
create_draft({
format: "visual",
layout, // "card" | "carousel"
slides, // headline, sub, alt
caption,
backgroundPrompt, // optional — art-direct it yourself
backgroundImage, // optional — bring your own
})
edit_draft({ slides, backgroundPrompt }) // re-renders what changed
set_brand({ ... }) // workspace-wide: colours, font,
// logo URL, handle
edit_draft re-renders only the slides whose words actually changed, so
correcting one headline in a ten-slide carousel doesn't redo the other nine. See
Connect Claude to Ballad for scopes: drafting needs
draft, set_brand needs decide.
Checklist
- "Image posts & carousels" enabled on the voice, for LinkedIn, X, Bluesky and Threads
- Instagram channel on, if you post there
- Brand look set: colours, font, logo, handle
- First post reviewed: concept right, words right, image right, every slide rendered
- X account connected on the voice, if you post there (Ballad publishes it)
- Everywhere else: slides downloaded and posted in order, caption pasted