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.
POST /v1/billing/checkout
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tier | String | Yes | Subscription tier: "pro" or "enterprise" |
success_url | String | Yes | URL to redirect after successful payment |
cancel_url | String | Yes | URL to redirect if user cancels |
external_user_id | String | No | External user ID for B2B2C model |
Example Request
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
{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_a1...",
"session_id": "cs_test_a1F386iivKDFGljBNeU4iBmnUGGw7k0dofurJX8JLC1dZAXMo4mSi3n3aP"
}
Next steps:
- Redirect user to
checkout_url - User completes payment on Stripe-hosted page
- Stripe redirects to your
success_url - Subscription is automatically activated
Purchase Single Report
Create a one-time payment checkout for a single $29 report analysis.
POST /v1/billing/purchase-report
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
success_url | String | Yes | URL to redirect after successful payment |
cancel_url | String | Yes | URL to redirect if user cancels |
external_user_id | String | No | External user ID for B2B2C model |
Example Request
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
{
"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.
GET /v1/subscriptions
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Example Request
curl https://api.homeinsightai.com/v1/subscriptions \
-H "Authorization: Bearer hi_live_YOUR_API_KEY"
Response
{
"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 standingpast_due- Payment failed, retryingcanceled- Canceled, access ends atcurrent_period_endincomplete- Initial payment pendingtrialing- In trial period (if applicable)
Customer Portal
Create a Stripe Customer Portal session for managing subscriptions, payment methods, and billing history.
POST /v1/billing/portal
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
return_url | String | Yes | URL to return to after portal session |
Example Request
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
{
"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.
GET /v1/billing/tiers
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Example Request
curl https://api.homeinsightai.com/v1/billing/tiers \
-H "Authorization: Bearer hi_live_YOUR_API_KEY"
Response
{
"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).
POST /v1/subscriptions
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tier | String | Yes | Subscription tier: "pro" or "enterprise" |
stripe_customer_id | String | Yes | Existing Stripe Customer ID (must have payment method) |
external_user_id | String | No | External user ID for B2B2C model |
Example Request
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
{
"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.
DELETE /v1/subscriptions/:subscription_id
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Example Request
curl -X DELETE https://api.homeinsightai.com/v1/subscriptions/sub_1abc123xyz \
-H "Authorization: Bearer hi_live_YOUR_API_KEY"
Response
{
"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.
POST /v1/subscriptions/:subscription_id/reactivate
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Example Request
curl -X POST https://api.homeinsightai.com/v1/subscriptions/sub_1abc123xyz/reactivate \
-H "Authorization: Bearer hi_live_YOUR_API_KEY"
Response
{
"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).
PUT /v1/subscriptions/:subscription_id/upgrade
Request
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
new_tier | String | Yes | Target tier: "pro" or "enterprise" |
Example Request
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
{
"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
| Event | Description |
|---|---|
customer.subscription.created | New subscription created |
customer.subscription.updated | Subscription tier or status changed |
customer.subscription.deleted | Subscription canceled and ended |
invoice.payment_succeeded | Payment successful |
invoice.payment_failed | Payment failed (retry or cancel) |
checkout.session.completed | Checkout session completed successfully |
Webhook Signature Verification
Always verify webhook signatures in production:
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:
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:
// 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:
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:
{
"error": {
"code": "no_subscription",
"message": "No active subscription found. Please subscribe to a plan.",
"suggested_action": "redirect_to_pricing"
}
}
Analysis limit exceeded:
{
"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:
{
"error": {
"code": "payment_failed",
"message": "Payment could not be processed. Please update your payment method.",
"stripe_error": "Your card was declined."
}
}
Invalid tier:
{
"error": {
"code": "invalid_tier",
"message": "Invalid tier 'premium'. Valid tiers: pro, enterprise"
}
}
Credit System API (B2B2C)
The Credit System API enables B2B2C billing where you charge your end-users for document access. Home Insight AI manages the credit accounting while you handle your own pricing and customer relationships.
Get Credit Balance
Get the current credit balance for an external user.
GET /v1/credits/balance?external_user_id={user_id}
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
external_user_id | String | Yes | Your user's unique identifier |
Response:
{
"external_user_id": "user_123",
"balance": 5,
"has_unlimited": false,
"total_purchased": 10,
"total_spent": 5
}
List Credit Packs
List available credit pack options for purchase.
GET /v1/credits/packs
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Response:
[
{
"pack_type": "single",
"name": "Single Analysis",
"credits": 1,
"price_cents": 499,
"price_display": "$4.99",
"per_credit_display": "$4.99/credit"
},
{
"pack_type": "medium",
"name": "5 Credits Pack",
"credits": 5,
"price_cents": 1999,
"price_display": "$19.99",
"per_credit_display": "$3.99/credit"
},
{
"pack_type": "pro",
"name": "10 Credits Pack",
"credits": 10,
"price_cents": 2999,
"price_display": "$29.99",
"per_credit_display": "$2.99/credit"
}
]
Purchase Credits
Create a Stripe checkout session for credit pack purchase.
POST /v1/credits/purchase
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
external_user_id | String | Yes | Your user's unique identifier |
pack_type | String | Yes | single, medium, or pro |
success_url | String | Yes | URL to redirect after successful payment |
cancel_url | String | Yes | URL to redirect if user cancels |
customer_email | String | No | User's email for Stripe checkout |
Example Request:
curl -X POST https://api.homeinsightai.com/v1/credits/purchase \
-H "Authorization: Bearer hi_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_user_id": "user_123",
"pack_type": "medium",
"success_url": "https://yourapp.com/billing/success",
"cancel_url": "https://yourapp.com/billing/cancel",
"customer_email": "user@example.com"
}'
Response:
{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_a1...",
"session_id": "cs_test_a1...",
"external_user_id": "user_123",
"pack_type": "medium",
"credits": 5,
"price_cents": 1999
}
Request Document Access
Request access to documents for an external user (deducts credits).
POST /v1/credits/access
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Content-Type: application/json
X-External-User-ID: {user_id}
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
external_user_id | String | Yes | Your user's unique identifier |
analysis_ids | Array[String] | Yes | Document IDs to access |
Credit Logic:
- Pro/Enterprise users: Free access (0 credits)
- Already purchased: Free access (cached)
- New documents: 1 credit per document
Example Request:
curl -X POST https://api.homeinsightai.com/v1/credits/access \
-H "Authorization: Bearer hi_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_user_id": "user_123",
"analysis_ids": ["ana_abc123", "ana_def456"]
}'
Success Response:
{
"external_user_id": "user_123",
"accessible_documents": ["ana_abc123", "ana_def456"],
"credits_spent": 2,
"remaining_balance": 3,
"has_unlimited": false
}
Insufficient Credits Response (HTTP 402):
{
"error": "payment_required",
"message": "Need 2 credits to access 2 documents",
"credits_required": 2,
"credits_available": 0,
"credits_needed": 2,
"can_unlock": false,
"purchase_options": [...],
"subscription_option": {
"tier": "pro",
"name": "Pro Subscription",
"price_display": "$99/month",
"description": "Unlimited document analyses"
}
}
Get Purchase History
Get credit purchase history for an external user.
GET /v1/credits/history?external_user_id={user_id}&limit=50&offset=0
Headers:
Authorization: Bearer hi_live_YOUR_API_KEY
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
external_user_id | String | Yes | - | Your user's unique identifier |
limit | Integer | No | 50 | Max results to return |
offset | Integer | No | 0 | Pagination offset |
Response:
{
"external_user_id": "user_123",
"purchases": [
{
"id": "cp_123",
"pack_type": "medium",
"credits": 5,
"price_cents": 1999,
"status": "completed",
"created_at": "2024-12-27T10:30:00Z",
"completed_at": "2024-12-27T10:32:00Z"
}
],
"total_purchased": 5,
"total_spent_cents": 1999
}
Credit Pricing
| Pack Type | Credits | Price | Per Credit |
|---|---|---|---|
single | 1 | $4.99 | $4.99 |
medium | 5 | $19.99 | $3.99 |
pro | 10 | $29.99 | $2.99 |
Pro/Enterprise Subscription: Unlimited document access for $99/month (Pro) or custom pricing (Enterprise)
Pricing Summary
| Plan | Price | Analyses/Month | Chat Messages |
|---|---|---|---|
| Free Trial | $0 | 1 | 50 |
| Pay-Per-Report | $29 one-time | 1 (30 days) | Unlimited (30 days) |
| Pro | $99/month | 100 | Unlimited |
| Enterprise | $999/month | Unlimited | Unlimited |
Next Steps
- Webhooks API - Handle billing events
- B2B2C Model - White-label billing for your customers
- React SDK - Embed payment UI components