<?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>Forem: Muhammad Zuhrul Umam</title>
    <description>The latest articles on Forem by Muhammad Zuhrul Umam (@zuhrulumam).</description>
    <link>https://forem.com/zuhrulumam</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3656464%2F73391403-1a39-42c5-a3aa-370d16b87fc4.jpeg</url>
      <title>Forem: Muhammad Zuhrul Umam</title>
      <link>https://forem.com/zuhrulumam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/zuhrulumam"/>
    <language>en</language>
    <item>
      <title>I Built a QR Code API in Go - Here's What I Learned in One Week</title>
      <dc:creator>Muhammad Zuhrul Umam</dc:creator>
      <pubDate>Thu, 11 Dec 2025 03:58:00 +0000</pubDate>
      <link>https://forem.com/zuhrulumam/i-built-a-qr-code-api-in-go-heres-what-i-learned-in-one-week-5b87</link>
      <guid>https://forem.com/zuhrulumam/i-built-a-qr-code-api-in-go-heres-what-i-learned-in-one-week-5b87</guid>
      <description>&lt;p&gt;The Setup: Father of 2, Go developer in Indonesia, 6 months runway, $63 budget. The mission: validate 1 of 20 researched micro-SaaS ideas before my savings run out.&lt;/p&gt;

&lt;p&gt;I chose the QR Code API. Not because it's sexy—because the numbers made sense.&lt;br&gt;
The Research That Led Me Here&lt;br&gt;
I spent 2 weeks analyzing exit data from Acquire.com, scraping RapidAPI marketplace pricing, and reading IndieHackers revenue posts. QR Code APIs showed:&lt;/p&gt;

&lt;p&gt;Competitors charging $5-30/month with active subscribers&lt;br&gt;
Post-COVID adoption created permanent demand (contactless payments, digital menus)&lt;br&gt;
Simple tech = low maintenance (critical with 2 kids)&lt;br&gt;
The QR standard hasn't changed since 2015 (zero breaking changes)&lt;/p&gt;

&lt;p&gt;The market exists. The question: Can I capture any of it?&lt;br&gt;
Why Speed Mattered More Than Features&lt;br&gt;
My biggest risk isn't building the wrong features—it's running out of time building features nobody wants.&lt;br&gt;
The bet: Ship a working API in 1 week. Free during beta. If 10+ people sign up asking about paid tiers, I build more features. If not, I pivot to idea #2 (Markdown to PDF API) using the same infrastructure.&lt;br&gt;
Day 1-2: Building the Core&lt;br&gt;
I picked Go because that's what I know. AWS Lambda because the free tier is permanent (1M requests/month forever). The actual QR generation library did the heavy lifting—I just needed to wrap it properly.&lt;br&gt;
The hardest part wasn't the code. It was resisting the urge to add "just one more feature."&lt;br&gt;
Every time I thought "I should add SVG support":&lt;/p&gt;

&lt;p&gt;That's 6 more hours&lt;br&gt;
Nobody asked for it yet&lt;br&gt;
I can add it in week 2 if demand proves it&lt;/p&gt;

&lt;p&gt;Ship the minimal version. Validate first. Perfectionism kills indie projects.&lt;br&gt;
Day 3: The 4-Hour CORS Detour&lt;br&gt;
Everything worked via curl. Then I tried calling it from my frontend and hit the dreaded CORS error.&lt;br&gt;
Turns out I had CORS headers in THREE places:&lt;/p&gt;

&lt;p&gt;My Lambda function&lt;br&gt;
API Gateway configuration&lt;br&gt;
CloudFlare Worker proxy&lt;/p&gt;

&lt;p&gt;Each one added Access-Control-Allow-Origin: *. Browsers saw *, * and rejected it. Duplicate headers = fail.&lt;br&gt;
The fix: Remove CORS from Lambda and API Gateway. Let CloudFlare Worker handle it once. One source of truth.&lt;br&gt;
The lesson: Distributed systems multiply your debugging surface area. When something breaks, you're hunting across multiple services.&lt;br&gt;
Day 4-5: Protection and Testing&lt;br&gt;
Free API = abuse magnet. I needed protection without friction.&lt;br&gt;
Set up API Gateway throttling:&lt;/p&gt;

&lt;p&gt;10 requests/second max&lt;br&gt;
50,000/day limit&lt;br&gt;
CloudWatch alarm emails me at 50K&lt;/p&gt;

&lt;p&gt;The math: 50K/day × 30 = 1.5M/month. My free tier is 1M. The alarm fires before I get charged.&lt;br&gt;
For testing, I skipped mocking AWS locally (too complex). Wrote simple table-driven tests that run in 50ms. Fast feedback &amp;gt; perfect simulation.&lt;br&gt;
Day 6-7: Landing Page and Launch Prep&lt;br&gt;
Built the landing page with plain HTML and Tailwind. No React, no build step, no complexity. The live demo calls the actual API client-side so people can test it instantly.&lt;br&gt;
Pricing decision: I almost listed $9 and $29/month tiers. Then I realized—I'm selling features I haven't built yet. SVG export? Not implemented. Logo embedding? Doesn't exist.&lt;br&gt;
Pivot to honesty: Free during beta. Unlimited. Email capture for "notify me when paid tiers launch."&lt;br&gt;
If people don't even use it free, they won't pay for it.&lt;br&gt;
The Economics That Make This Possible&lt;/p&gt;

&lt;p&gt;AWS Lambda: $0 (1M free requests/month, permanent)&lt;br&gt;
API Gateway: $0 (1M free requests/month, permanent)&lt;br&gt;
CloudFlare Worker: $0 (100K requests/day free)&lt;br&gt;
Route53: $0.50/month (only real cost)&lt;/p&gt;

&lt;p&gt;Total: $0.50/month&lt;br&gt;
Response times: 50-150ms globally.&lt;br&gt;
I can validate this idea for the cost of a coffee. That's the power of serverless for bootstrappers.&lt;br&gt;
What I Got Wrong&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CORS strategy
Should have decided upfront which layer handles it. Cost me 4 hours of debugging.&lt;/li&gt;
&lt;li&gt;Analytics
Launched without usage tracking. Now I have no idea who's testing it until they email.&lt;/li&gt;
&lt;li&gt;Overthinking features
Almost delayed launch to add SVG support. Caught myself, shipped anyway.
The Validation Framework
Week 1-2: Watch these signals
Good signs:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;10+ email signups&lt;br&gt;
People asking "when can I pay?"&lt;br&gt;
Feature requests in emails&lt;br&gt;
Actual API usage (CloudWatch shows calls)&lt;/p&gt;

&lt;p&gt;Bad signs:&lt;/p&gt;

&lt;p&gt;&amp;lt;3 signups after posting on 3 platforms&lt;br&gt;
Zero API calls (people don't even test it)&lt;br&gt;
"I'll just use the free alternatives"&lt;/p&gt;

&lt;p&gt;Week 3: Decision point&lt;/p&gt;

&lt;p&gt;Strong demand → Build SVG, logos, analytics, launch paid tiers&lt;br&gt;
Weak demand → Pivot to idea #2, reuse infrastructure&lt;/p&gt;

&lt;p&gt;What Happens If This Fails?&lt;br&gt;
I'm not starting from zero. The infrastructure is reusable:&lt;/p&gt;

&lt;p&gt;Lambda setup works for any API&lt;br&gt;
Landing page template ready&lt;br&gt;
Stripe integration (if I build it)&lt;br&gt;
Marketing channels (Product Hunt profile, Dev.to followers)&lt;/p&gt;

&lt;p&gt;Time to pivot: 1 week (just swap the API logic)&lt;br&gt;
From QR generation to Markdown→PDF conversion? Change 100 lines of Go. Everything else stays.&lt;br&gt;
I have runway for 4-5 validation attempts. This is attempt #1.&lt;br&gt;
Current Status&lt;br&gt;
✅ Live: healnify.com&lt;br&gt;
✅ Free: Unlimited during beta&lt;br&gt;
✅ Working: 50ms response times&lt;br&gt;
⏳ Validating: Waiting for demand signals&lt;br&gt;
Try it:&lt;br&gt;
POST &lt;a href="https://qrcodeapi.healnify.com/generate" rel="noopener noreferrer"&gt;https://qrcodeapi.healnify.com/generate&lt;/a&gt;&lt;br&gt;
{"url": "&lt;a href="https://example.com" rel="noopener noreferrer"&gt;https://example.com&lt;/a&gt;", "size": 512}&lt;br&gt;
Returns base64-encoded PNG.&lt;br&gt;
The Real Lesson&lt;br&gt;
Perfect code doesn't matter if nobody wants the product.&lt;br&gt;
I could spend 2 more weeks adding:&lt;/p&gt;

&lt;p&gt;SVG and PDF export&lt;br&gt;
Logo embedding with transparency&lt;br&gt;
Gradient backgrounds&lt;br&gt;
Analytics dashboard&lt;br&gt;
Dynamic QR with tracking&lt;/p&gt;

&lt;p&gt;Or I can spend 2 weeks learning if anyone cares.&lt;br&gt;
I chose validation over perfection.&lt;br&gt;
Next 2 weeks: Marketing push (Product Hunt, Dev.to, Reddit). Track signups and usage. Make the pivot decision at week 3.&lt;/p&gt;

&lt;p&gt;Following along? I'm building in public on Twitter/X and LinkedIn. Sharing real metrics, not vanity numbers.&lt;br&gt;
Questions about:&lt;/p&gt;

&lt;p&gt;The validation framework?&lt;br&gt;
AWS free tier limits?&lt;br&gt;
Why I'm risking 6 months on this?&lt;/p&gt;

&lt;p&gt;Drop them below. I'll answer everything.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>startup</category>
      <category>go</category>
      <category>api</category>
    </item>
  </channel>
</rss>
