The $0 Creative Department
How we built a full ad pipeline, from image generation to Meta deployment, with AI and 200 lines of Python
At Alma, we’re a small team. We don’t have a creative department. We don’t have a media buyer. For most of our existence, we didn’t run paid ads at all.
In less than a day, we shipped 13 carousel ad campaigns (10 educational advertorials and 3 geo-targeted city guides) totaling 116 carousel cards, each linking to a fully designed landing page with original copy, structured data for SEO, and scroll-depth analytics. The whole pipeline, from concept to live ads, took about two hours per batch.
No dedicated designer. No copywriter. No agency. No Canva.
This isn’t a story about AI replacing jobs. It’s a story about what becomes possible when the barrier between “idea” and “live campaign” drops to near zero.
The Old Way Was Expensive Enough to Kill Ideas
Before this, our ad workflow looked like most early-stage startups:
Have an idea for a campaign
Brief a designer (or open Figma yourself)
Write copy in a Google Doc
Export assets in 4 different aspect ratios
Upload to Meta Ads Manager manually
Build a landing page (or worse, send traffic to your homepage)
Wait days. Repeat.
The real cost wasn’t money. It was activation energy. Most campaign ideas died in step 2 because the effort-to-test ratio was absurd. You’d spend a week building something to discover it doesn’t convert, then start over.
We needed a system where the cost of testing an idea was close to zero.
What We Actually Built
The pipeline has four layers, each one a Python script or a React config file:
1. Image Generation (Programmatic)
We generate ad creative images programmatically. Not generic stock photos. Structured compositions with our brand system (colors, typography, layouts) applied automatically. For our city guide campaigns, each restaurant gets a card. For our advertorial campaigns, we generate cards around specific nutritional concepts. The visual language is consistent because it’s code, not a designer’s memory.
2. Landing Pages (Config-Driven)
Every landing page is a React component driven by a JSON-like config object. Want a new advertorial about the protein myth? Write a config with a title, sections, and a CTA. Want a city guide for San Francisco? Write a config with 10 restaurants, their descriptions, highlights, and links. The component handles layout, SEO meta tags, JSON-LD structured data, scroll tracking, and CTA analytics automatically.
Adding a new page is 15 minutes of writing content. Not design. Not code.
3. Meta Ads API (Deployment Scripts)
This is where it gets interesting. Instead of clicking through Ads Manager, we deploy campaigns programmatically:
Create campaign with objective and budget
Create geo-targeted ad sets (SF residents see SF restaurants, NYC sees NYC)
Upload carousel card images via API
Build carousel creatives with UTM-tagged links
Create ads and attach them to ad sets
Activate or pause with a flag
One Python script. Three cities. Fifteen carousel cards. Geo-targeting, conversion optimization, and budget allocation, all configured in code. Run it, and the ads are live.
4. Analytics (Closed Loop)
Every landing page tracks scroll depth, CTA clicks, and page views via PostHog. Every ad link carries UTM parameters that connect Meta spend to on-page behavior. We can see exactly which city, which carousel card, and which scroll depth led to a download.
The Two-Hour Campaign
Here’s what the city guide campaign looked like in practice:
Hour 1: Write restaurant descriptions for SF, NYC, and LA. Ten restaurants per city. This was the bottleneck, and it was the creative bottleneck, not the production bottleneck. I guided the AI, fact-checked claims, adjusted tone, and shaped the editorial voice. The research, structuring, and first drafts were AI-assisted.
Hour 2: Generate carousel images. Write the deploy script. Dry-run. Deploy. Push landing pages to production. Activate ads.
By the end, we had:
3 SEO-optimized landing pages with 10 restaurants each
3 geo-targeted ad sets ($30/day each)
18 carousel cards with custom images (title + 4 restaurants + CTA per city)
Full analytics pipeline
JSON-LD structured data for Google rich results
Total ad spend on creative production: $0.
But the city guides were just one campaign. Here’s everything we shipped with this pipeline: 13 carousel campaigns across two categories, all deployed the same way.
Every Campaign We Shipped (With the Actual Ad Copy)
All of these are live on Meta right now. Each one was conceived, designed, written, and deployed with the same pipeline described above. Title card, content cards, CTA card. All generated programmatically from our brand template system.
Educational Carousels (10 campaigns)
These use a swipeable format: a gallery-style title card, 7-9 content cards with data and images, and a closing CTA card. Every carousel links to a dedicated advertorial landing page.
1. What 2,000 Calories Looks Like - 9 cards, LEARN_MORE → alma.food/what-2000-looks-like
A Big Mac, fries, and a Coke = 2,000 calories. A full Mediterranean spread with fish, hummus, salad, fruit, and nuts = also 2,000 calories.
Same number. Wildly different plates.
Swipe to see what 2,000 calories actually looks like across 7 different eating styles.
Cards: Title → Fast Food (1 Meal) → Mediterranean (A Full Day) → “Healthy” Snacking → Japanese (Dozens of Dishes) → Pizza Night (3 Slices + Beer) → Indian Thali (A Feast) → Mindless Snacking → CTA
2. The Protein Myth - 9 cards, LEARN_MORE → alma.food/protein-myth
Granola: 4g protein per serving. Greek yogurt: 17g.
Almond milk: 1g per cup. Regular milk: 8g.
Most “high-protein” marketing is just marketing.
Swipe to see the real protein numbers behind 7 common foods.
Cards: Title → Granola (4g) → Peanut Butter (7g) → Quinoa (8g) → Almond Milk (1g) → Avocado (4g) → Protein Bar (10g) → Hummus (2g) → CTA
3. Guess the Calories - 10 cards, LEARN_MORE → alma.food/guess-the-calories
That açaí bowl? 680 calories. The Caesar salad? 520. Your “healthy” green smoothie? 450.
Most people underestimate their food by 40-50%.
Swipe to see the real numbers. How close can you get?
Cards: Title → Açaí Bowl (680) → Caesar Salad (520) → Trail Mix (700) → Green Smoothie (450) → Sushi (850) → Avocado Toast (550) → Protein Bar (380) → Overnight Oats (580) → CTA
4. A Love Letter to Food - 10 cards, DOWNLOAD → App Store
Bread is 10,000 years old and still the first thing we reach for.
Honey never spoils. Tomatoes were once thought poisonous. Half the planet eats rice every single day.
This isn’t about macros. It’s about the food itself.
For people who love food, not to restrict it, but to understand it.
Cards: Title → Dear Bread → Dear Eggs → Dear Rice → Dear Olive Oil → Dear Chocolate → Dear Tomato → Dear Honey → Dear Lemon → CTA
5. Meal Prep vs. Reality - 10 cards, DOWNLOAD → App Store
The overnight oats you planned: layered, beautiful, art. The overnight oats you ate: gray mush from a jar while standing.
Both counted. Both were 380 calories.
Alma tracks what you actually eat, not the Pinterest version.
Swipe to see the plan vs. the reality.
Cards: Title → Chicken & Quinoa (Plan) → Desk Lunch (Reality) → Overnight Oats (Plan) → Gray Mush (Reality) → Salmon Salad (Plan) → Sad Desk Salad (Reality) → Berry Smoothie (Plan) → Protein Shake (Reality) → CTA
6. The Protein Gap - 10 cards, LEARN_MORE → alma.food/the-protein-gap
An egg has 6g of protein. Not 15. A café smoothie bowl? 9g. Not 30. Peanut butter toast? 7g. Not 15.
Most people overestimate protein in common foods by 2-3x.
Swipe to see how much protein is actually in your food.
Cards: Title → Egg (6g) → Yogurt Parfait (12g) → PB Toast (7g) → “Protein” Smoothie Bowl (9g) → Salmon Fillet (17g) → Quinoa Bowl (8g) → Hummus & Pita (6g) → Chicken Breast (54g) → CTA
7. Hidden Sugar - 10 cards, LEARN_MORE → alma.food/hidden-sugar
Your oat milk latte? 28g of sugar. The granola? 24g. The açaí bowl? 42g, more than a can of Coke.
WHO recommends under 25g of added sugar per day. Most people hit that before lunch.
Swipe to see where the sugar is hiding.
Cards: Title → Oat Milk Latte (28g) → Granola (24g) → Açaí Bowl (42g) → Flavored Greek Yogurt (19g) → Dried Mango (27g) → Kombucha (16g) → Teriyaki Bowl (22g) → Daily Total: 89g → CTA
8. The Serving Size Lie - 10 cards, LEARN_MORE → alma.food/serving-size-lie
A “serving” of cereal is 3/4 cup. Nobody pours that. A “serving” of ice cream is 2/3 cup. Three bites. A “serving” of peanut butter is 2 tbsp. A thin film.
If every serving is double, your 1,800-calorie day is actually 3,400.
Swipe to see the label vs. what you actually pour.
Cards: Title → Cereal (160 vs. 530) → Olive Oil (120 vs. 360) → Pasta (200 vs. 400) → Orange Juice (110 vs. 220) → Peanut Butter (190 vs. 380) → Ice Cream (230 vs. 520) → Chips (140 vs. 370) → Daily Gap: +1,630 → CTA
9. Invisible Calories - 10 cards, LEARN_MORE → alma.food/invisible-calories
Handful of trail mix: 280 cal Afternoon latte: 190 cal Cheese while cooking: 210 cal Glass of wine: 150 cal “Just a bite” of the kid’s food: 130 cal
Total: 1,175 calories of “nothing.”
Swipe to see the calories you’re not tracking.
Cards: Title → Trail Mix at Desk (280) → Afternoon Latte (190) → Dark Chocolate (120) → Cheese While Cooking (210) → Glass of Wine (150) → Spoonful of PB (95) → Kid’s Leftovers (130) → Total: 1,175 → CTA
10. Same Name, Different Calories - 10 cards, LEARN_MORE → alma.food/same-name-different-calories
“Caesar salad” can be 380 or 1,150 calories. “Pad Thai” can be 400 or 1,100. “Turkey sandwich” can be 350 or 890.
The name on the menu tells you nothing about the nutrition.
Swipe to see how much the same dish can vary.
Cards: Title → Caesar Salad (380 vs. 1,150) → Burrito Bowl (410 vs. 980) → Margherita (550 vs. 1,200) → Pad Thai (400 vs. 1,100) → Salmon Bowl (450 vs. 920) → Smoothie Bowl (320 vs. 780) → Turkey Sandwich (350 vs. 890) → Average Gap: 594 → CTA
City Guide Carousels (3 campaigns, geo-targeted)
Each city gets its own ad set targeted ONLY to people in that metro. Six cards per carousel: title card, four restaurants, CTA card. Each links to a long-form advertorial landing page with the full top-10 list, SEO structured data, and scroll tracking.
11. San Francisco - 6 cards, geo: SF only → alma.food/healthy-restaurants-san-francisco
San Francisco has some of the best healthy restaurants in the country.
From Greens, the vegetarian pioneer with Golden Gate views, to Nopa’s organic wood-fired kitchen sourcing from 20+ local farms.
We put together a guide to the 10 best healthy restaurants in SF. Swipe to see our picks.
Cards: Title → Greens (Fort Mason) → Nopa (North Panhandle) → Beloved Café (Mission) → Blue Barn (Marina) → CTA
12. New York City - 6 cards, geo: NYC only → alma.food/healthy-restaurants-nyc
NYC’s healthy restaurant scene goes way beyond sad desk salads.
From Eleven Madison Park’s plant-based fine dining to Dirt Candy’s mind-bending vegetable tasting menus, healthy food in NYC is actually some of the most exciting food in the city.
Here are the 10 best healthy restaurants in New York. Swipe to explore.
Cards: Title → Eleven Madison Park (Flatiron) → abcV (Flatiron) → Dirt Candy (Lower East Side) → Avant Garden (East Village) → CTA
13. Los Angeles - 6 cards, geo: LA only → alma.food/healthy-restaurants-la
LA practically invented the wellness-dining movement.
From Crossroads Kitchen, the vegan restaurant that convinced skeptics, to Destroyer, where a 2-Michelin-starred chef makes avocado toast into fine art.
Here are the 10 best healthy restaurants in LA. Swipe to see our picks.
Cards: Title → Crossroads Kitchen (Melrose) → Destroyer (Culver City) → Café Gratitude (Venice) → Gracias Madre (WeHo) → CTA
Total: 13 campaigns. 116 carousel cards. 13 landing pages. $0 in creative production.
What This Changes for Early-Stage Teams
The implication isn’t “fire your designer.” It’s more fundamental than that.
1. You can test 10x more ideas.
When the cost of going from idea to live ad is two hours and zero dollars, you stop debating which campaign to run. You run all of them. The bad ones die fast. The good ones get budget. This is how a two-person team competes with a company that has a media buying agency.
2. The landing page IS the ad.
Most startups send ad traffic to their homepage and wonder why conversion is low. When you can spin up a purpose-built landing page for every campaign in minutes, every ad gets a dedicated destination. Our city guides aren’t selling Alma directly. They’re providing genuine value (a restaurant guide) with a soft CTA. The content does the selling.
3. Iteration is instant.
Our SF guide started with 4 restaurants. Feedback said “make it a top 10.” Twenty minutes later, it was a top 10: researched, written, deployed, and live. Try asking an agency for that turnaround.
4. The code is the brand guideline.
When your creative pipeline is code, consistency is automatic. Colors, typography, spacing, tone. They’re constants in a file, not a PDF that nobody reads. Every new campaign inherits the brand system by default.
What Still Requires a Human
Let me be honest about where AI falls short in this pipeline:
Editorial judgment. AI can research and draft restaurant descriptions. It cannot tell you that Greens Restaurant’s story about being recognized by the New York Times is the detail that makes the copy compelling. That’s taste.
Strategic direction. The decision to build geo-targeted city guides aimed at health-conscious diners in specific metros: that’s strategy. AI didn’t suggest that. We had a hypothesis about local intent and built a fast way to test it.
Brand voice. Every piece of copy got edited. Not rewritten. Edited. The difference between AI-generated marketing copy and copy that sounds like your brand is usually 15 minutes of a human with opinions.
Quality control. Are these restaurants still open? Is the Michelin star current? Does the website link work? AI gets you 90% there. The last 10% is checking.
The Stack
For anyone who wants to build something similar:
Landing pages: React + Vite, config-driven components, deployed via Git push
Image generation: Python scripts with Pillow/HTML rendering
Ad deployment: Facebook Business SDK (
facebook-businessPython package)Analytics: PostHog for page events, UTM parameters for attribution
Content: Claude for research and drafting, human for editing and judgment
Hosting: Vercel (or similar) with instant deploys
The total codebase for the ad pipeline is maybe 1,500 lines of Python across the deploy scripts. The landing page component is ~250 lines of React. The config for each campaign is ~100 lines of JavaScript. The image generation (title/CTA cards and content cards) adds another ~500 lines.
The Takeaway
The most expensive part of marketing at an early-stage startup isn’t ad spend. It’s the time between having an idea and knowing if it works.
We didn’t build an AI marketing department. We built a pipeline that makes the distance between “what if we tried...” and “here’s the data” as short as possible.
The ads are running. The landing pages are live. Thirteen campaigns, three cities, ten advertorial concepts. If the city guides don’t convert, we’ll know by Friday and try something else by Saturday. If “Invisible Calories” outperforms “The Protein Myth,” we’ll shift budget in an hour.
That’s the actual unlock. Not cheaper creative. Faster learning.
Curious about what we’re building? Alma is an AI nutrition coach that actually remembers you. Free to start.


This is genuinely impressive, Rami. You’ve removed the friction that kills experimentation and turned creativity into a systems problem instead of a bottleneck. The clearest takeaway for me is not “AI ads,” it’s faster learning with real editorial judgment still in the loop.