Muse Image

Muse Image is Meta's flagship image generation model from Meta Superintelligence Labs. It is built for prompt-faithful image creation, precision editing, and multi-reference composition, with strong text rendering and the ability to refine existing photos through localized markup-based edits. Meta positions it as an agentic image model that plans layouts, uses search and coding tools to improve accuracy, blends multiple visual references intelligently, and handles both creative generation and practical visual tasks such as infographics, QR codes, restorations, product-style mockups, and photobomber removal.

Complete technical specification for integration
Step-by-step tutorials for advanced use cases
← All GuidesRendering exact text with Muse Image
How to render exact, legible copy inside an image with Muse Image: quoting the literal string, keeping it short, directing the type, and landing multi-element layouts.
Introduction
Baked-in copy is where generated design work usually falls apart. Most image models treat lettering as texture rather than as a string with a spelling, so an otherwise clean layout comes back with a headline that reads NEWW ARRIVALS and the file is unusable.
Muse Image takes the other route. It plans the layout before it renders anything, then refines the frame inside its own reasoning pass, which is what makes it usable for work where a misspelling is a failed deliverable. The carton below carries three separate strings at three sizes, and each one is set where the prompt put it.

A studio packshot of a tall matte white carton of electrolyte drink sticks standing on a pale grey seamless backdrop, straight-on camera, soft even studio light with a gentle shadow falling to the right. The front panel carries the wordmark "RIVERSALT" in heavy black uppercase across the upper third, "Electrolyte Drink Mix" set directly beneath it in a light grey sentence case weight, and "30 STICK PACKS" in small black capitals along the bottom edge of the panel. A flat orange citrus wedge graphic sits centred between them. Sharp commercial product photography, crisp print detail on the carton.
This guide covers the prompt side of getting copy right: quoting the string, keeping it short, writing numbers and prices so they stay attached to the right item, directing the type, and landing layouts where several elements all have to be correct.
Quoting the copy
Wrap every string you want rendered in quotation marks. The quotes separate copy you are setting from copy you are describing. Inside them the model treats the characters as content to render. Outside them it reads a description of what a sign says and writes its own wording to fit.

A modern gym storefront photographed straight on from the pavement, with a large white vinyl decal applied across the window glass. The decal reads "NEW MEMBER OFFER" in heavy condensed uppercase across the top and "$0 JOINING FEE UNTIL MARCH" in a lighter weight on the line below. Racks of dumbbells and a row of treadmills are visible through the glass behind the lettering, bright overcast daylight, clean architectural photography.

A modern gym storefront photographed straight on from the pavement, with a large white vinyl decal applied across the window glass advertising a new member offer with no joining fee until March. Racks of dumbbells and a row of treadmills are visible through the glass behind the lettering, bright overcast daylight, clean architectural photography.
The quoted decal sets both lines as written, down to the dollar sign and the month. The second prompt describes the same offer in the same scene and leaves the wording to the model, which lands somewhere near the brief rather than on it.
Give each string a role as well as a value. "reads NEW MEMBER OFFER" is weaker than "the headline across the top reads NEW MEMBER OFFER". The role tells the model what the string is for, and the layout follows from it.
import { createClient } from '@runware/sdk'
const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()
const [result] = await client.run({
model: 'meta:muse@image',
positivePrompt: 'A modern gym storefront photographed straight on from the pavement, with a large white vinyl decal applied across the window glass. The decal reads "NEW MEMBER OFFER" in heavy condensed uppercase across the top and "$0 JOINING FEE UNTIL MARCH" in a lighter weight on the line below. Racks of dumbbells and a row of treadmills are visible through the glass behind the lettering, bright overcast daylight, clean architectural photography.',
width: 1920,
height: 1280
})import asyncio
import os
from runware import Runware
async def main():
async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
results = await client.run({
"model": "meta:muse@image",
"positivePrompt": "A modern gym storefront photographed straight on from the pavement, with a large white vinyl decal applied across the window glass. The decal reads \"NEW MEMBER OFFER\" in heavy condensed uppercase across the top and \"$0 JOINING FEE UNTIL MARCH\" in a lighter weight on the line below. Racks of dumbbells and a row of treadmills are visible through the glass behind the lettering, bright overcast daylight, clean architectural photography.",
"width": 1920,
"height": 1280
})
asyncio.run(main())curl https://api.runware.ai/v1 \
-H "Authorization: Bearer $RUNWARE_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"taskType": "imageInference",
"taskUUID": "4c7f1a92-8d3e-4b16-9a2f-0e5b7c8d91a3",
"model": "meta:muse@image",
"positivePrompt": "A modern gym storefront photographed straight on from the pavement, with a large white vinyl decal applied across the window glass. The decal reads \"NEW MEMBER OFFER\" in heavy condensed uppercase across the top and \"$0 JOINING FEE UNTIL MARCH\" in a lighter weight on the line below. Racks of dumbbells and a row of treadmills are visible through the glass behind the lettering, bright overcast daylight, clean architectural photography.",
"width": 1920,
"height": 1280
}
]'runware run meta:muse@image \
positivePrompt="A modern gym storefront photographed straight on from the pavement, with a large white vinyl decal applied across the window glass. The decal reads \"NEW MEMBER OFFER\" in heavy condensed uppercase across the top and \"\$0 JOINING FEE UNTIL MARCH\" in a lighter weight on the line below. Racks of dumbbells and a row of treadmills are visible through the glass behind the lettering, bright overcast daylight, clean architectural photography." \
width=1920 \
height=1280{
"taskType": "imageInference",
"taskUUID": "4c7f1a92-8d3e-4b16-9a2f-0e5b7c8d91a3",
"model": "meta:muse@image",
"positivePrompt": "A modern gym storefront photographed straight on from the pavement, with a large white vinyl decal applied across the window glass. The decal reads \"NEW MEMBER OFFER\" in heavy condensed uppercase across the top and \"$0 JOINING FEE UNTIL MARCH\" in a lighter weight on the line below. Racks of dumbbells and a row of treadmills are visible through the glass behind the lettering, bright overcast daylight, clean architectural photography.",
"width": 1920,
"height": 1280
}[
{
"taskType": "imageInference",
"taskUUID": "4c7f1a92-8d3e-4b16-9a2f-0e5b7c8d91a3",
"imageUUID": "b8d0e6f1-3a4c-4d5e-8f90-1a2b3c4d5e6f",
"imageURL": "https://im.runware.ai/image/os/a14d18/ws/2/ii/b8d0e6f1-3a4c-4d5e-8f90-1a2b3c4d5e6f.jpg"
}
]Text-to-image calls size the frame with width and height, taken from a fixed list of eight pixel pairs. resolution: "2K" is the other way to size a request, and it applies only when you attach inputs.referenceImages, where it takes the aspect ratio from the input. The two cannot be sent in the same request.
Keeping each string short
Accuracy drops as a string gets longer. A headline, a product name, a price and a one-line qualifier are the units that render cleanly. A paragraph of body copy set inside the image is where it starts to break down.
Write the copy the way the finished piece would carry it, as set pieces rather than as a sentence:
Brief in one string
"Our new lightweight commuter tyres are now available in three widths, and fitting is free when you buy in store"
Same brief as set pieces
"COMMUTER TYRE FITTING"
"Three widths in stock"
"Fitting included in store"The split does two jobs. Each string stays short enough to render reliably, and the hierarchy becomes explicit instead of something the model has to infer from a run-on sentence.
When a frame is finished except for one wrong word, regenerating the whole prompt trades a small error for a new layout. Send the image back with a scoped instruction instead, covered in editing images.
Numbers and prices
Write every number into the string yourself. "30% OFF" is copy. "a discount" is a decision handed to the model, and it will make one. The same holds for counts, sizes, dates and percentages, all of which come back as a plausible invented value when the prompt only implies them.
When a layout carries more than one price, keep each price inside the same quoted string as its item. A price written in its own clause is free to attach to the wrong row when the model lays the card out.

A printed shelf talker card clipped to a black shelf rail in a bike shop, photographed straight on and filling most of the frame. The card is white with a black header band reading "COMMUTER TYRE FITTING" in white uppercase. Two black rows are printed below the band, "Urban 35C tyre, $42 fitted" on the first row and "Gravel 40C tyre, $54 fitted" on the second. A grey line at the foot of the card reads "Fitting included in store". Bright even shop lighting, the tyre display behind the rail softly out of focus.
Both rows on the card are written as a single string that carries the tyre and its price together, so the $42 travels with the 35C line rather than floating between the two rows. The same pattern holds for a size next to a variant name or a serving count next to a flavour.
Type direction
Left undirected, the model picks a typeface and a position that suit the scene, and that choice moves between runs. Naming the treatment is how you get a specific look rather than a plausible one. Four directives carry most of the work:
- Weight and case: heavy condensed uppercase, light title case, small widely letter-spaced capitals
- Colour: white on the deep green field, charcoal on sand
- Placement: across the lower left, centred in the upper half, along the bottom edge of the panel
- Hierarchy: which string is the headline, which sits directly beneath it, which is the small print

An app store feature graphic on a deep forest green field. "NEVER MISS A WATERING" is set in heavy condensed white uppercase, left aligned across the lower left of the frame, with the app name "SPROUT" in small white capitals directly above it. A single potted monstera photographed against the green fills the right third of the frame. Flat modern layout, generous margins.

An app store feature graphic on a pale sand field. "Never Miss A Watering" is set in a light title case sans-serif, centred in the upper half of the frame in charcoal, with the app name "SPROUT" in small widely letter-spaced charcoal capitals centred beneath it. A single potted monstera sits centred at the bottom edge, cropped by the frame. Flat modern layout, generous white space.

An app store feature graphic on a warm cream field. "Never miss a watering" is set in a tall dark green serif across the top of the frame, left aligned, with the app name "SPROUT" in small green capitals above it. A phone mockup showing a plant care app screen tilts into the frame from the bottom right, partly cropped. Editorial layout, soft drop shadow under the phone.
All three feature graphics carry the same two strings. Weight, case, colour and placement are the only things the prompt changed, and each one reads as a different brand.
Hierarchy is set in words, not in point sizes. There is no type scale to pass, so phrases like "directly beneath it in a lighter weight" and "small capitals along the bottom edge" are the levers you have. Say which string is largest and what sits under it, and the relationship survives the layout the model plans.
A real brand's wordmark is a different problem from a string you invented. Two ways to pin one: let the model look it up with settings.imageSearch, covered in grounded generation, or attach the asset itself through inputs.referenceImages, covered in multi-reference composition.
Multi-element layouts
A real brief is rarely one string. Give each element its own clause, naming what it is, what it says and where it sits. A story ad carries a headline, a product name, a price, a shipping line and a button label, and the frame only ships if all five are right.

A vertical social story ad for an outdoor gear brand, photographed as a charcoal 32 litre hiking backpack standing on a pale concrete floor against a warm terracotta wall, with graphic type laid over the upper and lower thirds. Across the top "WEEKEND DROP" is set in heavy white uppercase, with "Trail Pack 32L" in a lighter white weight on the line beneath it. Near the bottom "$148" is set large in white, with "Free shipping over $75" in small white capitals directly under the price. A white outlined pill at the very bottom holds the words "Shop the drop". Clean commercial layout, generous margins, soft daylight.
Order the clauses the way the design stacks, from the top of the frame down. A prompt that already reads in the order of the finished piece leaves the planning pass less to resolve. settings.thinkingLevel defaults to high, which is the depth that planning runs at, and prompting covers when dropping it to low is worth it.
Expect the layout to reflow. Elements move between runs even when the copy holds, so treat placement as a strong preference rather than a coordinate. If something has to sit at an exact position, generate it into a clear area of the frame and place the rest downstream.
Structured layouts like data tables and functional QR codes are built by a different mechanism. The model can write and run code to lay those out before it renders, covered in infographics and charts.
Run-to-run variation
The same request run twice comes back with a different image. There is no seed parameter on this model, so a frame you like cannot be pinned and reproduced. Prompting covers what that means in general. For text it means the exact lettering and the layout both move from run to run, and a string that came out perfect once can come back with a dropped character.

A flat lay of a single protein bar wrapper on a pale grey surface, photographed straight down and filling the frame. The wrapper is deep navy with the wordmark "OATBAR" in large white uppercase across the middle, "Peanut + Sea Salt" directly beneath it in a lighter white weight, and "12 G PROTEIN" in a small white box in the lower right corner. Soft even studio light, sharp print detail on the foil.

A flat lay of a single protein bar wrapper on a pale grey surface, photographed straight down and filling the frame. The wrapper is deep navy with the wordmark "OATBAR" in large white uppercase across the middle, "Peanut + Sea Salt" directly beneath it in a lighter white weight, and "12 G PROTEIN" in a small white box in the lower right corner. Soft even studio light, sharp print detail on the foil.

A flat lay of a single protein bar wrapper on a pale grey surface, photographed straight down and filling the frame. The wrapper is deep navy with the wordmark "OATBAR" in large white uppercase across the middle, "Peanut + Sea Salt" directly beneath it in a lighter white weight, and "12 G PROTEIN" in a small white box in the lower right corner. Soft even studio light, sharp print detail on the foil.
The three wrappers came from one request. The copy holds across all three, and the tracking and the badge position do not.
Batch the attempt instead of perfecting the prompt. Ask for several results in one call, read them all, and keep the one whose copy is clean. That is usually faster than another round of prompt edits, because the prompt was not what was wrong.
import { createClient } from '@runware/sdk'
const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()
const [result] = await client.run({
model: 'meta:muse@image',
positivePrompt: 'A flat lay of a single protein bar wrapper on a pale grey surface, photographed straight down and filling the frame. The wrapper is deep navy with the wordmark "OATBAR" in large white uppercase across the middle, "Peanut + Sea Salt" directly beneath it in a lighter white weight, and "12 G PROTEIN" in a small white box in the lower right corner. Soft even studio light, sharp print detail on the foil.',
numberResults: 3,
width: 1600,
height: 1600
})import asyncio
import os
from runware import Runware
async def main():
async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
results = await client.run({
"model": "meta:muse@image",
"positivePrompt": "A flat lay of a single protein bar wrapper on a pale grey surface, photographed straight down and filling the frame. The wrapper is deep navy with the wordmark \"OATBAR\" in large white uppercase across the middle, \"Peanut + Sea Salt\" directly beneath it in a lighter white weight, and \"12 G PROTEIN\" in a small white box in the lower right corner. Soft even studio light, sharp print detail on the foil.",
"numberResults": 3,
"width": 1600,
"height": 1600
})
asyncio.run(main())curl https://api.runware.ai/v1 \
-H "Authorization: Bearer $RUNWARE_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"taskType": "imageInference",
"taskUUID": "9e2b4d70-5c81-4f3a-b6d9-7a0c1e2f3b45",
"model": "meta:muse@image",
"positivePrompt": "A flat lay of a single protein bar wrapper on a pale grey surface, photographed straight down and filling the frame. The wrapper is deep navy with the wordmark \"OATBAR\" in large white uppercase across the middle, \"Peanut + Sea Salt\" directly beneath it in a lighter white weight, and \"12 G PROTEIN\" in a small white box in the lower right corner. Soft even studio light, sharp print detail on the foil.",
"numberResults": 3,
"width": 1600,
"height": 1600
}
]'runware run meta:muse@image \
positivePrompt="A flat lay of a single protein bar wrapper on a pale grey surface, photographed straight down and filling the frame. The wrapper is deep navy with the wordmark \"OATBAR\" in large white uppercase across the middle, \"Peanut + Sea Salt\" directly beneath it in a lighter white weight, and \"12 G PROTEIN\" in a small white box in the lower right corner. Soft even studio light, sharp print detail on the foil." \
numberResults=3 \
width=1600 \
height=1600{
"taskType": "imageInference",
"taskUUID": "9e2b4d70-5c81-4f3a-b6d9-7a0c1e2f3b45",
"model": "meta:muse@image",
"positivePrompt": "A flat lay of a single protein bar wrapper on a pale grey surface, photographed straight down and filling the frame. The wrapper is deep navy with the wordmark \"OATBAR\" in large white uppercase across the middle, \"Peanut + Sea Salt\" directly beneath it in a lighter white weight, and \"12 G PROTEIN\" in a small white box in the lower right corner. Soft even studio light, sharp print detail on the foil.",
"numberResults": 3,
"width": 1600,
"height": 1600
}[
{
"taskType": "imageInference",
"taskUUID": "9e2b4d70-5c81-4f3a-b6d9-7a0c1e2f3b45",
"imageUUID": "1c4e5a6b-7d8f-4901-a2b3-c4d5e6f70819",
"imageURL": "https://im.runware.ai/image/os/a14d18/ws/2/ii/1c4e5a6b-7d8f-4901-a2b3-c4d5e6f70819.jpg"
},
{
"taskType": "imageInference",
"taskUUID": "9e2b4d70-5c81-4f3a-b6d9-7a0c1e2f3b45",
"imageUUID": "2d5f6b7c-8e90-4a12-b3c4-d5e6f7081920",
"imageURL": "https://im.runware.ai/image/os/a14d18/ws/2/ii/2d5f6b7c-8e90-4a12-b3c4-d5e6f7081920.jpg"
},
{
"taskType": "imageInference",
"taskUUID": "9e2b4d70-5c81-4f3a-b6d9-7a0c1e2f3b45",
"imageUUID": "3e6a7c8d-9f01-4b23-c4d5-e6f708192a3b",
"imageURL": "https://im.runware.ai/image/os/a14d18/ws/2/ii/3e6a7c8d-9f01-4b23-c4d5-e6f708192a3b.jpg"
}
]Read the candidates at full resolution. A dropped character is invisible at thumbnail size and obvious at 100%. Check the small print before the headline, because the headline is the string the model gets right most often and the qualifier underneath it is where a run tends to break.
Production deliverables
Three pieces that ship with copy baked in, each generated at one of the model's eight fixed pixel pairs. Pick the pair closest to the placement and crop downstream when the target size is not one of the eight. The full list is in the model reference.
App store screenshot caption
Store screenshots carry a caption band above a device frame, and that caption is the copy a browsing customer actually reads. Give the caption and the step marker separate quoted strings, so the small marker is not absorbed into the headline.

A vertical app store screenshot frame on a soft blue gradient background. "Step 1 of 5" is set in small white capitals near the top, with "Track every invoice in one place" beneath it in a bold white sentence case across the upper third. Below the caption a phone mockup tilts slightly into frame showing an invoicing dashboard, cropped by the bottom edge. Clean product marketing layout, soft shadow under the phone.
The screen inside the phone frame is left undescribed beyond the app category. Interface text renders small and rarely survives at that size, so spend the prompt on the strings a customer reads at full size and keep the mockup generic.
Packaging insert card
An insert card is a couple of lines and a code that a customer has to type. A code is the least forgiving string in a layout, because there is no word for the model to fall back on when a character slips. Quote it in uppercase and read it back character by character before a batch goes to print.

A square printed card lying on a folded linen shirt inside an open cardboard shipping box, photographed from directly above. The card is off-white with "THANKS FOR SHOPPING SMALL" in charcoal uppercase across the top, "Your next order is 15% off" in a smaller charcoal weight beneath it, and "USE CODE RESTOCK15" set in a bold charcoal box at the foot of the card. Warm window light, shallow depth of field on the edges of the box.
Tips
-
Quote every string you want set. Anything outside quotation marks is a description the model rewords. Anything inside is content it renders.
-
Keep each string short. A headline, a product name, a price and a one-line qualifier all render reliably. Body copy at paragraph length does not.
-
Write the number, never imply it. Put the number in the string yourself, whether it is a price, a percentage, a count or a date. Anything the model has to derive, it invents.
-
Keep a price in the same string as its item. A price in its own clause can attach to the wrong row when the layout reflows.
-
Name weight, case, colour and placement. Type you do not direct gets chosen for you, and the choice changes between runs.
-
Batch, then pick. Ask for several results in one call. Lettering varies from run to run with no seed to pin it, so a batch of candidates beats one more prompt edit.
-
Check the copy at full resolution. Errors that vanish in a thumbnail are obvious at 100%, and the small print breaks before the headline does.
-
Fix a single wrong word by editing. Send the frame back with a scoped instruction rather than regenerating and losing a layout you already liked. See editing images.
