DEV Community

Cover image for What I shipped in 24 hours after my Product Hunt launch failed
The Data Nerd
The Data Nerd

Posted on • Originally published at signals.gitdealflow.com

What I shipped in 24 hours after my Product Hunt launch failed

The setup

I built GitDealFlow — a tool that tracks GitHub engineering acceleration on 4,200+ venture-backed startups and surfaces breakouts before they raise.

I scheduled a Product Hunt launch for April 26, 2026 at 07:01 UTC. The maker dashboard accepted the post. The listing appeared at producthunt.com/posts/vc-deal-flow-signal.

But the post never made it onto the daily leaderboard.

I figured this out by querying the PH GraphQL API directly:

{
  post(slug: "vc-deal-flow-signal") {
    featuredAt
    votesCount
    commentsCount
  }
}
Enter fullscreen mode Exit fullscreen mode
{
  "featuredAt": null,
  "votesCount": 0,
  "commentsCount": 1
}
Enter fullscreen mode Exit fullscreen mode

Every other product that launched at the same 07:01:00Z timestamp had featuredAt: 2026-04-26T07:01:00Z. Mine had null. The post existed but wasn't featured to PH's discovery flow.

I emailed launches@producthunt.com asking whether this was a moderation hold or an automated filter. I'm still waiting for a reply.

So at T+7 hours, when the day was clearly burned, I had a choice. Refresh the maker dashboard and spiral, or treat the day as found time and ship.

I shipped. Here's the inventory.


1. Launch banner with countdown timer (30 min)

The simplest thing on the list. A small banner across the top of the landing page showing:

PH50OFF — 50% off Insider Circle. Expires in 4d 12h.

A live countdown timer driven by the difference between Date.now() and a hardcoded expiry. CSS does the rest.

Why this matters: scarcity copy lifts conversion on visitor-to-trial paths by ~10-30% in most A/B tests I've read. I'd known this for months and never built it. The PH-failure focus made me actually do it.

Stack: React, no library.

function LaunchBanner({ expiry }: { expiry: Date }) {
  const [now, setNow] = useState(Date.now());
  useEffect(() => {
    const t = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(t);
  }, []);
  const ms = Math.max(0, expiry.getTime() - now);
  const days = Math.floor(ms / 86_400_000);
  const hours = Math.floor((ms % 86_400_000) / 3_600_000);
  return (
    <div className="bg-amber-500/10 px-4 py-2 text-center text-sm">
      PH50OFF — 50% off Insider Circle. Expires in {days}d {hours}h.
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

2. 10 new pSEO pages for AI agent frameworks (90 min)

Each page targets a long-tail query like "use CrewAI with GitDealFlow MCP" and contains:

  • 3-step install with copy-pasteable code
  • One worked example (research a startup, return GitHub signal)
  • Link out to the framework's docs
  • CTA to the free predict tool

The 10 frameworks: CrewAI, Mastra, Pydantic AI, Continue, Cline, Aider, Inngest, n8n, Zapier, Autogen. Combined with 5 from earlier in the week, that's 15 of a planned 20.

Indexation lag means this isn't Monday traffic. It's June traffic. But it costs almost nothing once you have the template, and these pages compound forever.

I won't paste the template here because it's pretty boring (generateStaticParams + static MDX). The interesting part is choosing the integration list — pick frameworks that have real adoption (>10k GitHub stars or VC backing), not "comprehensive coverage." Long tail is for traffic, not completionism.


3. HMAC-signed share token endpoint (45 min)

Probably the highest-leverage thing I shipped. Most viral-loop tutorials skip this step.

The setup: when a scout shares their Scout Score from /receipts, the share URL goes through /share/[token] first. The recipient lands on a "[someone in your network] just shared their score with you — here's your 7-day extended preview" page and gets a cookie that unlocks deeper content.

Both ends get value:

  • The sharer feels good (their score sent value to a friend)
  • The recipient gets a thing (the unlock + cookie)
  • The platform gets distribution (the cookie correlates with much higher conversion later)

Greg Isenberg writes about this as "every share needs to be useful to the recipient." If the share is just "look at my score," it dies. If the share unlocks something for the recipient, it spreads.

The HMAC bit:

import { createHmac, timingSafeEqual } from "crypto";

const SECRET = process.env.SHARE_TOKEN_SECRET!;

export interface SharePayload {
  s: string;        // sharer handle
  e: number;        // expiration unix-ms
  k: string;        // kind: signal-card, scout, predict
}

export function generateShareToken(sharer: string, kind: string, daysValid = 7): string {
  const payload = { s: sharer, e: Date.now() + daysValid * 86_400_000, k: kind };
  const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
  const sig = createHmac("sha256", SECRET).update(body).digest("hex");
  return `${body}.${sig}`;
}

export function verifyShareToken(token: string): SharePayload | null {
  const [body, sig] = token.split(".");
  if (!body || !sig) return null;
  const expected = createHmac("sha256", SECRET).update(body).digest("hex");
  if (!timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(sig, "hex"))) return null;
  const payload = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
  if (payload.e < Date.now()) return null;
  return payload;
}
Enter fullscreen mode Exit fullscreen mode

Tokens are unforgeable, time-bound, and embed the sharer identity for analytics later.


4. Cursor collaboration recipe blog post (2 hr)

Cursor has 500k+ developers. My MCP server gives any AI assistant access to GitHub momentum data. Combining the two lets a Cursor user say "research this startup as a deal-flow agent would" and get back a structured signal.

Wrote a long-form blog post with full setup, the MCP config block, and 4 example prompts that surface real differentiation:

  1. "What's the contributor velocity trend on Vercel over the last 90 days?"
  2. "Find OSS projects that match Cline's growth pattern from 6 months ago."
  3. "Score this GitHub URL: github.com/"
  4. "List 5 startups that crossed 10k stars in the last 30 days."

Held the cold-outreach email to the Cursor team until my domain warmup completes (~10 days from now), but the post is live and the recipe is reproducible.


5. A2A (Agent-to-Agent) launch-status skill (1 hr)

This one's a little inside-baseball. The Agent2Agent (A2A) protocol lets external AI agents call my server and ask for structured info via JSON-RPC. I'd shipped a launch-status skill that returned "we're live on Product Hunt today!" as part of the launch-day push.

After PH didn't feature, that response became false.

I had two choices: kill the skill (lose the agent-discoverability), or harden it to return calibrated state. I chose the second.

The hardened endpoint:

  • Fetches PH GraphQL for the post's featuredAt
  • Sets active: true only when featuredAt is non-null
  • Returns state: "scheduled-pending-feature" honestly when it's not
  • Caches with stale: true if the GraphQL call rate-limits
  • Auto-flips when PH eventually features (if they do)

Plot twist: the calibrated-honesty version is a STRONGER demo than the original "we're live!" angle. AI agents downstream are graded on calibration. Cherry-picked claims would have leaked into a downstream agent's reasoning and hurt its accuracy. Honest state is robust.

If you're building agent-discoverable APIs, never return cherry-picked positives. Build for calibration from day one.


6. OG launch card template (90 min)

@vercel/og template that auto-renders a 1200x630 PNG with the launch countdown, baked in. When anyone tweets a GitDealFlow link, the tweet preview shows a branded card with the live countdown — no manual sharing flow needed.

This builds an OG-image library I can reuse for every future launch (Q3 paid plan launch, MCP v2 launch, etc.).

Cost is dominated by font choice and copy iteration, not by code. The template itself is ~80 lines.


What this cost in total

  • Total focused ship time: ~7 hours
  • Total dollars: $0
  • Total PH-launch traffic: effectively zero (the failure case)
  • Total compounding marketing surface added: 6 ships that all work tomorrow

Product Hunt was a single-day window. These six ships compound forever.


What I learned

Every founder I know waits for one big launch event. PH. HN front page. Press hit. Then if it doesn't pop, the rest of the quarter feels heavier.

The hidden lesson, which I half-knew but didn't act on until yesterday: if you ship 6 small things instead of staking your week on one launch event, you don't need the launch event. You ARE the launch event, every day.

This isn't original. It's just what the math shows when you compare 1 day of attention to 6 always-on assets.

The PH-launch failure was, in retrospect, the unlock.

If you're building something and you're stuck waiting for an event, my honest tactical advice: pick 6 things, give yourself a 24-hour shot clock, and ship.


Resources

Drop a comment if you've ever had a launch event that didn't pop. What did you ship instead?

@The_Data_Nerd

Top comments (0)