Billing API

The Billing API provides Stripe-powered subscription management and one-time payment processing. All endpoints handle checkout sessions, customer portals, and subscription lifecycle management.

Create Checkout Session

Create a Stripe Checkout session for Pro or Enterprise subscription plans.

HTTP
POST /v1/billing/checkout

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json

Body Parameters:

ParameterTypeRequiredDescription
tierStringYesSubscription tier: "pro" or "enterprise"
success_urlStringYesURL to redirect after successful payment
cancel_urlStringYesURL to redirect if user cancels
external_user_idStringNoExternal user ID for B2B2C model

Example Request

Shell
curl -X POST https://api.homeinsightai.com/v1/billing/checkout \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tier": "pro",
    "success_url": "https://yourapp.com/billing/success",
    "cancel_url": "https://yourapp.com/billing/cancel"
  }'

Response

JSON
{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_test_a1...",
  "session_id": "cs_test_a1F386iivKDFGljBNeU4iBmnUGGw7k0dofurJX8JLC1dZAXMo4mSi3n3aP"
}

Next steps:

  1. Redirect user to checkout_url
  2. User completes payment on Stripe-hosted page
  3. Stripe redirects to your success_url
  4. Subscription is automatically activated

Purchase Single Report

Create a one-time payment checkout for a single $29 report analysis.

HTTP
POST /v1/billing/purchase-report

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json

Body Parameters:

ParameterTypeRequiredDescription
success_urlStringYesURL to redirect after successful payment
cancel_urlStringYesURL to redirect if user cancels
external_user_idStringNoExternal user ID for B2B2C model

Example Request

Shell
curl -X POST https://api.homeinsightai.com/v1/billing/purchase-report \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "success_url": "https://yourapp.com/report/success",
    "cancel_url": "https://yourapp.com/pricing"
  }'

Response

JSON
{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_test_b2...",
  "session_id": "cs_test_b2G497jjwLEHImoCPfV5jCnoVHHx8l1epgvsKY9NMD2eAYNPp5nTj4o4bQ"
}

What you get:

  • 1 analysis credit added to your account
  • Valid for 30 days
  • Unlimited chat messages for that analysis

Get Subscription Status

Retrieve current subscription status for the authenticated API key.

HTTP
GET /v1/subscriptions

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY

Example Request

Shell
curl https://api.homeinsightai.com/v1/subscriptions \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

Response

JSON
{
  "subscription_id": "sub_1abc123xyz",
  "status": "active",
  "tier": "pro",
  "current_period_start": "2025-11-01T00:00:00Z",
  "current_period_end": "2025-12-01T00:00:00Z",
  "cancel_at_period_end": false,
  "analyses_used": 8,
  "analyses_limit": 100,
  "created_at": "2025-11-01T00:00:00Z",
  "stripe_customer_id": "cus_abc123xyz"
}

Possible statuses:

  • active - Subscription is active and in good standing
  • past_due - Payment failed, retrying
  • canceled - Canceled, access ends at current_period_end
  • incomplete - Initial payment pending
  • trialing - In trial period (if applicable)

Customer Portal

Create a Stripe Customer Portal session for managing subscriptions, payment methods, and billing history.

HTTP
POST /v1/billing/portal

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json

Body Parameters:

ParameterTypeRequiredDescription
return_urlStringYesURL to return to after portal session

Example Request

Shell
curl -X POST https://api.homeinsightai.com/v1/billing/portal \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "return_url": "https://yourapp.com/settings/billing"
  }'

Response

JSON
{
  "portal_url": "https://billing.stripe.com/p/session/test_abc123..."
}

Portal features:

  • Update payment method
  • View billing history and invoices
  • Cancel or reactivate subscription
  • Download receipts
  • Update billing email

Get Available Tiers

Retrieve all available subscription tiers with pricing information.

HTTP
GET /v1/billing/tiers

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY

Example Request

Shell
curl https://api.homeinsightai.com/v1/billing/tiers \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

Response

JSON
{
  "tiers": [
    {
      "id": "free",
      "name": "Free Trial",
      "price": 0,
      "currency": "USD",
      "interval": "month",
      "features": [
        "1 analysis per month",
        "50 chat messages",
        "Basic support"
      ],
      "analyses_limit": 1
    },
    {
      "id": "pro",
      "name": "Pro",
      "price": 99,
      "currency": "USD",
      "interval": "month",
      "features": [
        "100 analyses per month",
        "Unlimited chat messages",
        "Priority support",
        "White-label widget",
        "Advanced cost estimates"
      ],
      "analyses_limit": 100,
      "stripe_price_id": "price_1SZPUkR9pxNkCCCYoc4jXp56"
    },
    {
      "id": "enterprise",
      "name": "Enterprise",
      "price": 999,
      "currency": "USD",
      "interval": "month",
      "features": [
        "Unlimited analyses",
        "Unlimited chat messages",
        "Dedicated support",
        "Custom integrations",
        "SLA guarantee",
        "On-premise deployment option"
      ],
      "analyses_limit": null,
      "stripe_price_id": "price_1SZPVCR9pxNkCCCYbRqZFp52"
    }
  ]
}

Create Subscription (Server-Side)

Create a subscription directly without checkout page (requires Stripe Customer ID).

HTTP
POST /v1/subscriptions

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json

Body Parameters:

ParameterTypeRequiredDescription
tierStringYesSubscription tier: "pro" or "enterprise"
stripe_customer_idStringYesExisting Stripe Customer ID (must have payment method)
external_user_idStringNoExternal user ID for B2B2C model

Example Request

Shell
curl -X POST https://api.homeinsightai.com/v1/subscriptions \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tier": "pro",
    "stripe_customer_id": "cus_abc123xyz"
  }'

Response

JSON
{
  "subscription_id": "sub_1abc123xyz",
  "status": "active",
  "tier": "pro",
  "current_period_start": "2025-11-27T12:00:00Z",
  "current_period_end": "2025-12-27T12:00:00Z",
  "stripe_subscription_id": "sub_1abc123xyz"
}

Cancel Subscription

Cancel a subscription at the end of the current billing period.

HTTP
DELETE /v1/subscriptions/:subscription_id

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY

Example Request

Shell
curl -X DELETE https://api.homeinsightai.com/v1/subscriptions/sub_1abc123xyz \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

Response

JSON
{
  "subscription_id": "sub_1abc123xyz",
  "status": "active",
  "cancel_at_period_end": true,
  "current_period_end": "2025-12-01T00:00:00Z",
  "message": "Subscription will be canceled on 2025-12-01T00:00:00Z"
}

Note: Access continues until current_period_end. No refunds for partial months.


Reactivate Subscription

Reactivate a canceled subscription before the end of the current period.

HTTP
POST /v1/subscriptions/:subscription_id/reactivate

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY

Example Request

Shell
curl -X POST https://api.homeinsightai.com/v1/subscriptions/sub_1abc123xyz/reactivate \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

Response

JSON
{
  "subscription_id": "sub_1abc123xyz",
  "status": "active",
  "cancel_at_period_end": false,
  "current_period_end": "2025-12-01T00:00:00Z",
  "message": "Subscription reactivated successfully"
}

Upgrade/Downgrade Subscription

Change subscription tier (prorated billing applies).

HTTP
PUT /v1/subscriptions/:subscription_id/upgrade

Request

Headers:

Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json

Body Parameters:

ParameterTypeRequiredDescription
new_tierStringYesTarget tier: "pro" or "enterprise"

Example Request

Shell
curl -X PUT https://api.homeinsightai.com/v1/subscriptions/sub_1abc123xyz/upgrade \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "new_tier": "enterprise"
  }'

Response

JSON
{
  "subscription_id": "sub_1abc123xyz",
  "status": "active",
  "tier": "enterprise",
  "previous_tier": "pro",
  "proration_amount": 900,
  "proration_currency": "USD",
  "current_period_end": "2025-12-01T00:00:00Z",
  "message": "Subscription upgraded to enterprise. Prorated amount: $900.00"
}

Proration:

  • Upgrade: Immediate charge for prorated difference
  • Downgrade: Credit applied to next invoice

Webhook Events

Subscribe to Stripe webhooks to receive real-time billing events:

Endpoint: POST /v1/webhooks/stripe

Supported Events

EventDescription
customer.subscription.createdNew subscription created
customer.subscription.updatedSubscription tier or status changed
customer.subscription.deletedSubscription canceled and ended
invoice.payment_succeededPayment successful
invoice.payment_failedPayment failed (retry or cancel)
checkout.session.completedCheckout session completed successfully

Webhook Signature Verification

Always verify webhook signatures in production:

Python
import stripe

# Your webhook secret from Stripe Dashboard
webhook_secret = "whsec_..."

# Verify signature
stripe.Webhook.construct_event(
    payload=request.body,
    sig_header=request.headers["Stripe-Signature"],
    secret=webhook_secret
)

See Webhooks documentation for full implementation guide.


Best Practices

1. Handle Checkout Redirects

After creating a checkout session, immediately redirect the user:

JavaScript
const response = await fetch('/v1/billing/checkout', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer hi_live_YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    tier: 'pro',
    success_url: window.location.origin + '/billing/success',
    cancel_url: window.location.origin + '/pricing'
  })
})

const { checkout_url } = await response.json()
window.location.href = checkout_url  // Redirect immediately

2. Check Subscription Status Before API Calls

Cache subscription status to avoid rate limits:

JavaScript
// Cache for 5 minutes
const cachedStatus = localStorage.getItem('subscription_status')
const cacheTime = localStorage.getItem('subscription_cache_time')

if (!cachedStatus || Date.now() - cacheTime > 300000) {
  const response = await fetch('/v1/subscriptions', {
    headers: { 'Authorization': 'Bearer hi_live_YOUR_API_KEY' }
  })
  const status = await response.json()

  localStorage.setItem('subscription_status', JSON.stringify(status))
  localStorage.setItem('subscription_cache_time', Date.now())
}

3. Handle Failed Payments

Display clear messaging for past_due status:

JavaScript
if (subscription.status === 'past_due') {
  showAlert('Your payment failed. Please update your payment method.')
  redirectToPortal()
}

4. Test with Stripe Test Mode

Use Stripe test cards for development:

Successful payment: 4242 4242 4242 4242
Failed payment:     4000 0000 0000 0002
Requires 3DS:       4000 0025 0000 3155

Error Handling

Common Errors

No active subscription:

JSON
{
  "error": {
    "code": "no_subscription",
    "message": "No active subscription found. Please subscribe to a plan.",
    "suggested_action": "redirect_to_pricing"
  }
}

Analysis limit exceeded:

JSON
{
  "error": {
    "code": "limit_exceeded",
    "message": "Monthly analysis limit reached (100/100). Upgrade to Enterprise for unlimited analyses.",
    "analyses_used": 100,
    "analyses_limit": 100,
    "suggested_action": "upgrade_tier"
  }
}

Payment failed:

JSON
{
  "error": {
    "code": "payment_failed",
    "message": "Payment could not be processed. Please update your payment method.",
    "stripe_error": "Your card was declined."
  }
}

Invalid tier:

JSON
{
  "error": {
    "code": "invalid_tier",
    "message": "Invalid tier 'premium'. Valid tiers: pro, enterprise"
  }
}

Pricing Summary

PlanPriceAnalyses/MonthChat Messages
Free Trial$0150
Pay-Per-Report$29 one-time1 (30 days)Unlimited (30 days)
Pro$99/month100Unlimited
Enterprise$999/monthUnlimitedUnlimited

Next Steps

Billing API - Home Insight AI Documentation