The model is the easy part. What building Dantiva taught me A developer built Dantiva, a photo-to-video product powered by Google's Veo 3.1 and Gemini models that generates eight-second clips with sound across a website, Telegram bot, and Telegram Mini App. The developer reports that the surrounding product layer — shared accounts and token balances across three surfaces, a reserve/capture/refund ledger, and admin tooling — took far more effort than the underlying models, and that a September 19 UI bug briefly showed unlimited-access users a paid balance despite the server logic being correct. Payments have been live since early September and subscriptions since the 18th, with paid demand still unconfirmed. Dantiva turns a photo into a short video. You pick a template, upload a picture, and a few minutes later you get an eight second clip with sound. It runs on Google's models, it lives on a website and inside Telegram, and it is my first product that takes real money from strangers. This is what the build looked like from the inside, including the parts that went wrong. Under the hood there are two Google models. Veo 3.1 makes the video, in a Fast and a Lite variant. A Gemini image model makes and edits pictures. A third Gemini model rewrites the user's prompt before it goes to the video model, because most people type three words and expect a movie. Around those calls is everything that makes it a product rather than a demo: accounts, a balance in tokens, templates, a library of results, projects, a legal center in two languages, an admin panel for support and refunds. That second layer took most of the time. The first Telegram bot, in July, was a single API call to Veo on Cloud Run with all state kept in memory. It worked. It could not be sold. The audience is Russian speaking people who want a video with themselves in it: a birthday greeting, a trend from their feed, a new avatar. The tools they would normally use are behind a foreign card and a VPN. Paying in rubles, from a Telegram account, with a proper receipt, is the one advantage I can prove today. Everything else about the segment is still a hypothesis, and I try to write it down that way. Paid demand is not confirmed yet. Payments have been live since early September and subscriptions since the 18th, so the next few weeks are the test. There are three ways in: the website at dantiva.com, a Telegram bot, and a Telegram Mini App that opens inside the bot. They share one account and one token balance. That last sentence cost me a month. Each surface has its own way of knowing who you are. The site uses Google sign in or email with verification. The bot knows your Telegram ID. The Mini App gets a signed payload from Telegram. All three have to resolve to the same wallet, and a purchase made in one place has to show up in the other two within seconds. Every feature now gets a parity check across all three before release, because the first time I skipped it, the bot had templates the site did not. I still do not know which door converts best. The bot is where people arrive, the site is where the bigger packs are, and the Mini App sits in between. I will only find out from purchase data, not from opinions. Generation costs real money on every call, and a call can fail halfway. So the balance is not a number you subtract from. It is a ledger: reserve tokens when a job starts, capture them when the video arrives, refund them if the provider fails. Every job has an idempotency key, so a double tap on a slow connection does not start two generations. There is one welcome grant per device, a daily ceiling, and a limit on jobs running at the same time, because free tokens on an open internet get farmed within hours. On September 19 the ledger reminded me why the UI is not allowed to have opinions. Some users have unlimited access: friends, testers, partners. The server checks that list before touching any wallet, and it did so correctly. But the Mini App rendered the launch screen twice. The first pass set the status to unlimited. The second pass overwrote it with the subscription wallet. So a person with unlimited access saw a balance of 25 paid tokens and an offer to buy a plan. Nothing was charged. It still looked like a broken promise. The fix was a priority rule in the interface and two regression tests that render the screen twice on purpose. The server was never the problem, and that is the point: the money logic belongs in one place, and the screens only display it. The project has had three names. It started in July as Project Aurora, an internal codename. Then it became Synora. Then Dantiva, which is the name on the domain and in every customer facing string. Inside the code it is still Synora. The environment variables start with SYNORA , the device header is X-Synora-Device, the Cloud Run service and the task queue carry the old name. I wrote a rule into the cutover document that forbids renaming them. A rename touches secrets, deployment configuration, the queue, the header every client sends, and the Telegram configuration, all at once, for zero user value. Users never see it. The day I break production for a cosmetic change is the day I deserve to lose the users. So the mismatch stays, and it is documented. The first prices were token packs at 449, 1590 and 3890 rubles. Then 490, 1690 and 3990, after a review of the provider's actual prices. Then, on September 18, subscriptions: Start at 199 rubles for 1400 tokens, Author at 499 for 4200, Pro at 999 for 10080, with smaller top ups from 99 rubles. An eight second Fast video with sound costs 140 tokens, so the cheapest plan is about ten videos a month. Renewal is manual for now, until the automatic payment is approved by the payment provider. The honest footnote: generation is currently subsidized by a Google Cloud grant. At Google's list price an eight second clip costs roughly 80 rubles to produce. The catalog is normalized to a gross margin of around 30 percent at real provider prices, so the plans are meant to survive the grant. Whether they do is a question for November, when the grant runs out. All the templates start from a photo of a person. Google Veo blocks image to video with recognizable people. It is a separate filter, it cannot be switched off, and there is no allowlist for it. I found this out after the template catalog was built. So the main feature the product was designed around does not work on the main model. Text to video works. Image generation works. Animating your own face does not. I have spent the last week comparing alternatives that accept a photo without a video consent recording: Kling through fal.ai, Runway's Gen-4 Turbo, Seedance through BytePlus. Each has its own price per second, its own payment path, and its own rules about Russian users and Russian cards. None is connected yet. The plan is to run paid video through whichever one passes a small test, keep Google for everything it does well, and charge separate token rates per model inside the same balance. I could hide this. It would be a bad idea, because the first person who tries the product finds it in two minutes. I would test the provider's content policy on the exact use case before building a whole template catalog around it. I would write the ledger first and the screens second, instead of the other way around. I would pick the final name before the first deployment. And I would ship subscriptions earlier: a 199 ruble monthly plan tells you more about demand than three sizes of one time pack. A second video provider behind the same token balance. Automatic renewal once the payment provider approves it. A small set of interviews with people who actually paid, so the segment stops being a hypothesis. And a decision by November on whether the economics hold without the grant. I built most of this with AI coding assistants doing the typing and me doing the deciding, the testing, and the reading of every audit document. If you are building something similar and hit the same walls, write to me. I would like to compare notes. Originally published at ilinmaks.com https://www.ilinmaks.com/blog/en/dantiva-ai-video-studio-build-notes .