Engineering

YourMitra: building a live AI storybook platform on my own

The story behind YourMitra — a personalized AI storybook product I built end to end, from the generation pipeline to payments, rate limiting, and the admin panel that runs the business.

Mokshit Jain · · 9 min read

YourMitra is a personalized AI storybook platform where a child becomes the hero of their own story. I built it end to end as the sole engineer — backend, frontend, the AI pipeline, payments, deployment, and the admin panel that actually runs the business. It’s live, with real paying customers and repeat traffic, so most of what I write here is about keeping something like this reliable in production, not just getting a demo working.

Let me go from the product down to the engineering.

What the product actually is

A parent uploads their child’s photo and we generate a story where that child is the main character. There are three ways to get a story:

  • Digital — a set of generated, personalized images (around 20+ per story) with matching audio narration. Every image is customized for the specific child.
  • B2C events — an event manager registers an event, shares a signup link, and every participating child gets a story as a gift hamper. Each event gets its own portal, and organizers can pick from our stories or request a custom one.
  • Hardcover — an actual printed book, delivered to the customer. For events we either deliver to the venue, or ship to each participant’s home when a venue drop isn’t possible.

On top of that there’s a user dashboard, a sample-preview page, and an admin portal where I can see every unit, order, event, and — importantly — how much we’ve spent on AI so far.

How a story gets generated

The generation flow is the heart of it. Starting from a story template:

  1. The child’s photo is turned into an avatar.
  2. A GPT image model places that avatar into the template, and then I use Pillow (plus some processing) to lay text, overlays, and colors onto each image.
  3. Audio comes in two kinds — dynamic audio that’s personalized (the child’s name, for example), and static audio that’s the same across every story (like the storybook’s name).

The naive version of this ran everything in sequence and took about 20 minutes per story, which is unusable when someone has just paid and is waiting. So I moved generation onto Temporal.io workers and parallelized the independent steps — images, audio, and the rest run concurrently, and generation is fully separated from delivery. That brought a story down to roughly 2 minutes, and story pages themselves load quickly because the heavy work is already done by the time a user opens one.

# The independent pieces fan out instead of running one after another.
image_tasks = [
    workflow.execute_activity(generate_page_image, page, start_to_close_timeout=...)
    for page in story.pages
]
images, narration = await asyncio.gather(
    asyncio.gather(*image_tasks),
    workflow.execute_activity(generate_narration, story.text, start_to_close_timeout=...),
)

The parts that made it a real product

A demo is one thing; something people pay for needs a lot of unglamorous plumbing. The pieces I’m most glad I built:

  • A rate limiter across every AI provider. OpenAI, ElevenLabs, Replicate, and the image-edit service all have different limits and tiers. Instead of scattering that logic, I built one token-bucket rate limiter that an admin can tune per provider from the dashboard, and new providers can be added later without touching the workflows.
  • Feature flags. Around six of them — auto-guest, photo cleanup, OTP hard lockout, print-generation delay, selective retry — so I can change behavior for specific situations without a deploy.
  • A notification service that isn’t tied to one vendor. Email goes through SendGrid or Resend, SMS and WhatsApp through MSG91 or Twilio, and RCS through MSG91. The point was to pick a provider per message and optimize for cost and deliverability.
  • My own short-link service. The internal IDs are long UUIDs, so I generate 6-character codes (/r/<code>) with click tracking and caching — the links people actually share and I actually watch in analytics.
  • Payments. I integrated Razorpay for the whole checkout and order flow, and it’s been solid — no payment issues from customers.

The stack, honestly

Backend is FastAPI + PostgreSQL + Redis with Temporal for orchestration, running as Docker services (API, worker, Temporal, Postgres, Redis). The frontend is Astro + React + TypeScript. Media lives on AWS S3. AI is OpenAI (images + text), ElevenLabs (voice), and Replicate. Errors go to Sentry and product analytics to PostHog. I also manage the infrastructure myself — the VPS, domain, networking, and the reverse proxy in front.

What I took away from it

The lesson that stuck with me is that the model calls are the easy part. What made YourMitra survivable in production was treating the boring things — rate limits, retries, feature flags, provider fallbacks, an admin panel that shows real costs — as first-class features. Being the only engineer meant I couldn’t hide behind “someone else owns that,” and that’s exactly why I learned the most from it.

If you want to see it, it’s live at yourmitra.com.

Share
Written by
Mokshit Jain

AI engineer & full-stack developer building LLM products, automation, and RAG pipelines.

Continue reading