B2B2C Integration Guide

Enable your individual users to purchase their own Home Insight AI subscriptions through Stripe.

Overview

The B2B2C (Business-to-Business-to-Consumer) model allows real estate platforms to let their individual users purchase Home Insight AI subscriptions directly. Each external user gets:

  • Independent subscription tiers (Free Trial, Pay-per-Report, Pro, Enterprise)
  • Separate usage limits tracked per user
  • Property-based billing (unlimited documents per property)
  • Direct Stripe checkout with your platform branding

How It Works

Quick Start

1. Create Checkout Session

When a user wants to upgrade, create a Stripe checkout session:

Shell
curl -X POST https://api.homeinsight.ai/v1/external-users/checkout \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_user_id": "user_abc123",
    "tier": "pro",
    "success_url": "https://yourapp.com/success",
    "cancel_url": "https://yourapp.com/cancel",
    "customer_email": "user@example.com"
  }'

Response:

JSON
{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_...",
  "session_id": "cs_test_abc123",
  "external_user_id": "user_abc123",
  "tier": "pro"
}

2. Redirect User to Stripe

Redirect your user to the checkout_url to complete payment.

3. Handle Success/Cancel

After payment, Stripe redirects to your success_url or cancel_url:

JavaScript
// success_url handler
app.get('/success', (req, res) => {
  // Payment successful - show confirmation
  res.send('Subscription activated!');
});

// cancel_url handler
app.get('/cancel', (req, res) => {
  // User canceled - return to pricing page
  res.redirect('/pricing');
});

4. Check Subscription Status

Query the user's current subscription and usage:

Shell
curl https://api.homeinsight.ai/v1/external-users/subscription?external_user_id=user_abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

JSON
{
  "external_user_id": "user_abc123",
  "tier": "pro",
  "status": "active",
  "properties_this_month": 15,
  "properties_limit": 999999,
  "chat_messages_this_month": 327,
  "chat_messages_limit": 999999,
  "current_period_end": "2025-12-28T00:00:00Z",
  "cancel_at_period_end": false
}

Subscription Tiers

TierPriceProperties/MonthChat MessagesDocuments Per Property
Free Trial$0/month1 property50 messages10 documents
Pay-Per-Report$29/property (one-time)1 property per purchaseUnlimited for 30 days50 documents
Pro$99/monthUnlimited propertiesUnlimited75 documents
Enterprise$999/month + usageUnlimited (1,000 included, then $0.50-$0.15/report)UnlimitedUnlimited documents

Enterprise Usage Pricing:

  • Base: $999/month includes 1,000 reports
  • Reports 1,001-5,000: $0.50/report
  • Reports 5,001-10,000: $0.30/report
  • Reports 10,000+: $0.15/report

Property-Based Billing

Each unique property analyzed counts once per month. Users can upload unlimited documents for the same property:

Property: 123 Main St
  ✅ Inspection Report (counts as 1 property)
  ✅ Disclosure Document (same property, no charge)
  ✅ Loan Estimate (same property, no charge)
  ✅ Additional Photos (same property, no charge)

Property: 456 Oak Ave
  ✅ Inspection Report (counts as 2nd property)

External User ID

The external_user_id is YOUR identifier for the user:

  • Can be any string (user ID, email, UUID, etc.)
  • Must be unique within your platform
  • Used to track subscriptions and usage
  • Passed via API or X-External-User-ID header

Best Practices:

JavaScript
// ✅ GOOD: Use your internal user ID
external_user_id: user.id  // "12345"

// ✅ GOOD: Use a UUID
external_user_id: uuid.v4()  // "550e8400-e29b-41d4-a716-446655440000"

// ❌ BAD: Use email (users may change email)
external_user_id: user.email  // "user@example.com"

// ❌ BAD: Use sequential IDs (leaks user count)
external_user_id: "1", "2", "3"...

List All External Users

View all users who have subscriptions:

Shell
curl https://api.homeinsight.ai/v1/external-users?limit=50&offset=0 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

JSON
{
  "users": [
    {
      "external_user_id": "user_123",
      "tier": "pro",
      "status": "active",
      "properties_this_month": 42,
      "properties_limit": 999999,
      "chat_messages_this_month": 1245,
      "chat_messages_limit": 999999,
      "current_period_end": "2025-12-28",
      "created_at": "2025-11-15T10:30:00Z"
    }
  ],
  "total": 156,
  "active_subscriptions": 89,
  "free_tier_users": 67,
  "limit": 50,
  "offset": 0
}

Platform Identification

External user subscriptions are linked to your platform through both your API key and your user account. This design ensures:

  • Subscription persistence - Even if you delete/revoke an API key, subscription records are preserved
  • Platform attribution - We can always identify which platform a subscription belongs to
  • Usage continuity - Users don't lose access when you rotate API keys

How It Works

When an external user subscribes:

  1. Subscription is created with api_key_id linking to your API key
  2. System also stores user_id (your platform's account ID) for permanent identification
  3. If API key is later deleted:
    • api_key_id is set to NULL (not deleted)
    • user_id remains, preserving platform attribution
    • Subscription continues to work

Database Schema

SQL
external_user_subscriptions (
  id             UUID PRIMARY KEY,
  api_key_id     UUID REFERENCES api_keys(id) ON DELETE SET NULL,  -- Nullable
  user_id        UUID REFERENCES auth.users(id),                   -- Permanent
  external_user_id TEXT NOT NULL,
  tier           TEXT NOT NULL,
  stripe_customer_id TEXT,
  stripe_subscription_id TEXT,
  status         TEXT,
  ...
)

Best Practice: Key Rotation

When rotating API keys:

  1. Create new API key
  2. Update your integration to use new key
  3. Delete old API key
  4. External user subscriptions continue working (linked via user_id)

Webhooks

Home Insight AI automatically handles Stripe webhooks to update subscriptions:

  • checkout.session.completed - Activates new subscription
  • customer.subscription.updated - Updates tier/status changes
  • customer.subscription.deleted - Downgrades to free tier
  • invoice.payment_failed - Marks subscription as past_due

No action required - subscriptions update automatically.

Usage Tracking

Track which external user is making API calls using headers or form data:

Option 1: Header (Recommended)

Shell
curl -X POST https://api.homeinsight.ai/v1/analyses \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-External-User-ID: user_abc123" \
  -F "file=@inspection.pdf" \
  -F "external_property_id=prop_123"

Option 2: Form Data

Shell
curl -X POST https://api.homeinsight.ai/v1/analyses \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@inspection.pdf" \
  -F "external_user_id=user_abc123" \
  -F "external_property_id=prop_123"

Error Handling

Limit Exceeded

JSON
{
  "detail": {
    "error": "property_limit_exceeded",
    "message": "Monthly property limit reached (1 property on free trial)",
    "properties_used": 1,
    "limit": 1,
    "tier": "free_trial",
    "upgrade_url": "/v1/billing/upgrade"
  }
}

Already Subscribed

JSON
{
  "detail": "External user already has pro subscription"
}

Testing

Use Stripe test mode for development:

  1. Configure STRIPE_SECRET_KEY with sk_test_...
  2. Use test card: 4242 4242 4242 4242
  3. Any future expiry date and CVC
  4. Webhooks work in test mode

Production Checklist

Before going live:

  • [ ] Configure production Stripe API keys
  • [ ] Update Stripe price IDs in backend config
  • [ ] Set up Stripe webhook endpoint (auto-configured)
  • [ ] Test complete checkout flow
  • [ ] Verify usage limits enforce correctly
  • [ ] Add subscription management UI
  • [ ] Configure success/cancel URLs

Next Steps

Home Insight AI - Developer Portal