You already have the hard part. Somewhere in your week there's a piece of real information nobody else has: the rooftop deck opened, the two-bedrooms are stacking up on floors 4 through 7, the new concession is six weeks free on 13-month terms, the dog park finally has grass. That's the input. What you don't have is time to turn it into an Instagram post, a Google Business Profile update, a renewal email, a Craigslist ad, four ILS description tweaks, and a talking point for the leasing team's Monday huddle.
So the update dies in your head. Or worse, it lives in a Slack message that three people react to and nobody acts on.
The content engine fixes exactly this, and it's the single pattern behind every AI content operation worth copying. One input, structured properly. Many outputs, generated in one pass. You're not writing faster. You're writing once.
The pattern
Every good AI content system has the same three parts, and most people skip the first one.
The source block. A single structured dump of facts about the thing. Not prose. Facts. Property name, submarket, current availability by floor plan, pricing, current concession and its expiry, three physical features of the unit or amenity you're pushing, the nearest employer or transit node, the brand voice in one line, and anything you are legally required to include.
The transform instruction. What formats you want, with the constraints that make each one usable. Character limits. Required disclaimers. Tone. Where it's going to appear.
The output contract. How you want the response structured so you can actually paste it somewhere. Labeled sections. No preamble. No "Here's your content."
Most people type the input and the transform in one blurry sentence and get back mush. The separation is the technique.
Building your source block
Do this once per property, not once per post. Open a doc titled "Source block: [Property]" and fill in the facts that don't change weekly:
PROPERTY: Larkspur Flats, 268 units, Midtown submarket
UNIT MIX: studio 520sf, 1BR 710sf, 2BR/2BA 1,080sf, 3BR 1,340sf
FEATURES BY PLAN: 2BR has double vanity, walk-in closet in primary,
in-unit W/D full size, private balcony on stacks 04-08
COMMUNITY: rooftop deck w/ grills, 24hr gym, package room w/ cold storage,
fenced dog run, garage parking $125/mo
LOCATION: 0.4mi to Blue Line Midtown station, 1.2mi to Baptist Medical,
Trader Joe's across the street
VOICE: direct, specific, no exclamation points, never uses "luxury"
ALWAYS INCLUDE: EHO logo/statement on all paid and listing content
Now the weekly part is four lines: what's available, what it costs, what the concession is, and what changed. That's your variable input. The source block is the constant.
This is the whole trick. Your prompt quality problem was never prompt engineering. It was that you were asking a model to write about an apartment it knows nothing about.
The transform
Here's where you get paid. Take the source block plus this week's variables and ask for the full set of outputs in one request:
- Instagram caption, under 125 characters before the fold, no hashtag soup
- Google Business Profile post, 1,500 char limit, one clear action
- ILS description, 250 words, front-loaded with the three features that differentiate
- Two paid search headlines at 30 characters and two descriptions at 90
- Renewal outreach email for residents in the same floor plan
- Three text-message follow-ups for prospects who toured and went quiet
- Five bullet talking points for the leasing team
Seven assets. One request. The model has the same facts for all of them, so your Instagram post and your ILS listing finally say the same thing about the same building, which is more than can be said for most portfolios where the ILS copy was written by a person who left in 2021.
Where it goes sideways, and the fix
Ask a model to write apartment marketing copy and it will reach, immediately and cheerfully, for the resident instead of the unit. "Perfect for young professionals." "Great for a growing family." "Ideal for students at the university." Every one of those describes who should live there, and describing who should live there is a fair housing problem. Familial status, age, national origin: the model doesn't know it's steering, but the language does it anyway.
The fix goes in your transform instruction and stays there permanently: describe the unit, the building, and the location. Never the person who should live in it. No references to who a home suits, who would love it, or what kind of household it fits. Then read the output before it ships. The model will comply when told and drift back when not told, so the instruction lives in your saved prompt, not in your memory.
The other failure is quieter: the model will invent amenities. It will give you a pool. If your source block doesn't say pool, and the output says pool, that's not creativity, that's a fair housing and advertising accuracy problem wearing a friendly hat. Read every factual claim against your source block. Every time.
Make it a system
Save the source block per property. Save the transform prompt once. Then Monday looks like this: paste source block, paste this week's four variables, run, review, distribute.
The version of this that actually sticks adds one more step. Keep a "rejected" file of outputs you killed and why. Feed the three worst offenders back in with "avoid these patterns" the next time you run it. Your prompt gets sharper every month instead of resetting every Monday.
You can run this for one property or thirty. The only thing that scales badly is the review, and that's the part you should never automate.