← All work

AI · Payments · Case study

AI CV Photo

Professional headshots from a selfie, in about 20 seconds

running in production aicvphoto.com ↗

The problem

A studio headshot costs €100–300 and a booking you'll postpone twice. Most people don't need a photoshoot — they need one good, professional photo for a CV or LinkedIn, today. Generic AI filters exist, but their output tends to fail the only test that matters: would a recruiter believe this is a photograph?

What I built

Upload any selfie, optionally describe what you want, pick a background — get a CV-ready portrait back in roughly twenty seconds.

  • Optional plain-text editing instruction plus background presets: solid color, gradient, office, outdoor
  • Free to try with a watermark; Stripe credit packs unlock full-resolution downloads
  • A credit system with validity windows per pack, tracked in a ledger
  • Private gallery with 60-day retention and permanent delete at any time
  • Google sign-in, and GA4 funnels to see exactly where users drop off

How it works

  1. Selfie upload
  2. Prompt compiler merges instruction + background + guardrails
  3. AI image model renders (~20 s)
  4. Post-process & watermark on the free tier
  5. Saved to the private gallery (60-day retention)
  6. Stripe credits unlock the full-resolution download

The differentiator is the prompt-engineering layer. Raw model output on arbitrary selfies is inconsistent — lighting, angles and framing vary wildly. So every request is compiled into a structured prompt: the user's instruction, the chosen background, and a set of guardrails that preserve the person's identity and enforce professional-portrait conventions. Consistency is designed, not lucky.

Payments run through Stripe Checkout, with webhooks feeding a credit ledger in SQL Server — handled idempotently, so a retried webhook can never double-credit an account. The app itself is Blazor Server on .NET.

Distribution

This is the product where I did real marketing, not just engineering. It carries the most serious SEO of the three — content pages, clean structure, proper metadata — and I ran paid-acquisition experiments on both Google Ads and Reddit Ads to test channels against organic traffic.

Hard problems

  • Consistent quality across uncontrolled inputs — any phone, any lighting, any angle. The guardrail prompt evolved constantly against real-world selfies.
  • Holding roughly 20 seconds per render as usage grows, so the experience feels instant rather than "submitted to a queue."
  • Billing correctness: expiring credits plus asynchronous webhooks is a small distributed system, and the ledger must never disagree with Stripe.

Results & lessons

Over 2,000 photos generated for 500+ users so far. The biggest lesson: distribution beats features. A few weeks of SEO and ads experiments taught me more about what this product really is than a month of building did.