TutuoAI

How to Add a Stripe Paywall to Your AI Agent API

You've built an AI agent that does useful work. Now you want to charge for it. This guide covers the practical architecture of adding Stripe-powered subscription billing and token-gated access to your agent's API — the same pattern we use for the TutuoAI Pro API.

The Token-Gating Pattern

Token gating is straightforward in concept: every API request includes a bearer token, your server validates the token against Stripe subscription status, and returns data only if the subscription is active and the tier permits the requested resource.

Request flow:

Client → Bearer token in Authorization header
  → Your API server
    → Look up token → find associated Stripe customer
    → Check subscription status (active? which tier?)
    → If valid: return data with tier-appropriate limits
    → If invalid: 401 Unauthorized

The key design decisions are: how you map tokens to customers, how you define tier entitlements, and how you handle subscription state changes in real time.

Step 1: Define Your Products and Prices in Stripe

Start by creating your tier structure in Stripe. A common pattern for AI agent APIs:

TierPriceRate LimitFeatures
Starter$19/mo100 req/dayCore endpoints only
Operator$49/mo1,000 req/dayAll endpoints + priority
Team$99/mo10,000 req/dayAll endpoints + team seats

In Stripe, create one Product per tier, each with a recurring Price. Store the Price IDs in your server config — you'll use them to create Checkout Sessions and validate subscriptions.

// Stripe product/price setup (one-time, via Dashboard or API)
const TIERS = {
  starter:  { priceId: 'price_1Abc...', rateLimit: 100 },
  operator: { priceId: 'price_1Def...', rateLimit: 1000 },
  team:     { priceId: 'price_1Ghi...', rateLimit: 10000 },
}

Step 2: Generate and Store API Tokens

When a customer completes checkout, generate a unique API token and associate it with their Stripe customer ID. Two common approaches:

Opaque tokens + DB lookup

Generate a random string (e.g., crypto.randomUUID()), store it in your database alongside the Stripe customer ID and tier. Every request does a DB lookup. Simple, revocable, but adds latency.

Signed JWTs with cache

Issue a JWT containing the customer ID and tier, signed with your secret. Verify locally without a DB hit. Cache subscription status with a short TTL (5 min) to handle cancellations. More complex but lower latency.

For most agent APIs (under 10K requests/day), opaque tokens with a simple key-value store (Redis or even SQLite) work fine. Optimize later.

Step 3: Build the Verification Middleware

Your API middleware extracts the token, looks up the subscription, and enforces tier limits:

// Express middleware example
async function requireSubscription(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '')
  if (!token) return res.status(401).json({ error: 'Missing API token' })

  // Look up token → customer + tier
  const sub = await db.get('SELECT * FROM tokens WHERE token = ?', token)
  if (!sub) return res.status(401).json({ error: 'Invalid token' })

  // Verify subscription is active via Stripe
  const stripeSub = await stripe.subscriptions.retrieve(sub.stripe_subscription_id)
  if (stripeSub.status !== 'active')
    return res.status(403).json({ error: 'Subscription inactive' })

  // Enforce rate limit
  const usage = await rateLimiter.check(sub.customer_id, TIERS[sub.tier].rateLimit)
  if (usage.exceeded)
    return res.status(429).json({ error: 'Rate limit exceeded', resetAt: usage.resetAt })

  req.customer = sub
  next()
}

Performance tip: Don't call Stripe on every request. Cache the subscription status locally and refresh it when you receive a webhook event (next step), or on a short interval (every 5 minutes).

Step 4: Handle Stripe Webhooks

Webhooks are how Stripe tells you about subscription changes in real time — upgrades, downgrades, cancellations, failed payments. You need to handle at minimum these events:

  • checkout.session.completed — New subscription. Generate token, store in DB, email to customer.
  • customer.subscription.updated — Tier change. Update the customer's tier and rate limits.
  • customer.subscription.deleted — Cancellation. Revoke or deactivate the token.
  • invoice.payment_failed — Payment issue. Optionally grace period, then deactivate.
// Webhook endpoint (verify signature!)
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['stripe-signature']
  const event = stripe.webhooks.constructEvent(req.body, sig, WEBHOOK_SECRET)

  switch (event.type) {
    case 'checkout.session.completed':
      // Create token, store mapping, send welcome email
      break
    case 'customer.subscription.deleted':
      // Deactivate all tokens for this customer
      break
    // ... handle other events
  }

  res.json({ received: true })
})

Critical: Always verify the webhook signature. Without verification, anyone can fake events and grant themselves access.

Step 5: Build the Checkout Flow

Use Stripe Checkout (hosted) or Payment Links for the fastest path to accepting payments. Stripe handles the entire payment UI, PCI compliance, and receipt emails:

// Create a Checkout Session
const session = await stripe.checkout.sessions.create({
  mode: 'subscription',
  line_items: [{ price: TIERS[selectedTier].priceId, quantity: 1 }],
  success_url: 'https://youragent.com/confirmed?session_id={CHECKOUT_SESSION_ID}',
  cancel_url: 'https://youragent.com/pricing',
})

// Redirect user to session.url

Your confirmation page retrieves the session, displays the API token (generated by the webhook), and shows the customer how to use it. This is the exact flow used by the TutuoAI Pro API.

Real-World Example: TutuoAI Pro API

Our Pro API uses exactly this pattern. Three subscription tiers (Starter $19, Operator $49, Team $99), each with:

  • Token-gated access to curated agent tool drops
  • Tier-based entitlements (which drops you can access)
  • Rate limiting per tier
  • Webhook-driven subscription lifecycle management
  • Hosted Stripe Checkout → confirmation page with token display

You can see it in action at /pro — the tier selection, checkout flow, and token delivery are all live.

Need this built for your agent?

Our Setup Kit includes Stripe integration, token gating, webhook handling, and subscription management — configured and verified for your specific agent setup.

Get the Setup Kit →See it in action → Pro