<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Just a Side Project</title>
    <description>The latest articles on DEV Community by Just a Side Project (@just_a_side_project).</description>
    <link>https://dev.to/just_a_side_project</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4063172%2F2d4a6757-a858-4445-a5c2-acf8d9ab9994.png</url>
      <title>DEV Community: Just a Side Project</title>
      <link>https://dev.to/just_a_side_project</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/just_a_side_project"/>
    <language>en</language>
    <item>
      <title>What 'Free' Actually Means Across a Multi-Service Google Stack</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Mon, 24 Aug 2026 12:00:30 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/what-free-actually-means-across-a-multi-service-google-stack-349m</link>
      <guid>https://dev.to/just_a_side_project/what-free-actually-means-across-a-multi-service-google-stack-349m</guid>
      <description>&lt;p&gt;I want to be upfront about something before this post goes any further: I don't have a clean dollar figure to show you. I went looking for one -- I wanted to open the Google Cloud billing console, screenshot a $0.00 total, and call it proof. What I found instead was that "free" across a multi-service Google stack isn't one number at all. It's a pile of separate ceilings, each with its own reset clock, its own fine print, and in at least one case, a wall that had nothing to do with usage limits and everything to do with a policy I didn't know existed. This is the more honest version of that post -- what "free" actually meant, service by service, including the parts that cost me time instead of money.&lt;/p&gt;

&lt;h3&gt;The free tiers that behaved exactly like the docs said&lt;/h3&gt;

&lt;p&gt;Two services in this pipeline were boring in the best way -- I read the limit once, stayed under it, and never thought about it again.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blogger API v3&lt;/strong&gt; has no meaningful quota for a single-author blog. It's a legacy Google product that's still maintained, and nothing about posting, updating, or publishing through the API has a cost attached at this scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dev.to's API&lt;/strong&gt; is free for posting and reading, full stop, with no billing account involved at all -- refreshing, after spending so much time inside Google Cloud's console.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;The free tier that has more than one number in it&lt;/h3&gt;

&lt;p&gt;Google Cloud Text-to-Speech looks like a single "free tier" on the pricing page, but it's actually several different ceilings stacked depending on which voice model you use -- Standard, WaveNet, and Neural2 voices are metered separately, and the Neural2 allowance is meaningfully smaller than the other two. I'd recommend checking the current numbers directly on Google's pricing page before you plan a project around them, since free-tier terms are exactly the kind of thing that gets revised without much fanfare -- but the shape of it, at least when I set this up, was: generous character allowances on the older voice models, a noticeably tighter one on the newest, most natural-sounding tier. If your project leans on the nicest-sounding voices specifically, that's the number to actually watch, not the headline "free tier" claim.&lt;/p&gt;

&lt;h3&gt;The one that wasn't a usage limit at all&lt;/h3&gt;

&lt;p&gt;The most expensive part of this build, in time if not in dollars, wasn't a quota. It was an organization policy -- &lt;code&gt;iam.disableServiceAccountKeyCreation&lt;/code&gt; -- silently blocking me from generating a service account key on a project I owned outright, because my Google account happened to sit inside an org where that constraint defaults to on. Nothing about that shows up on a pricing page, because it isn't a pricing question. It's worth naming as its own category of "free tier cost": the setup friction that has nothing to do with usage and everything to do with defaults you didn't choose. I ended up switching to an OAuth-based auth flow instead of fighting the policy, which turned out to be less work anyway.&lt;/p&gt;

&lt;h3&gt;The one I still can't give you a confident number for&lt;/h3&gt;

&lt;p&gt;Google Cloud Storage's free tier -- relevant if you're hosting generated images or audio anywhere other than inline in your content -- is the one I'm least willing to state a specific figure for here. The free storage and egress allowances exist, but they're also the kind of number Google has adjusted before, and I haven't independently re-verified the current terms against my own account at the time of writing. If a project of yours actually depends on staying under that ceiling, treat whatever number you read anywhere, including this post, as a starting point to confirm on Google's own current pricing documentation -- not a fact to build on unchecked.&lt;/p&gt;

&lt;h3&gt;What actually forced a decision, versus what didn't&lt;/h3&gt;

&lt;p&gt;Looking back at every point where I had to stop and make a call, almost none of them were "I'm about to exceed a quota." They were closer to: an org policy blocking a key, a billing address that Google's system didn't recognize for a newly-split Korean administrative district, a DNS lookup failing because a machine hadn't finished waking from sleep. The free tiers themselves, once I understood their actual shape instead of the one-line pricing-page summary, were generous enough that usage limits never once forced a redesign. The friction was almost entirely operational -- verifying an address, understanding a policy, debugging a race condition -- not financial.&lt;/p&gt;

&lt;h3&gt;If you're planning something similar&lt;/h3&gt;

&lt;p&gt;The practical version of this post, if you don't want to read the rest of it: budget your setup time around policy and identity friction, not around character counts or API call limits. The free tiers on the usage side are more forgiving than they look. The parts that will actually eat an afternoon are the ones that don't show up on a pricing page at all.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My Service Account Key Got Blocked By an Org Policy I Didn't Know Existed</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Fri, 21 Aug 2026 12:02:15 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/my-service-account-key-got-blocked-by-an-org-policy-i-didnt-know-existed-4cjl</link>
      <guid>https://dev.to/just_a_side_project/my-service-account-key-got-blocked-by-an-org-policy-i-didnt-know-existed-4cjl</guid>
      <description>&lt;p&gt;The error didn't even try to be helpful: &lt;code&gt;FAILED_PRECONDITION: Key creation is not allowed on this service account.&lt;/code&gt; No link, no suggestion, no explanation of which policy was doing this or why. I'd asked Google Cloud for a JSON key file for a brand-new service account on a brand-new project I owned outright, and it said no. This is the story of the two hours I spent trying to fight that, and the one afternoon I saved myself by giving up and doing it a different way instead.&lt;/p&gt;

&lt;h3&gt;Why I wanted a service account key in the first place&lt;/h3&gt;

&lt;p&gt;Every Google Cloud tutorial that touches server-to-server automation reaches for the same pattern: create a service account, generate a key, drop the JSON file next to your script, point &lt;code&gt;GOOGLE_APPLICATION_CREDENTIALS&lt;/code&gt; at it, done. It's the default advice for a reason -- it's non-interactive, it doesn't expire the way OAuth tokens can feel like they will, and there's no browser consent screen involved. For a script that was going to call the Text-to-Speech API on a timer with nobody watching, it looked like exactly the right tool.&lt;/p&gt;

&lt;p&gt;So I created the service account. I opened the "Keys" tab. I clicked "Add key" → "Create new key" → JSON, the same three clicks I'd done on other projects without thinking about it. And instead of a download prompt, I got that error.&lt;/p&gt;

&lt;h3&gt;The part where I assumed it was my mistake&lt;/h3&gt;

&lt;p&gt;My first instinct wasn't "this is a policy," it was "I did something wrong." I checked the IAM roles on the service account -- fine. I checked billing was actually enabled -- it was. I checked whether the API itself needed to be enabled first -- it was already on. I regenerated the service account from scratch in case the first one was somehow corrupted. Same error, verbatim, every time.

It took an embarrassingly long search before I found the actual cause: an organization policy constraint called &lt;code&gt;iam.disableServiceAccountKeyCreation&lt;/code&gt;. If your Google account sits inside a Google Workspace or Cloud org (mine did, through a domain I'd set up long before this project), that constraint is very often &lt;strong&gt;on by default&lt;/strong&gt;, inherited from the org level, and it blocks key creation across every project underneath it -- including ones you personally own and administer. You don't get an email about it. You don't see a warning when you create the project. You just hit the wall the first time you actually try to generate a key.&lt;/p&gt;

&lt;h3&gt;The two hours I don't recommend&lt;/h3&gt;

&lt;p&gt;Knowing the name of the constraint, my next move was to try to turn it off. This is the part I'd skip if I were doing it again. Changing an org policy constraint requires the &lt;code&gt;orgpolicy.policyAdmins&lt;/code&gt; role at the organization or folder level -- not the project level, no matter how much of an owner you are on the project itself. I went looking for that permission in the Google Cloud console, then in the Google Workspace admin console, then back again, trying to figure out which of my own logins was supposed to have organization-level admin rights over a domain I'd registered years earlier for an unrelated reason. I found a path that technically could have worked -- reassign myself an org policy admin role, override the constraint at the project level, generate the key, then presumably leave that override in place forever as a small permanent hole in an otherwise sane default.&lt;/p&gt;

&lt;p&gt;I got about ten minutes from actually doing that before I stopped and asked a more useful question: did I actually need a service account key, or did I need "a script that authenticates without a human present," and were those actually the same thing?&lt;/p&gt;

&lt;h3&gt;They weren't the same thing&lt;/h3&gt;

&lt;p&gt;They're not, and the gap between them is OAuth's installed-app flow. It's a pattern most people associate with interactive login -- a browser window pops up, you click "Allow," and a web app gets a token. What's less obvious is that the exact same flow works fine for a personal automation script, and it sidesteps the org policy entirely, because it authenticates &lt;em&gt;as you&lt;/em&gt;, using your own account's ordinary permissions, not as a service account subject to org-level key restrictions.&lt;/p&gt;

&lt;p&gt;The shape of it in Python is small enough that it fits in one paste:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
import pickle
from pathlib import Path

SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
TOKEN_PATH = Path("token.pickle")

def get_credentials():
    creds = None
    if TOKEN_PATH.exists():
        creds = pickle.loads(TOKEN_PATH.read_bytes())
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file("client_secret.json", SCOPES)
            creds = flow.run_local_server(port=0)
        TOKEN_PATH.write_bytes(pickle.dumps(creds))
    return creds&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You run this once, a browser tab opens, you click through your own account's consent screen, and a refresh token gets cached to disk. Every run after that is silent -- no browser, no human, the refresh token renews the access token automatically for as long as you keep using it. Functionally, for a solo automation script, this behaves exactly like the service account key I was originally trying to get: something a scheduled task can use without anyone sitting at the keyboard. It just doesn't touch the constraint that was blocking me, because it was never a service account to begin with.&lt;/p&gt;

&lt;h3&gt;What I'd tell myself before starting&lt;/h3&gt;

&lt;p&gt;The lesson isn't "OAuth is better than service accounts" in general -- for actual server-to-server systems, especially ones other people operate, service accounts with scoped IAM roles are still the right default, and disabling key creation org-wide is a genuinely reasonable security policy, not a bug. The lesson is narrower: if a script is going to run under &lt;em&gt;your own&lt;/em&gt; identity, on &lt;em&gt;your own&lt;/em&gt; machine, for &lt;em&gt;your own&lt;/em&gt; project, and you hit a wall trying to mint a service account key, check whether you actually need the service account at all before you go looking for a way around an org policy that's very likely there on purpose. The workaround that respects the policy is usually less work than the one that fights it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Silent Scheduled-Task Failure Nobody Warns You About (And How I Caught It)</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Thu, 20 Aug 2026 00:43:24 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/the-silent-scheduled-task-failure-nobody-warns-you-about-and-how-i-caught-it-1mi3</link>
      <guid>https://dev.to/just_a_side_project/the-silent-scheduled-task-failure-nobody-warns-you-about-and-how-i-caught-it-1mi3</guid>
      <description>&lt;p&gt;Last week, a blog post I had scheduled to auto-publish at 9pm simply didn't. No error in my inbox, no crash log, nothing. Windows Task Scheduler's own history said the task had run and &lt;strong&gt;succeeded&lt;/strong&gt;. It hadn't. Here's what was actually going on, because the failure mode is a lot more common than the one blog post I eventually found on it suggested.&lt;/p&gt;

&lt;h3&gt;The setup&lt;/h3&gt;

&lt;p&gt;My publishing pipeline is a Python script (&lt;code&gt;publish.py&lt;/code&gt;) wrapped in a small PowerShell script, registered as a Windows Task Scheduler job set to fire at a specific time even if the machine is asleep (&lt;code&gt;WakeToRun&lt;/code&gt;). The work PC sleeps overnight, wakes itself for the scheduled task, runs the script, goes back to sleep. That part works reliably.&lt;/p&gt;

&lt;h3&gt;Why Task Scheduler said "success" when it wasn't&lt;/h3&gt;

&lt;p&gt;The Python script failed with a DNS resolution error trying to reach &lt;code&gt;oauth2.googleapis.com&lt;/code&gt; -- the machine had woken up, but the network adapter hadn't finished reconnecting yet. That part is almost expected; waking from sleep isn't instant. The part that actually cost me a missed post is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PowerShell does not automatically propagate a wrapped native command's exit code as its own.&lt;/strong&gt; When my &lt;code&gt;.ps1&lt;/code&gt; script called &lt;code&gt;python publish.py ...&lt;/code&gt; and Python exited with a non-zero code, the PowerShell script itself still exited 0 unless I explicitly checked and re-threw that code. Task Scheduler only sees the PowerShell wrapper's exit code -- so from its point of view, the task ran cleanly. "Last Run Result: 0x0" doesn't mean the thing inside your script worked. It means your wrapper didn't crash.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Task Scheduler's report&lt;/th&gt;
&lt;th&gt;What actually happened&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Before the fix&lt;/td&gt;
&lt;td&gt;"Last Run Result: 0x0" (success)&lt;/td&gt;
&lt;td&gt;Post never went live -- DNS lookup for oauth2.googleapis.com failed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After the fix&lt;/td&gt;
&lt;td&gt;"Last Run Result: 0x0" (success)&lt;/td&gt;
&lt;td&gt;Script waits for a real connection first, then publishes correctly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;The fix&lt;/h3&gt;

&lt;p&gt;Two changes closed the gap. First, don't let the script even attempt the API call until the network is actually back:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Wait for a real network connection before doing anything else (up to 5 min)
$connected = $false
for ($i = 0; $i -lt 30; $i++) {
    if (Test-Connection -ComputerName "8.8.8.8" -Count 1 -Quiet -ErrorAction SilentlyContinue) {
        $connected = $true
        break
    }
    Start-Sleep -Seconds 10
}
if (-not $connected) {
    Add-Content -Path "$PSScriptRoot\publish_log.txt" -Value "$(Get-Date): network unavailable, publish cancelled"
    exit 1
}

python publish.py "post.html" --title "..." --publish-live *&amp;gt;&amp;gt; publish_log.txt&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Second -- and this is the one I'd skip if I were being lazy -- I now treat "Last Run Result: 0x0" as necessary but not sufficient. The wrapper script logs its own timestamped success/failure line to a text file, and that log, not the Task Scheduler history, is what I actually check.&lt;/p&gt;

&lt;h3&gt;If you're scheduling anything that wakes a sleeping machine&lt;/h3&gt;

&lt;p&gt;The general shape of this bug isn't specific to Blogger, Python, or even PowerShell -- it's "the task fired before its dependency was ready, and the wrapper swallowed the failure." Anywhere you see &lt;code&gt;WakeToRun&lt;/code&gt; or an equivalent, ask two questions: does the very first thing the script does depend on network/disk/another service being ready, and does a failure inside the wrapped process actually surface as a failure to whatever is monitoring the job? If the answer to either is "not sure," it's worth testing deliberately -- unplug the network, run the task, and see what the scheduler reports.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why I Picked Blogger Over WordPress for a Build-in-Public Blog in 2026</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Mon, 17 Aug 2026 12:37:36 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/why-i-picked-blogger-over-wordpress-for-a-build-in-public-blog-in-2026-31bj</link>
      <guid>https://dev.to/just_a_side_project/why-i-picked-blogger-over-wordpress-for-a-build-in-public-blog-in-2026-31bj</guid>
      <description>&lt;p&gt;Every "start a blog" guide defaults to WordPress, so it's worth explaining why this one runs on Blogger instead. It wasn't nostalgia — it came down to three practical factors for this specific project.&lt;/p&gt;

&lt;h3&gt;1. Zero hosting cost, permanently&lt;/h3&gt;

&lt;p&gt;WordPress.org needs hosting (a real monthly cost, even if small) or you're on WordPress.com's managed tiers, which limit plugins, ads, and themes at the free level. Blogger is hosted by Google, free, with no storage or bandwidth bill ever showing up. For a project explicitly built around a zero-budget constraint, this alone was close to decisive.&lt;/p&gt;

&lt;h3&gt;2. A working, current API&lt;/h3&gt;

&lt;p&gt;This was the bigger factor. Blogger's API v3 is REST-based, OAuth-authenticated, and — as I confirmed by actually using it — &lt;a href="https://justasideproject.blogspot.com/2026/08/the-blogger-api-is-still-alive-in-2026.html" rel="noopener noreferrer"&gt;fully functional in 2026&lt;/a&gt;. WordPress also has a REST API and it's arguably more powerful, but self-hosting it means also managing security updates, backups, and uptime — overhead a fully-automated, unattended publishing pipeline doesn't need.&lt;/p&gt;

&lt;h3&gt;3. Native Google AdSense integration&lt;/h3&gt;

&lt;p&gt;Since the whole point of this blog includes eventually running ads, being on a Google-owned platform removes a layer of setup friction — no separate ad-network plugin, no theme compatibility checks for ad placement.&lt;/p&gt;

&lt;h3&gt;Where WordPress would have won&lt;/h3&gt;

&lt;p&gt;To be fair to WordPress: it has a vastly larger plugin ecosystem, more design flexibility, and it's the better choice if you want fine-grained control over site structure, or you're planning something more complex than a straightforward blog. If this project needed custom post types, membership gating, or heavy on-page customization, I'd have made a different call.&lt;/p&gt;

&lt;h3&gt;The actual decision rule&lt;/h3&gt;

&lt;p&gt;For a simple, ad-monetized, API-driven blog with a zero-dollar budget: Blogger. For anything needing real customization, a content type WordPress specializes in (e-commerce, membership sites, complex layouts), or long-term platform independence: WordPress, hosting cost included. Neither is universally "better" — they're optimized for different constraints, and it's worth being honest about which one you actually have.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Reading the Fine Print on 'Free' AI Tools: 5 Questions to Check First</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Fri, 14 Aug 2026 12:02:53 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/reading-the-fine-print-on-free-ai-tools-5-questions-to-check-first-2oig</link>
      <guid>https://dev.to/just_a_side_project/reading-the-fine-print-on-free-ai-tools-5-questions-to-check-first-2oig</guid>
      <description>&lt;p&gt;After going through the terms of several "free" AI tools for this project, a pattern showed up enough times that it's worth writing down as a checklist. If you're evaluating any free AI tool — not just the ones I mention here — these are the five questions that actually matter, roughly in order of how often they trip people up.&lt;/p&gt;

&lt;h3&gt;1. Does it reset, or is it one-time?&lt;/h3&gt;

&lt;p&gt;"200 free credits" reads very differently depending on whether that's a monthly refill or a signup bonus you'll never see again. I've seen both marketed with nearly identical language. Always find the renewal cadence before estimating what a free tier actually gets you over a month.&lt;/p&gt;

&lt;h3&gt;2. Is there a hard cap that breaks your use case?&lt;/h3&gt;

&lt;p&gt;A generous-sounding credit allowance doesn't help if the underlying output is capped somewhere that matters — an 8-second maximum clip length, a resolution ceiling, a rate limit that throttles bursts. Check the cap against what you're actually trying to produce, not the headline number.&lt;/p&gt;

&lt;h3&gt;3. Is commercial use explicitly allowed, explicitly excluded, or just not mentioned?&lt;/h3&gt;

&lt;p&gt;These are three different situations, and "not mentioned" is the one to be most careful about — it usually doesn't mean "allowed," it means the terms haven't been tested and you're taking on the ambiguity yourself. I went looking for a clear answer on this for one particular tool and genuinely couldn't find one in the official terms, which became the reason I &lt;a href="https://justasideproject.blogspot.com/2026/08/i-tried-to-build-free-ai-shorts-channel.html" rel="noopener noreferrer"&gt;changed direction on an entire project&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;4. Does the free output carry a watermark or attribution requirement?&lt;/h3&gt;

&lt;p&gt;Fine for personal use, often a dealbreaker for anything public-facing or monetized. Worth checking before you build a workflow around the free tier, not after.&lt;/p&gt;

&lt;h3&gt;5. Are you reading the tool's actual terms, or someone's blog post about them?&lt;/h3&gt;

&lt;p&gt;This is the one that burned the most time. Several third-party "guides" to the same tool's free tier directly contradicted each other on basic facts — whether there's a watermark, what the daily limit actually is. Search results are full of this content, some of it clearly written to rank rather than to be accurate. When it matters, go to the source and check the date it was last updated.&lt;/p&gt;

&lt;h3&gt;The short version&lt;/h3&gt;

&lt;p&gt;"Free" is a marketing word. "Free tier" is a product decision with specific, checkable boundaries. The five questions above take about ten minutes to answer for any given tool, and they've saved me from building on the wrong foundation more than once.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Google's Free Tiers Compared: Cloud TTS vs. Translate vs. Flow</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Thu, 13 Aug 2026 00:52:20 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/googles-free-tiers-compared-cloud-tts-vs-translate-vs-flow-370f</link>
      <guid>https://dev.to/just_a_side_project/googles-free-tiers-compared-cloud-tts-vs-translate-vs-flow-370f</guid>
      <description>&lt;p&gt;Every Google Cloud product has a free tier. What "free tier" actually means — in generosity, in usability, in whether it's enough to run something real on — varies enormously between products. I ended up relying on three of them for this project's pipeline, so here's what each one actually gives you, not what the marketing page implies.&lt;/p&gt;

&lt;h3&gt;Cloud Text-to-Speech: genuinely generous&lt;/h3&gt;

&lt;p&gt;Standard and WaveNet voices come with 4 million free characters a month; Neural2 voices get 1 million. These limits reset monthly, not daily, and they don't require a paid upgrade to keep using indefinitely — it's a permanent free tier, separate from the one-time $300 trial credit every new account also gets. For a project generating a few thousand characters of narration a week, this tier is effectively unlimited. This is the one free tier in this list I'd call unambiguously generous.&lt;/p&gt;

&lt;h3&gt;Cloud Translation API: also generous, less commonly needed&lt;/h3&gt;

&lt;p&gt;500,000 characters a month, free, permanently. If your project needs to localize a modest amount of text, this covers it comfortably. Less central to what I was building, but worth knowing it's there.&lt;/p&gt;

&lt;h3&gt;Flow (Veo 3.1): generous-sounding, capped in ways that matter&lt;/h3&gt;

&lt;p&gt;Roughly 50 credits a day — enough for a handful of short video generations. Where this one differs from the two above: it resets daily rather than monthly (so unused credits don't bank), clips are capped at 8 seconds on the free tier, and free exports carry a visible watermark. I wrote about this in more &lt;a href="https://justasideproject.blogspot.com/2026/08/i-compared-free-tiers-of-google-flow.html" rel="noopener noreferrer"&gt;detail in an earlier post&lt;/a&gt;, including the commercial-use question that ultimately mattered more than the credit count.&lt;/p&gt;

&lt;h3&gt;The actual pattern&lt;/h3&gt;

&lt;p&gt;The products built primarily for developer infrastructure (TTS, Translation) had the most usable free tiers — large limits, permanent, no strings on commercial use. The product built around a hyped, resource-intensive generative model (Flow/Veo) had the most restricted one — smaller limits, daily resets, visible watermarking, and murkier commercial terms.&lt;/p&gt;

&lt;p&gt;That's not a coincidence, and it's probably a reasonable rule of thumb elsewhere too: the more compute-expensive and hyped a "free" AI feature is, the more likely its free tier exists mainly to get you trying the paid one.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Blogger API Is Still Alive in 2026 -- Here's Proof (and Working Code)</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Tue, 11 Aug 2026 00:29:22 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/the-blogger-api-is-still-alive-in-2026-heres-proof-and-working-code-ei8</link>
      <guid>https://dev.to/just_a_side_project/the-blogger-api-is-still-alive-in-2026-heres-proof-and-working-code-ei8</guid>
      <description>&lt;p&gt;When I went looking for a way to auto-publish blog posts without paying for anything, most of what I found online was outdated, contradictory, or both. So here's a current, first-hand data point: &lt;strong&gt;as of August 2026, the Blogger API v3 works, is actively maintained, and supports full programmatic posting&lt;/strong&gt; — creating, updating, and publishing posts and pages, all through OAuth.&lt;/p&gt;

&lt;h3&gt;Why this needed checking at all&lt;/h3&gt;

&lt;p&gt;Blogger is an old product, and Google has a well-known habit of sunsetting things. Its predecessor, the v2.0 GData API, was in fact shut down (September 2024). It's reasonable to assume the whole platform followed. It didn't — v3 is a separate, REST-based API and it's still receiving updates.&lt;/p&gt;

&lt;h3&gt;What actually works, confirmed by using it&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;posts().insert()&lt;/code&gt; — create a new post, as a draft or published directly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;posts().update()&lt;/code&gt; — edit existing post content&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;posts().publish()&lt;/code&gt; — flip a draft to live&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pages().insert()&lt;/code&gt; — create static pages (this is how I published this blog's Privacy Policy, Terms of Service, and Contact pages)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;The authentication gotcha&lt;/h3&gt;

&lt;p&gt;Service-account keys — the "just generate a key file" method that's normal for a lot of Google Cloud APIs — may be blocked by an organization policy on your Google Cloud project (mine was, by default). Blogger access is inherently tied to a personal account anyway, so the right method is OAuth: a one-time browser consent flow that hands your script a refresh token, after which it runs unattended.&lt;/p&gt;

&lt;h3&gt;Minimal working shape&lt;/h3&gt;

&lt;p&gt;In Python, that's &lt;code&gt;google-auth-oauthlib&lt;/code&gt;'s &lt;code&gt;InstalledAppFlow&lt;/code&gt; for the first login, then &lt;code&gt;googleapiclient.discovery.build("blogger", "v3", credentials=creds)&lt;/code&gt; for every call after. The whole authenticated client is maybe fifteen lines of code once you know which scope to request (&lt;code&gt;https://www.googleapis.com/auth/blogger&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;If you've been putting off a Blogger-based project because you assumed the API was dead — it isn't, and it was less work to automate than I expected going in.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Wired Up Fully-Automated Cross-Posting Between Blogger and dev.to (With Working Code)</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Sun, 09 Aug 2026 22:41:31 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/how-i-wired-up-fully-automated-cross-posting-between-blogger-and-devto-with-working-code-41ak</link>
      <guid>https://dev.to/just_a_side_project/how-i-wired-up-fully-automated-cross-posting-between-blogger-and-devto-with-working-code-41ak</guid>
      <description>&lt;p&gt;The last two posts on this blog went out through a pipeline I built specifically so I wouldn't have to manually copy-paste content between platforms. Here's the actual setup, in case you're trying to do the same thing.&lt;/p&gt;

&lt;h3&gt;The goal&lt;/h3&gt;

&lt;p&gt;One command, two platforms: publish to Blogger (where this blog actually lives) and have it show up on dev.to at the same time, without dev.to's copy counting against the original for search ranking purposes.&lt;/p&gt;

&lt;h3&gt;Piece 1: Blogger, via its own API&lt;/h3&gt;

&lt;p&gt;Blogger still has a working API (v3), authenticated through standard OAuth — no service-account keys needed, which matters if your Google Cloud project has an org policy blocking those (mine did). A one-time browser login gets you a refresh token; after that, a script can call &lt;code&gt;posts().insert()&lt;/code&gt; or &lt;code&gt;posts().update()&lt;/code&gt; and &lt;code&gt;posts().publish()&lt;/code&gt; without touching a browser again.&lt;/p&gt;

&lt;h3&gt;Piece 2: dev.to, via its API&lt;/h3&gt;

&lt;p&gt;dev.to exposes a simple REST API gated by a personal API key (generate one under Settings → Extensions). A POST to &lt;code&gt;/api/articles&lt;/code&gt; with a title, body, tags, and a &lt;code&gt;canonical_url&lt;/code&gt; field creates the post. That last field is the important one.&lt;/p&gt;

&lt;h3&gt;Why canonical_url matters&lt;/h3&gt;

&lt;p&gt;Posting the same article on two platforms verbatim is exactly the setup that can cause one copy to get buried by search engines as duplicate content — something I ran into thinking about cross-posting between other platforms for this same blog, before settling on this approach. Setting &lt;code&gt;canonical_url&lt;/code&gt; on the dev.to copy to point back at the Blogger original tells search engines "this is a copy, the real one lives here," which keeps SEO credit flowing to one place instead of splitting or confusing it.&lt;/p&gt;

&lt;h3&gt;Wiring it together&lt;/h3&gt;

&lt;p&gt;The actual glue is small: a publish script that (1) pushes content to Blogger, (2) grabs the resulting live URL, (3) immediately POSTs the same content to dev.to with that URL set as canonical. Two API calls, one command, no manual copy-paste, no risk of forgetting to update one platform after editing the other.&lt;/p&gt;

&lt;h3&gt;What I'd do differently next time&lt;/h3&gt;

&lt;p&gt;Right now the script assumes a clean HTML post every time. If you're writing in Markdown instead, dev.to wants Markdown natively (it renders raw HTML inline reasonably well, but it's not the primary format) — something to normalize if you're pulling from a Markdown-first source instead of an HTML editor like Blogger's.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Compared the Free Tiers of Google Flow, Kling AI, and Hailuo So You Don't Have To</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Tue, 04 Aug 2026 22:28:21 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/i-compared-the-free-tiers-of-google-flow-kling-ai-and-hailuo-so-you-dont-have-to-2737</link>
      <guid>https://dev.to/just_a_side_project/i-compared-the-free-tiers-of-google-flow-kling-ai-and-hailuo-so-you-dont-have-to-2737</guid>
      <description>&lt;p&gt;In my &lt;a href="https://justasideproject.blogspot.com/2026/08/i-tried-to-build-free-ai-shorts-channel.html" rel="noopener noreferrer"&gt;last post&lt;/a&gt;, I mentioned pivoting away from AI-generated video after digging into the free tiers of the big three tools. Here's the actual digging — what each one gives you for free, and where the fine print gets in the way.&lt;/p&gt;

&lt;p&gt;I'm not affiliated with any of these tools. I just wanted a straight answer to "can I use this for a monetized channel without paying," and it took longer to find than it should have.&lt;/p&gt;

&lt;h3&gt;The short version&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Free credits&lt;/th&gt;
&lt;th&gt;Renewal&lt;/th&gt;
&lt;th&gt;Max clip length (free)&lt;/th&gt;
&lt;th&gt;Watermark&lt;/th&gt;
&lt;th&gt;Commercial use on free tier&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Flow (Veo 3.1)&lt;/td&gt;
&lt;td&gt;~50&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;8 seconds&lt;/td&gt;
&lt;td&gt;"Made with Veo" visible&lt;/td&gt;
&lt;td&gt;Unclear — see below&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kling AI&lt;/td&gt;
&lt;td&gt;~66&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;~5 seconds per generation&lt;/td&gt;
&lt;td&gt;Visible&lt;/td&gt;
&lt;td&gt;Explicitly excluded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hailuo / MiniMax&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;One-time&lt;/strong&gt; (new account bonus)&lt;/td&gt;
&lt;td&gt;~6 seconds (768p)&lt;/td&gt;
&lt;td&gt;Visible&lt;/td&gt;
&lt;td&gt;Explicitly excluded&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;Google Flow (Veo 3.1)&lt;/h3&gt;

&lt;p&gt;Flow bundles Veo 3.1 (video), an image model, and a music model into one workspace. The free allotment is roughly 50 credits a day, non-cumulative — use them or lose them. At the cheaper "Lite" quality setting that's enough for a handful of generations; the higher "Quality" tier alone can cost more credits than the entire daily allowance.&lt;/p&gt;

&lt;p&gt;The catch that matters most: I could not find a clear statement, in Google's own terms, that free-tier Veo output is cleared for monetized YouTube use. Some third-party writeups say yes, some say no, and they contradict each other on basic facts like whether the watermark is even there. If you're planning to monetize, this is worth confirming directly with Google support before you build anything on top of it — not something I'd take on a blog's word, including this one.&lt;/p&gt;

&lt;h3&gt;Kling AI&lt;/h3&gt;

&lt;p&gt;Kling's free daily credit count is the most generous of the three, and the motion quality on character animation is genuinely good. But its free-tier terms are the most explicit of the group: no commercial use. That's a documented limitation, not a gray area, which actually makes it the easiest of the three to plan around — you know where you stand.&lt;/p&gt;

&lt;h3&gt;Hailuo / MiniMax&lt;/h3&gt;

&lt;p&gt;Hailuo front-loads new accounts with a decent one-time credit bonus rather than a strong daily refresh, which makes it better suited to a short burst of experimentation than ongoing daily production. Same commercial-use restriction as Kling on the free tier.&lt;/p&gt;

&lt;h3&gt;What I'd actually check before committing&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Read the tool's current terms of service yourself — not a summary of it, the actual page, dated to when you read it. These change.&lt;/li&gt;
&lt;li&gt;Search specifically for "commercial use" or "monetization" in the terms, not just "free" or "credits."&lt;/li&gt;
&lt;li&gt;If a paid tier removes the watermark and adds commercial rights, price that in before assuming the free tier is a real substitute.&lt;/li&gt;
&lt;li&gt;Treat any blog post claiming "unlimited free generation," including ones with big view counts, as marketing until you've verified it against the source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this means these tools are bad — the free tiers are still useful for experimenting and learning the workflow. It just means "free" and "free to monetize" aren't the same claim, and only one of them was easy to find a straight answer to.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Tried to Build a Free AI Shorts Channel. Here's Why I Pivoted to Writing Instead.</title>
      <dc:creator>Just a Side Project</dc:creator>
      <pubDate>Tue, 04 Aug 2026 22:28:04 +0000</pubDate>
      <link>https://dev.to/just_a_side_project/i-tried-to-build-a-free-ai-shorts-channel-heres-why-i-pivoted-to-writing-instead-1l65</link>
      <guid>https://dev.to/just_a_side_project/i-tried-to-build-a-free-ai-shorts-channel-heres-why-i-pivoted-to-writing-instead-1l65</guid>
      <description>&lt;p&gt;I wanted one thing: a fully automated, zero-cost pipeline that could turn an idea into a YouTube Short, start to finish, using nothing but free tools and an AI coding assistant. No stock footage subscriptions, no editing software, no manual screen recording. Just a script in, a video out.&lt;/p&gt;

&lt;p&gt;I got closer than I expected. Then I hit a wall that had nothing to do with code.&lt;/p&gt;

&lt;h3&gt;What actually got built&lt;/h3&gt;

&lt;p&gt;Over one long session, the pipeline came together piece by piece:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text-to-speech&lt;/strong&gt; via Google Cloud's free tier (WaveNet/Neural2 voices, a few million free characters a month — far more than a couple of Shorts a week would ever use)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visuals&lt;/strong&gt; generated entirely in code (Python + Pillow): chat-bubble mockups, file-browser mockups, "results" grids, all procedurally drawn, no stock assets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assembly&lt;/strong&gt; via ffmpeg, stitching narration, captions, and generated slides into a finished vertical video&lt;/li&gt;
&lt;li&gt;One orchestration script tying it all together, so a new video was just: drop in a script file, run one command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Along the way there were real, unglamorous obstacles — a newly-split Korean administrative district that Google's billing system didn't recognize yet, a service-account-key policy that blocked the "obvious" authentication path (fixed by switching to OAuth-based application-default credentials instead). Nothing fatal, just the normal texture of actually shipping something.&lt;/p&gt;

&lt;h3&gt;Where it got interesting&lt;/h3&gt;

&lt;p&gt;The slideshow-style visuals worked, but they looked exactly like what they were: slides. Meanwhile, a very different kind of AI content was clearly having a moment — short, photorealistic AI-generated video clips (animals doing improbable things, mostly) racking up millions of views. The tools behind them — Google's Veo (via Flow), Kling AI, Hailuo/MiniMax — all advertise usable free tiers.

&lt;/p&gt;
&lt;p&gt;So the obvious next move was: swap the static slides for actual AI-generated video clips.&lt;/p&gt;

&lt;h3&gt;Where it stalled&lt;/h3&gt;

&lt;p&gt;Checking the free tiers properly turned up real limits, not just marketing copy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free-tier clips capped at around 8 seconds&lt;/li&gt;
&lt;li&gt;A visible "Made with Veo" watermark on free exports&lt;/li&gt;
&lt;li&gt;Kling and Hailuo's free tiers explicitly exclude commercial use in their terms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The commercial-use question mattered most, since the whole point was a monetized channel. I went looking for a clear answer in the actual terms of service rather than trusting summary blog posts (several of which flatly contradicted each other on the watermark question alone). I couldn't find an unambiguous yes. Google's own policy pages didn't spell out whether free-tier output could be used in monetized YouTube content; third-party writeups disagreed with each other.

&lt;/p&gt;
&lt;p&gt;That's not a legal opinion, and I'm not a lawyer — it's just an observation: when the terms are that unclear, building a monetization plan on top of them felt like the wrong foundation, however good the free credits looked on paper.&lt;/p&gt;

&lt;h3&gt;So, this instead&lt;/h3&gt;

&lt;p&gt;Rather than keep gambling on shifting terms of service, I pivoted to writing about the build itself — which sidesteps the whole problem. It's fully original, the "content" is just documenting what actually happened, and there's no ambiguity about whether I'm allowed to publish it.&lt;/p&gt;

&lt;p&gt;The pipeline still exists and still works, free-tier TTS and all. It's just B-roll for a different kind of project now.&lt;/p&gt;

&lt;p&gt;If you're building something similar: check the actual terms before you build a business plan on a "free" AI tool, not just the blog posts telling you it's free. The credits are real. The fine print sometimes isn't what you'd hope.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
