Billing & Subscriptions
Overview
AppVector uses a comprehensive billing system with subscription plans, credit-based usage tracking, and flexible payment options. Each workspace has one subscription that determines its features, limits, and available credits.
Key Components: - Dynamic Feature System: Flexible feature management without code changes - Credit System: Track and limit API calls, data scrapes, and other usage - Subscription Plans: Tiered pricing with different feature sets - Stripe Integration: Secure payment processing via hosted pages
For detailed credit system documentation, see Credits Documentation.
Payment Flow with Stripe Hosted
Architecture
All payments are processed through Stripe's hosted pages - no card details touch our servers. Users are redirected to Stripe for payment, then return to your app.
User Journey & API Order
1. User Browses Plans → GET /api/billing/plans/
Lists all available subscription plans (FREE, STARTER, PRO, ENTERPRISE).
2. User Clicks "Subscribe" → POST /api/billing/stripe/checkout/
Creates Stripe Checkout Session, returns URL to redirect user to Stripe's payment page.
When to use: User wants to subscribe to a new plan or upgrade existing subscription.
What happens next: User enters card on Stripe → Payment processed → Webhook updates subscription → User returns to your app.
3. User Clicks "Manage Billing" → GET /api/billing/stripe/portal/
Opens Stripe Customer Portal where users self-manage: payment methods, subscriptions, invoices, cancellations.
When to use: User needs to update card, cancel subscription, view invoices, or change plans.
What happens next: User makes changes on Stripe → Webhooks sync changes → User returns to your app.
4. App Shows Current Subscription → GET /api/billing/subscription/
Returns workspace's current plan, status, renewal date, and trial info.
When to use: Display subscription details on billing settings page.
5. App Shows Usage & Limits → GET /api/billing/features/workspace/
Returns all features with current usage (projects: 3/10, credits: 1234/5000).
When to use: Show usage dashboard or "upgrade" prompts when nearing limits.
6. User Buys Credits → POST /api/billing/stripe/checkout/credits/
Creates Checkout Session for one-time credit purchase (doesn't affect subscription).
When to use: User runs out of monthly credits and needs more immediately.
7. App Shows Payment History → GET /api/billing/stripe/payment-history/
Fetches invoices from Stripe with PDF download links (not stored in our database).
When to use: User wants to view past payments and download invoices.
8. App Shows Next Bill → GET /api/billing/stripe/upcoming-invoice/
Preview of next billing charge with amount and date.
When to use: Show "Your next bill: $149 on Jan 15" message.
9. Stripe Sends Events → POST /api/billing/webhooks/stripe/ (automatic)
Stripe webhooks keep database synced: payment succeeded, subscription cancelled, etc.
When to use: Automatic - no frontend call needed. Stripe calls this when events happen.
API Quick Reference
| Endpoint | Method | Use When | Returns |
|---|---|---|---|
/api/billing/plans/ |
GET | Showing plan options | List of plans with prices/features |
/api/billing/stripe/checkout/ |
POST | User clicks "Subscribe" button | Stripe checkout URL to redirect to |
/api/billing/stripe/checkout/credits/ |
POST | User clicks "Buy Credits" | Stripe checkout URL for credits |
/api/billing/stripe/portal/ |
GET | User clicks "Manage Billing" | Stripe portal URL for self-service |
/api/billing/subscription/ |
GET | Showing current plan | Current subscription details |
/api/billing/features/workspace/ |
GET | Showing usage dashboard | All features with usage counts |
/api/billing/stripe/payment-history/ |
GET | Showing invoices page | List of past invoices with PDFs |
/api/billing/stripe/upcoming-invoice/ |
GET | Showing next bill | Amount and date of next charge |
/api/billing/credits/ |
GET | Showing credit balance | Available credits by type |
/api/billing/limits/ |
GET | Checking if action allowed | Current limits vs usage |
/api/billing/features/check/ |
GET | Before feature access | Whether feature is available |
/api/billing/features/consume/ |
POST | After API operation | Consumes credits, returns remaining |
Typical Flow Examples
New User Subscribing:
1. GET /api/billing/plans/ → Show plans
2. POST /api/billing/stripe/checkout/ → Create checkout session
3. Redirect to checkout_url → User pays on Stripe
4. Webhook updates database → Subscription becomes ACTIVE
5. GET /api/billing/subscription/ → Confirm activation
Existing User Managing Billing:
1. GET /api/billing/subscription/ → Show current plan
2. GET /api/billing/stripe/portal/ → Get portal URL
3. Redirect to portal_url → User updates card/cancels/etc
4. Webhooks sync changes → Database updated
5. User returns to app
User Checking Usage:
1. GET /api/billing/features/workspace/ → Get all feature usage
2. Display: "Projects: 3/10 (70% available)"
3. Display: "API Calls: 4234/5000 (17% remaining)"
4. Show "Upgrade" button if nearing limits
Before Creating Project:
1. GET /api/billing/limits/?workspace_id=xxx → Check current limits
2. If projects < max_projects → Allow creation
3. If projects >= max_projects → Show upgrade prompt
After API Call (automatic):
1. User calls GET /api/android/apps/com.example
2. System checks cache → miss
3. System consumes 1 DATA_SCRAPE credit internally
4. Returns app data
5. GET /api/billing/credits/ → Shows updated balance
Important Notes
- Never handle card details - always redirect to Stripe Checkout or Portal
- Webhooks are essential - they sync all payment state changes automatically
- Payment history is fetched from Stripe - not stored in your database
- Subscription changes take effect via webhooks (immediate for upgrades, end-of-period for downgrades)
- Credits are managed internally - Stripe only handles payments, not consumption tracking
Plan Tiers
We offer 5 subscription tiers to meet different needs:
Free Plan
- Price: $0/month
- Best for: Individuals getting started
- Limits: 1 project, 10 keywords, 3 competitors
- Credits: 100 monthly (API, scraping, tracking)
- Features: 7-day history, basic support
Starter Plan
- Price: $49/month (or $490/year - save 17%)
- Best for: Small businesses and freelancers
- Limits: 3 projects, 50 keywords, 10 competitors
- Credits: 1,000 monthly
- Features: 30-day history, API access, data export
Professional Plan ⭐
- Price: $149/month (or $1,490/year - save 17%)
- Best for: Growing agencies and teams
- Limits: 10 projects, 200 keywords, 25 competitors
- Credits: 5,000 monthly
- Features: 90-day history, priority support, advanced analytics
Enterprise Plan
- Price: $499/month (or $4,990/year - save 17%)
- Best for: Large organizations
- Limits: Unlimited projects, keywords, competitors
- Credits: 20,000 monthly
- Features: 365-day history, white label, dedicated support
Internal Plan
- Visibility: Hidden (company use only)
- Price: $0
- Limits: Everything unlimited
- Purpose: For internal testing and company accounts
Credit System
Credit Types
Credits are consumed for various operations:
- API_CALL: Direct API requests
- DATA_SCRAPE: App store data scraping
- KEYWORD_TRACK: Keyword ranking checks
- AI_ANALYSIS: AI-powered insights
- PREMIUM_INTEGRATION: Third-party service calls
Credit Allocation
- Monthly Credits: Included with your plan, reset monthly
- Purchased Credits: Buy additional credits, roll over indefinitely
- Bonus Credits: Promotional credits, don't expire
Credit Consumption
# Example: Scraping an app consumes 1 credit
GET /api/android/apps/com.example.app
# Deducts 1 DATA_SCRAPE credit
# Checking keyword rankings consumes credits
POST /api/projects/{id}/check-rankings
# Deducts KEYWORD_TRACK credits based on keyword count
Credit Balance
Check your credit balance:
Response:
{
"balances": [
{
"credit_type": "DATA_SCRAPE",
"allocated": 5000,
"consumed": 1234,
"purchased": 500,
"available": 4266
}
]
}
Dynamic Feature System
Overview
AppVector uses a fully dynamic feature system that allows flexible configuration of plan features without code changes. Features can be:
- Hard Limits: Maximum allowed resources (e.g., max 10 projects)
- Credit-Based: Consumable resources that reset (e.g., 1000 API calls/month)
- Boolean: On/off features (e.g., priority support enabled)
- Rate Limits: Time-based restrictions (e.g., 60 requests/minute)
Feature Types
Hard Limits
Resources with a maximum count:
{
"feature_key": "max_projects",
"feature_type": "HARD_LIMIT",
"limit_value": 10,
"current_count": 3,
"remaining": 7
}
Credit-Based Features
Consumable resources with monthly reset:
{
"feature_key": "api_calls",
"feature_type": "CREDIT_BASED",
"allocated": 5000,
"consumed": 1234,
"available": 3766,
"reset_period": "MONTHLY"
}
Boolean Features
Simple enabled/disabled features:
Rate Limits
Time-window based restrictions:
{
"feature_key": "api_rate_limit",
"feature_type": "RATE_LIMIT",
"rate_limit": 120,
"current_count": 45,
"window_start": "2024-10-30T15:30:00Z"
}
Available Features
Each plan includes different feature configurations:
| Feature | Free | Starter | Professional | Enterprise |
|---|---|---|---|---|
| Hard Limits | ||||
| Max Projects | 1 | 3 | 10 | Unlimited |
| Max Keywords/Project | 10 | 50 | 200 | Unlimited |
| Max Competitors/Project | 3 | 10 | 25 | Unlimited |
| Max Team Members | 1 | 3 | 10 | Unlimited |
| Historical Data (days) | 7 | 30 | 90 | 365 |
| Credit-Based (monthly) | ||||
| API Calls | 100 | 1,000 | 5,000 | 20,000 |
| Data Scrapes | 100 | 1,000 | 5,000 | 20,000 |
| Keyword Tracking | 100 | 1,000 | 5,000 | 20,000 |
| AI Analysis | 0 | 100 | 500 | 2,000 |
| Rate Limits | ||||
| API Requests/Minute | 10 | 60 | 120 | Unlimited |
| Boolean Features | ||||
| API Access | ✗ | ✓ | ✓ | ✓ |
| Data Export | ✗ | ✓ | ✓ | ✓ |
| Priority Support | ✗ | ✗ | ✓ | ✓ |
| Advanced Analytics | ✗ | ✗ | ✓ | ✓ |
| Custom Reports | ✗ | ✗ | ✓ | ✓ |
| White Label | ✗ | ✗ | ✗ | ✓ |
Using Dynamic Features
Check Feature Availability
Response:
{
"feature_key": "api_access",
"is_available": true,
"details": {
"feature_type": "BOOLEAN",
"is_enabled": true
}
}
Get All Workspace Features
Response:
{
"workspace_id": "...",
"workspace_name": "My Workspace",
"plan": "Professional",
"features_by_category": {
"PROJECT": [
{
"feature_key": "max_projects",
"feature_name": "Projects per Workspace",
"feature_type": "HARD_LIMIT",
"current_count": 3,
"limit": 10,
"remaining": 7
}
],
"API": [
{
"feature_key": "api_calls",
"feature_name": "API Calls",
"feature_type": "CREDIT_BASED",
"allocated": 5000,
"consumed": 1234,
"available": 3766,
"usage_percentage": 24.68,
"reset_period": "MONTHLY",
"period_end": "2024-11-30T00:00:00Z"
}
]
}
}
Consume Feature Credits
POST /api/billing/features/consume/
{
"workspace_id": "...",
"feature_key": "api_calls",
"amount": 1,
"metadata": {
"endpoint": "/api/android/apps/...",
"operation": "app_details"
}
}
Response:
{
"success": true,
"feature_key": "api_calls",
"amount_consumed": 1,
"remaining_balance": 3765,
"message": "Credits consumed successfully"
}
List All Features
Response: List of all available features with their configuration.
Feature Reset Periods
Different features can have different reset frequencies:
- DAILY: Resets every 24 hours (e.g., daily report generation)
- WEEKLY: Resets every 7 days (e.g., batch operations)
- MONTHLY: Resets on billing cycle (e.g., API calls, scraping)
- NEVER: Never resets (e.g., purchased credits, hard limits)
Custom Features
Enterprise clients can request custom features:
- Feature is created in admin with unique key
- Assigned to specific workspace/plan
- Custom reset period and limits
- Usage tracked automatically
Example custom feature:
{
"feature_key": "custom_white_label_domains",
"feature_name": "Custom White Label Domains",
"feature_type": "HARD_LIMIT",
"limit_value": 5,
"category": "CUSTOM"
}
Integration with Application Code
Features are automatically enforced when:
- Creating resources: Checks hard limits before creation
- API operations: Consumes credits for each operation
- Rate limiting: Enforces time-based restrictions
- Feature access: Blocks features not in current plan
Example enforcement in code:
from services.billing.feature_service import DynamicFeatureService
# Check if feature is available
if not DynamicFeatureService.check_feature_available(workspace, 'api_access'):
return Response({'error': 'API access not available in your plan'},
status=403)
# Consume credits for operation
success, remaining, usage = DynamicFeatureService.consume_credits(
workspace=workspace,
feature_key='api_calls',
amount=1
)
if not success:
return Response({
'error': 'Insufficient API credits',
'remaining': remaining,
'upgrade_url': '/billing/upgrade'
}, status=402)
Subscription Management
Creating a Subscription
Workspaces automatically get a FREE subscription upon creation. To upgrade:
Plan Changes
- Upgrades: Take effect immediately with proration
- Downgrades: Scheduled for the end of the current billing period
- Cancellations: Can be immediate or at period end
Checking Subscription Status
Response:
{
"plan": {
"name": "Professional",
"tier": "PROFESSIONAL",
"monthly_price": "149.00"
},
"status": "ACTIVE",
"current_period_end": "2024-11-30T00:00:00Z",
"auto_renew": true
}
Limit Enforcement
Hard Limits
These limits are strictly enforced based on your plan:
- Projects per workspace
- Keywords per project
- Competitors per project
- Team members per workspace
When you reach a limit, you'll see:
{
"error": "Plan limit reached",
"message": "Your plan allows maximum 3 projects. Upgrade to Professional for more.",
"upgrade_url": "/billing/upgrade"
}
Soft Limits
Credits use soft limits with warnings:
- 80% consumed: Email warning sent
- 90% consumed: In-app notifications
- 100% consumed: Operations blocked, purchase required
Payment Methods
Adding a Payment Method
Managing Payment Methods
# List all payment methods
GET /api/billing/payment-methods/
# Remove a payment method
DELETE /api/billing/payment-methods/{id}/
# Set as default
PATCH /api/billing/payment-methods/{id}/
{
"is_default": true
}
Invoices
Viewing Invoices
# List all invoices
GET /api/billing/invoices/
# Get specific invoice
GET /api/billing/invoices/{id}/
# Download PDF (redirects to Stripe)
GET /api/billing/invoices/{id}/pdf/
Invoice Structure
{
"invoice_number": "INV-202410-00001",
"amount": "149.00",
"currency": "USD",
"status": "PAID",
"period_start": "2024-10-01",
"period_end": "2024-10-31",
"paid_at": "2024-10-01T00:00:00Z",
"pdf_url": "https://stripe.com/..."
}
Trial Periods
New accounts get trial periods for paid plans:
- Starter: 14-day trial
- Professional: 14-day trial
- Enterprise: 30-day trial
During trial: - Full access to plan features - No credit card required initially - Automatic conversion to FREE if not upgraded
Promo Codes
Apply promotional codes for discounts:
Webhooks
We process payment events via webhooks:
subscription.createdsubscription.updatedsubscription.cancelledinvoice.paidinvoice.payment_failedpayment_method.attached
API Rate Limiting
Rate limits vary by plan:
| Plan | Requests/minute |
|---|---|
| Free | 10 |
| Starter | 60 |
| Professional | 120 |
| Enterprise | Unlimited |
Frequently Asked Questions
How do I upgrade my plan?
Navigate to Settings → Billing → Choose Plan, or use the API:
Can I buy additional credits?
Yes, purchase credits that don't expire:
What happens when credits run out?
- Operations requiring credits will fail
- You'll receive error messages with remaining balance
- Purchase more credits or wait for monthly reset
Can I cancel anytime?
Yes, cancellations can be: - Immediate: Lose access immediately, prorated refund - End of period: Keep access until period ends
How do refunds work?
- Yearly plans: Prorated refund for unused months
- Monthly plans: Prorated refund for unused days
- Credits: No refunds for purchased credits
Support
For billing questions, contact: - Email: [email protected] - Priority Support: Available for Professional and Enterprise plans - Response Time: - Free/Starter: 48 hours - Professional: 24 hours - Enterprise: 4 hours with SLA