DEV Community

Anders Dahl Rasmussen
Anders Dahl Rasmussen

Posted on

I built HostAI in 48 hours — Cloudflare Worker + Claude AI + Stripe (full stack breakdown)

I've been building a series of AI micro-tools under the name BaseAI. The latest: HostAI, a free listing optimizer for Airbnb, Booking.com and Vrbo. Here's exactly how it's built, including the parts that surprised me.

The stack (zero monthly cost)

  • Cloudflare Workers — API, AI calls, rate limiting, Telegram cron
  • Cloudflare KV — rate limiting (5 free req/day per IP) + Pro token storage
  • Cloudflare Pages — static frontend
  • Anthropic Claude — Haiku for quick optimizations, Sonnet for full audits
  • Brevo — transactional email (300/day free tier)
  • Stripe Payment Links — no checkout page needed

Total fixed monthly cost: $0. It runs on free tiers until traffic justifies upgrading.

Rate limiting without a database

The key design decision: no user accounts, no database, no friction. Three free optimizations per day per IP, verified via KV:

async function checkRateLimit(env, ip, type) {
  const limits = { optimize: 3, 'mini-audit': 1 };
  const today = new Date().toISOString().split('T')[0];
  const key = `rate:${type}:${ip}:${today}`;
  const count = parseInt((await env.HA_RATE.get(key)) || '0');
  if (count >= limits[type]) return { allowed: false };
  await env.HA_RATE.put(key, String(count + 1), { expirationTtl: 86400 });
  return { allowed: true };
}
Enter fullscreen mode Exit fullscreen mode

KV keys auto-expire after 24h. No cleanup needed. No cron job. No database.

The Pro activation flow (no webhook needed)

Stripe webhooks are overkill for this use case. The approach: Stripe redirects to the success URL with ?session_id=cs_live_xxx. The frontend POSTs that to /activate-pro, the worker validates the cs_live_ prefix and generates a permanent token:

if (!sessionId?.startsWith('cs_live_')) return json({ error: 'Invalid session' }, 400);
const existing = await env.HA_TOKENS.get('session:' + sessionId);
if (existing) return json({ token: existing, reused: true });
const token = 'ha_pro_' + crypto.randomUUID().replace(/-/g, '');
await env.HA_TOKENS.put('session:' + sessionId, token);
await env.HA_TOKENS.put('token:' + token, JSON.stringify({ email, activated: new Date().toISOString() }));
Enter fullscreen mode Exit fullscreen mode

Idempotent — replaying the same session_id returns the same token. The user gets it by email via Brevo.

Async audit delivery via ctx.waitUntil

The full HostScan audit (10 sections, Sonnet model) takes 15-30 seconds. Too long for a synchronous response. Solution: respond immediately, run the audit in the background:

ctx.waitUntil((async () => {
  const audit = await runFullAudit(env, body);
  const html = buildAuditEmail(audit, body.title);
  await sendEmail(env, body.email, `HostScan: ${body.title}`, html);
})());
return json({ success: true, message: 'Check your email in ~15 minutes.' });
Enter fullscreen mode Exit fullscreen mode

ctx.waitUntil keeps the Worker alive after the response is sent. The user gets instant confirmation, audit arrives by email.

Telegram daily cron (passive audience building)

# wrangler.toml
[triggers]
crons = ["0 8 * * *"]
Enter fullscreen mode Exit fullscreen mode
export default {
  fetch: handleRequest,
  async scheduled(event, env, ctx) {
    ctx.waitUntil(postDailyTip(env));
  }
};
Enter fullscreen mode Exit fullscreen mode

Every morning at 08:00 UTC, one actionable Airbnb hosting tip goes out to the Telegram channel. No manual work. The channel grows while I sleep.

What surprised me

Platform-specific prompting matters more than I expected. Airbnb titles max out at 50 characters. Booking.com weights location keywords heavily. Vrbo leans toward family/group language. Giving Claude explicit platform context in the prompt increased output quality noticeably — generic prompts produce generic results.

The audit model selection is important. Using Haiku for 10-section audits produced mediocre output. Sonnet produces genuinely useful, specific recommendations. The $29 price point absorbs the extra cost easily.

Try it

HostAI — free optimizer, 3/day, no signup

HostScan — full 10-section audit, $29, delivered by email

Full codebase available — drop a comment if you want the repo link.

Top comments (0)