API Reference
Complete reference for all AV API endpoints.
Base URL
Authentication
All endpoints except /api/auth/google/ and /api/token/refresh/ require authentication.
Include the access token in the Authorization header:
Endpoints Overview
| Endpoint | Method | Auth Required | Purpose |
|---|---|---|---|
/api/auth/google/ |
POST | No | Exchange Google token for JWT |
/api/token/refresh/ |
POST | No | Refresh expired access token |
/api/me/ |
GET | Yes | Get current user profile |
/api/aso/android-search/ |
POST | Yes | Search Android apps in Google Play Store |
/api/aso/apple-search/ |
POST | Yes | Search Apple apps in App Store |
/api/aso/android-details/ |
POST | Yes | Get Android app details (with caching) |
/api/aso/android-history/ |
POST | Yes | Get Android app change history |
/api/aso/apple-details/ |
POST | Yes | Get Apple app details (with caching) |
/api/aso/apple-history/ |
POST | Yes | Get Apple app change history |
| Billing Endpoints | |||
/api/billing/plans/ |
GET | No | List available subscription plans |
/api/billing/plans/{id}/ |
GET | No | Get plan details |
/api/billing/subscription/ |
GET | Yes | Get current subscription |
/api/billing/subscription/upgrade/ |
POST | Yes | Upgrade subscription |
/api/billing/subscription/downgrade/ |
POST | Yes | Downgrade subscription |
/api/billing/subscription/cancel/ |
POST | Yes | Cancel subscription |
/api/billing/credits/ |
GET | Yes | Get credit balances |
/api/billing/credits/consume/ |
POST | Yes | Consume credits |
/api/billing/credits/bonus/ |
POST | Yes | Add bonus credits |
/api/billing/credits/history/ |
GET | Yes | Get credit usage history |
/api/billing/usage/ |
GET | Yes | Get usage statistics |
/api/billing/limits/ |
GET | Yes | Get plan limits |
/api/billing/features/ |
GET | Yes | List all features |
/api/billing/features/workspace/ |
GET | Yes | Get workspace features |
/api/billing/features/check/ |
POST | Yes | Check feature availability |
/api/billing/features/consume/ |
POST | Yes | Consume feature usage |
/api/billing/invoices/ |
GET | Yes | List invoices |
/api/billing/invoices/{id}/ |
GET | Yes | Get invoice details |
/api/billing/stripe/checkout/ |
POST | Yes | Create Stripe checkout session |
/api/billing/stripe/checkout/credits/ |
POST | Yes | Create credit purchase session |
/api/billing/stripe/portal/ |
GET | Yes | Create customer portal session |
/api/billing/stripe/payment-history/ |
GET | Yes | Get payment history from Stripe |
/api/billing/stripe/upcoming-invoice/ |
GET | Yes | Preview upcoming invoice |
/api/billing/webhooks/stripe/ |
POST | No | Stripe webhook endpoint (CSRF exempt) |
POST /api/auth/google/
Exchange a Google OAuth 2.0 access token for JWT tokens.
Request
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
access_token |
string | Yes | Google OAuth 2.0 access token |
Response (201 Created)
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"id": 1,
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe"
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
access |
string | JWT access token (60 min lifetime) |
refresh |
string | JWT refresh token (1 day lifetime) |
user.id |
integer | User's unique ID |
user.email |
string | User's email address |
user.first_name |
string | User's first name |
user.last_name |
string | User's last name |
Error Responses
400 Bad Request - Invalid Google token
Code Examples
POST /api/token/refresh/
Get a new access token using a refresh token.
Request
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
refresh |
string | Yes | JWT refresh token |
Response (200 OK)
Response Fields:
| Field | Type | Description |
|---|---|---|
access |
string | New JWT access token (60 min lifetime) |
Error Responses
401 Unauthorized - Refresh token expired or invalid
Code Examples
GET /api/me/
Get the authenticated user's profile information.
Request
Response (200 OK)
{
"id": 1,
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"date_joined": "2025-01-15T10:30:00Z"
}
Response Fields:
| Field | Type | Description |
|---|---|---|
id |
integer | User's unique ID |
email |
string | User's email address |
first_name |
string | User's first name |
last_name |
string | User's last name |
date_joined |
string (ISO 8601) | When user first authenticated |
Error Responses
401 Unauthorized - Missing or invalid access token
401 Unauthorized - Access token expired
Code Examples
Error Codes
HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created (authentication successful) |
| 400 | Bad Request (invalid input) |
| 401 | Unauthorized (missing/invalid/expired token) |
| 403 | Forbidden (no permission) |
| 404 | Not Found |
| 500 | Internal Server Error |
Common Error Responses
Missing Authorization Header:
Invalid Token:
Invalid Google Token:
Rate Limiting
Currently no rate limiting is implemented. This will be added in future versions.
CORS
CORS is configured to allow requests from specified origins. Configure in .env:
Interactive API Explorer
Try these endpoints live in the interactive API documentation:
The Scalar UI provides: - Interactive request testing - Code examples in multiple languages - Automatic schema validation - Real-time responses
POST /api/aso/android-search/
Search for Android apps in Google Play Store.
Request
POST /api/aso/android-search/
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"keyword": "messaging",
"country": "us",
"language": "en"
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
keyword |
string | Yes | - | Search keyword for Android apps |
country |
string | No | "us" | 2-letter country code |
language |
string | No | "en" | 2-letter language code |
Response (200 OK)
{
"keyword": "messaging",
"country": "us",
"language": "en",
"results": [
{
"title": "Google Messages",
"appId": "com.google.android.apps.messaging",
"url": "https://play.google.com/store/apps/details?id=com.google.android.apps.messaging",
"icon": "https://play-lh.googleusercontent.com/...",
"developer": "Google LLC",
"price": 0,
"free": true,
"summary": "Google Messages is the official Google app for messaging...",
"score": 4.57,
"installs": "5,000,000,000+"
},
{
"title": "Messenger",
"appId": "com.facebook.orca",
"url": "https://play.google.com/store/apps/details?id=com.facebook.orca",
"developer": "Meta Platforms, Inc.",
"price": 0,
"free": true,
"summary": "Messenger is a free messaging app...",
"score": 4.70,
"installs": "5,000,000,000+"
}
],
"count": 2
}
Response Fields:
| Field | Type | Description |
|---|---|---|
keyword |
string | The search keyword used |
country |
string | Country code used for search |
language |
string | Language code used for search |
results |
array | List of matching apps |
results[].title |
string | App title |
results[].appId |
string | Android package ID |
results[].url |
string | Play Store URL |
results[].icon |
string | App icon URL |
results[].developer |
string | Developer name |
results[].price |
number | App price |
results[].free |
boolean | Whether app is free |
results[].summary |
string | App description summary |
results[].score |
number | App rating (0-5) |
results[].installs |
string | Install count range |
count |
integer | Number of results returned |
Error Responses
401 Unauthorized - Missing or invalid access token
500 Internal Server Error - Search service error
Code Examples
const response = await fetch('http://localhost:8000/api/aso/android-search/', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
keyword: 'messaging',
country: 'us',
language: 'en'
})
});
const data = await response.json();
console.log('Found apps:', data.results);
import requests
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
payload = {
'keyword': 'messaging',
'country': 'us',
'language': 'en'
}
response = requests.post(
'http://localhost:8000/api/aso/android-search/',
headers=headers,
json=payload
)
data = response.json()
print(f"Found {data['count']} apps")
POST /api/aso/apple-search/
Search for Apple apps in App Store.
Request
POST /api/aso/apple-search/
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"keyword": "messaging",
"country": "us",
"language": "en"
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
keyword |
string | Yes | - | Search keyword for Apple apps |
country |
string | No | "us" | 2-letter country code |
language |
string | No | "en" | 2-letter language code |
Response (200 OK)
{
"keyword": "messaging",
"country": "us",
"language": "en",
"results": [
{
"id": 310633997,
"appId": "net.whatsapp.WhatsApp",
"title": "WhatsApp Messenger",
"url": "https://apps.apple.com/us/app/whatsapp-messenger/id310633997",
"developer": "WhatsApp Inc.",
"primaryGenre": "Social Networking",
"score": 4.69,
"reviews": 16707847,
"price": 0,
"free": true,
"version": "25.30.73",
"requiredOsVersion": "15.1"
},
{
"id": 874139669,
"appId": "org.whispersystems.signal",
"title": "Signal - Private Messenger",
"url": "https://apps.apple.com/us/app/signal-private-messenger/id874139669",
"developer": "Signal Messenger, LLC",
"primaryGenre": "Social Networking",
"score": 4.75,
"reviews": 958541,
"price": 0,
"free": true,
"version": "7.82",
"requiredOsVersion": "15.0"
}
],
"count": 2
}
Response Fields:
| Field | Type | Description |
|---|---|---|
keyword |
string | The search keyword used |
country |
string | Country code used for search |
language |
string | Language code used for search |
results |
array | List of matching apps |
results[].id |
integer | Apple app ID |
results[].appId |
string | Bundle identifier |
results[].title |
string | App title |
results[].url |
string | App Store URL |
results[].developer |
string | Developer name |
results[].primaryGenre |
string | Primary app category |
results[].score |
number | App rating (0-5) |
results[].reviews |
integer | Number of reviews |
results[].price |
number | App price |
results[].free |
boolean | Whether app is free |
results[].version |
string | Current app version |
results[].requiredOsVersion |
string | Minimum iOS version required |
count |
integer | Number of results returned |
Error Responses
401 Unauthorized - Missing or invalid access token
500 Internal Server Error - Search service error
Code Examples
const response = await fetch('http://localhost:8000/api/aso/apple-search/', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
keyword: 'messaging',
country: 'us',
language: 'en'
})
});
const data = await response.json();
console.log('Found apps:', data.results);
import requests
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
payload = {
'keyword': 'messaging',
'country': 'us',
'language': 'en'
}
response = requests.post(
'http://localhost:8000/api/aso/apple-search/',
headers=headers,
json=payload
)
data = response.json()
print(f"Found {data['count']} apps")
ASO Features
Keyword Tracking
Both Android and Apple search endpoints automatically store searched keywords in the database for tracking and analytics purposes. Keywords are normalized to lowercase for consistency.
Search Limits
- Returns up to 250 results per search (configurable)
- Results are ordered by relevance as determined by the app stores
- Supports localization with country and language parameters
Country and Language Codes
Common country codes:
- us - United States
- gb - United Kingdom
- de - Germany
- fr - France
- jp - Japan
- cn - China
Common language codes:
- en - English
- es - Spanish
- de - German
- fr - French
- ja - Japanese
- zh - Chinese
POST /api/aso/android-details/
Get current Android app details with automatic caching (7-day TTL).
Request
POST /api/aso/android-details/
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"app_id": "com.whatsapp",
"country": "us",
"language": "en",
"force_refresh": false
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
app_id |
string | Yes | - | Android package ID (e.g., com.whatsapp) |
country |
string | No | us |
2-letter country code |
language |
string | No | en |
2-letter language code |
force_refresh |
boolean | No | false |
Skip cache and fetch fresh data |
Response (200 OK)
{
"success": true,
"app_id": "com.whatsapp",
"country": "us",
"language": "en",
"data": {
"title": "WhatsApp Messenger",
"score": 4.39,
"ratings": 212040976,
"installs": "10,000,000,000+",
"developer": "WhatsApp LLC",
"genre": "Communication",
"price": 0,
"free": true,
"version": "2.25.2.75",
"androidVersion": "VARY"
}
}
POST /api/aso/android-history/
Get Android app change history with intelligent filtering.
Returns field-centric data - each field shows all dates when it changed, making it easy to track specific metrics over time.
Request
POST /api/aso/android-history/
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"app_id": "com.whatsapp",
"country": "us",
"language": "en",
"start_date": "2025-09-29",
"end_date": "2025-10-29",
"fields": ["score", "ratings"]
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
app_id |
string | Yes | - | Android package ID |
country |
string | No | us |
2-letter country code |
language |
string | No | en |
2-letter language code |
start_date |
string (YYYY-MM-DD) | No | 30 days ago | History start date |
end_date |
string (YYYY-MM-DD) | No | today | History end date |
fields |
array | No | all fields | Fields to track for changes |
Response (200 OK)
{
"success": true,
"app_id": "com.whatsapp",
"country": "us",
"language": "en",
"start_date": "2025-09-29",
"end_date": "2025-10-29",
"tracked_fields": ["score", "ratings"],
"change_count": 7,
"data": {
"score": [
{
"date": "2025-10-29",
"value": 4.39
},
{
"date": "2025-10-28",
"value": 4.35
},
{
"date": "2025-10-22",
"value": 4.38
}
],
"ratings": [
{
"date": "2025-10-29",
"value": 212040976
},
{
"date": "2025-10-28",
"value": 211500000
},
{
"date": "2025-10-22",
"value": 210500000
}
]
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success |
boolean | Whether the request was successful |
app_id |
string | The Android package ID |
country |
string | Country code used |
language |
string | Language code used |
start_date |
string | Start date of the history range |
end_date |
string | End date of the history range |
tracked_fields |
array | Fields that were tracked for changes |
change_count |
integer | Total number of field changes recorded |
data |
object | Field-centric data with dates (see below) |
data[field_name] |
array | Array of {date, value} objects for each field |
data[field_name][].date |
string | Date when the field changed (YYYY-MM-DD) |
data[field_name][].value |
any | The value of the field on that date |
POST /api/aso/apple-details/
Get current Apple app details with dual-TTL caching.
- Fast metadata (ratings, rankings): 1-day cache
- Slow metadata (descriptions, specs): 7-day cache
Request
POST /api/aso/apple-details/
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"app_id": "310633997",
"country": "us",
"language": "en",
"metadata_type": "both",
"force_refresh": false
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
app_id |
string | Yes | - | Apple app ID (numeric, e.g., 310633997) |
country |
string | No | us |
2-letter country code |
language |
string | No | en |
2-letter language code |
metadata_type |
string | No | both |
fast (ratings), slow (descriptions), or both |
force_refresh |
boolean | No | false |
Skip cache and fetch fresh data |
Response (200 OK)
{
"success": true,
"app_id": "310633997",
"country": "us",
"language": "en",
"metadata_type": "both",
"data": {
"title": "WhatsApp Messenger",
"appId": "net.whatsapp.WhatsApp",
"score": 4.63,
"ratings": 7203977,
"developer": "WhatsApp Inc.",
"primaryGenre": "Social Networking",
"price": 0,
"free": true,
"version": "25.30.73"
}
}
POST /api/aso/apple-history/
Get Apple app change history with intelligent filtering.
Returns field-centric data - each field shows all dates when it changed, organized by metadata type (fast/slow).
Request
POST /api/aso/apple-history/
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"app_id": "310633997",
"country": "us",
"language": "en",
"metadata_type": "fast",
"start_date": "2025-10-01",
"end_date": "2025-10-29",
"fields": ["score", "ratings"]
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
app_id |
string | Yes | - | Apple app ID (numeric) |
country |
string | No | us |
2-letter country code |
language |
string | No | en |
2-letter language code |
metadata_type |
string | No | both |
fast (ratings/rankings), slow (descriptions/media), or both |
start_date |
string (YYYY-MM-DD) | No | 30 days ago | History start date |
end_date |
string (YYYY-MM-DD) | No | today | History end date |
fields |
array | No | all fields | Fields to track for changes |
Response (200 OK)
{
"success": true,
"app_id": "310633997",
"country": "us",
"language": "en",
"metadata_type": "fast",
"start_date": "2025-10-01",
"end_date": "2025-10-29",
"tracked_fields": ["score", "ratings"],
"change_count": 6,
"data": {
"fast": {
"score": [
{
"date": "2025-10-29",
"value": 4.63
},
{
"date": "2025-10-28",
"value": 4.59
},
{
"date": "2025-10-22",
"value": 4.62
}
],
"ratings": [
{
"date": "2025-10-29",
"value": 7203977
},
{
"date": "2025-10-28",
"value": 7180000
},
{
"date": "2025-10-22",
"value": 7195000
}
]
},
"slow": {}
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
success |
boolean | Whether the request was successful |
app_id |
string | The Apple app ID |
country |
string | Country code used |
language |
string | Language code used |
metadata_type |
string | The metadata type(s) returned: fast, slow, or both |
start_date |
string | Start date of the history range |
end_date |
string | End date of the history range |
tracked_fields |
array | Fields that were tracked for changes |
change_count |
integer | Total number of field changes recorded |
data |
object | Field-centric data organized by metadata type |
data.fast |
object | Changes in fast-moving data (ratings, rankings) |
data.fast[field_name] |
array | Array of {date, value} objects for each field |
data.slow |
object | Changes in slow-moving data (descriptions, media) |
data.slow[field_name] |
array | Array of {date, value} objects for each field |
Billing & Subscription Endpoints
The billing system provides comprehensive subscription management, credit tracking, dynamic features, and Stripe integration.
Note: For interactive API documentation with try-it-out functionality, visit
/api/docs/(Scalar UI).
Subscription Plans
GET /api/billing/plans/
List all available subscription plans.
Request:
Response:
{
"plans": [
{
"id": "uuid",
"tier": "PROFESSIONAL",
"name": "Professional",
"description": "Perfect for growing teams",
"monthly_price": "149.00",
"yearly_price": "1490.00",
"limits": {
"max_projects": 10,
"max_keywords_per_project": 200,
"max_competitors_per_project": 25
},
"credits": {
"monthly_api_credits": 5000,
"monthly_scrape_credits": 5000
},
"features": [
"90-day history",
"Priority support",
"Advanced analytics"
]
}
]
}
GET /api/billing/subscription/
Get current workspace subscription details.
Request:
Response:
{
"subscription": {
"id": "uuid",
"plan": {
"tier": "PROFESSIONAL",
"name": "Professional"
},
"status": "ACTIVE",
"billing_cycle": "MONTHLY",
"current_period_start": "2024-10-01T00:00:00Z",
"current_period_end": "2024-10-31T23:59:59Z",
"auto_renew": true,
"trial_ends_at": null
}
}
POST /api/billing/subscription/upgrade/
Upgrade to a higher plan tier.
Request:
Response:
{
"subscription": {
"id": "uuid",
"plan": {
"tier": "ENTERPRISE",
"name": "Enterprise"
},
"status": "ACTIVE",
"upgrade_applied": true,
"prorated_amount": "350.00"
}
}
POST /api/billing/subscription/downgrade/
Downgrade to a lower plan tier. Downgrade takes effect at the end of current billing period.
Request:
Response:
{
"subscription": {
"id": "uuid",
"plan": {
"tier": "STARTER",
"name": "Starter"
},
"status": "ACTIVE",
"downgrade_scheduled": true,
"downgrade_effective_date": "2024-10-31T23:59:59Z"
}
}
POST /api/billing/subscription/cancel/
Cancel subscription. Cancellation takes effect at end of current billing period.
Request:
Response:
{
"subscription": {
"id": "uuid",
"status": "CANCELLED",
"cancel_at_period_end": true,
"period_end": "2024-10-31T23:59:59Z"
}
}
Credits Management
GET /api/billing/credits/
Get current credit balances.
Request:
Response:
{
"balances": [
{
"credit_type": "DATA_SCRAPE",
"allocated_credits": 5000,
"consumed_credits": 1234,
"purchased_credits": 500,
"bonus_credits": 0,
"available_credits": 4266,
"usage_percentage": 24.68,
"period_end": "2024-10-31T23:59:59Z"
},
{
"credit_type": "API_CALL",
"allocated_credits": 5000,
"consumed_credits": 567,
"available_credits": 4433
}
]
}
POST /api/billing/credits/consume/
Consume credits for an operation (typically called internally by services).
Request:
{
"workspace_id": "uuid",
"feature_key": "api_calls",
"amount": 1,
"metadata": {
"operation": "android_app_fetch",
"app_id": "com.example.app"
}
}
Response:
{
"success": true,
"remaining": 4999,
"consumed": 1,
"feature": {
"key": "api_calls",
"name": "API Calls",
"allocated": 5000,
"consumed": 1
}
}
POST /api/billing/credits/bonus/
Add bonus credits to a workspace (admin only).
Request:
{
"workspace_id": "uuid",
"feature_key": "api_calls",
"amount": 500,
"reason": "Customer appreciation bonus"
}
Response:
GET /api/billing/credits/history/
Get credit usage history for a workspace.
Request:
GET /api/billing/credits/history/?workspace_id=uuid&feature_key=api_calls&limit=50
Authorization: Bearer YOUR_ACCESS_TOKEN
Parameters:
- workspace_id (required): Workspace UUID
- feature_key (optional): Filter by specific feature
- limit (optional): Number of records (default: 100)
Response:
{
"history": [
{
"feature_key": "api_calls",
"feature_name": "API Calls",
"consumed_amount": 1,
"operation": "android_app_fetch",
"metadata": {
"app_id": "com.example.app"
},
"timestamp": "2024-10-22T14:32:15Z"
}
],
"total_count": 1234
}
Usage & Limits
GET /api/billing/usage/
Get usage statistics for workspace.
Request:
Response:
{
"workspace_id": "uuid",
"period_start": "2024-10-01T00:00:00Z",
"period_end": "2024-10-31T23:59:59Z",
"usage": {
"projects": {
"current": 5,
"limit": 10,
"percentage": 50.0
},
"api_calls": {
"consumed": 1234,
"allocated": 5000,
"percentage": 24.68
},
"data_scrapes": {
"consumed": 567,
"allocated": 5000,
"percentage": 11.34
}
}
}
GET /api/billing/limits/
Get all plan limits for workspace.
Request:
Response:
{
"workspace_id": "uuid",
"plan": {
"tier": "PROFESSIONAL",
"name": "Professional"
},
"limits": {
"max_projects": 10,
"max_keywords_per_project": 200,
"max_competitors_per_project": 25,
"max_team_members": 10,
"historical_data_days": 90,
"api_calls_per_month": 5000,
"data_scrapes_per_month": 5000
}
}
Dynamic Features
GET /api/billing/features/
List all available features in the system.
Request:
Response:
{
"features": [
{
"id": "uuid",
"key": "max_projects",
"name": "Maximum Projects",
"description": "Number of projects that can be created",
"feature_type": "HARD_LIMIT",
"category": "WORKSPACE",
"unit": "projects"
},
{
"id": "uuid",
"key": "api_calls",
"name": "API Calls",
"description": "Monthly API call credits",
"feature_type": "CREDIT_BASED",
"category": "API",
"reset_period": "MONTHLY",
"unit": "calls"
}
]
}
GET /api/billing/features/workspace/
Get all features for a specific workspace with usage information.
Request:
Response:
{
"workspace_id": "uuid",
"plan": {
"tier": "PROFESSIONAL",
"name": "Professional"
},
"features": [
{
"key": "max_projects",
"name": "Maximum Projects",
"feature_type": "HARD_LIMIT",
"limit_value": 10,
"current_usage": 5,
"available": 5
},
{
"key": "api_calls",
"name": "API Calls",
"feature_type": "CREDIT_BASED",
"allocated": 5000,
"consumed": 1234,
"available": 3766,
"usage_percentage": 24.68,
"period_end": "2024-10-31T23:59:59Z"
}
]
}
POST /api/billing/features/check/
Check if a feature is available for a workspace.
Request:
Response:
{
"feature_key": "api_access",
"is_available": true,
"details": {
"feature_type": "BOOLEAN",
"is_enabled": true
}
}
POST /api/billing/features/consume/
Consume feature usage (for CREDIT_BASED or HARD_LIMIT features).
Request:
Response:
Stripe Integration
POST /api/billing/stripe/checkout/
Create a Stripe checkout session for subscription signup.
Request:
{
"workspace_id": "uuid",
"plan_id": "uuid",
"success_url": "https://yourdomain.com/billing/success?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://yourdomain.com/billing/cancel"
}
Response:
POST /api/billing/stripe/checkout/credits/
Create a Stripe checkout session for credit purchase.
Request:
{
"workspace_id": "uuid",
"feature_key": "api_calls",
"amount": 1000,
"success_url": "https://yourdomain.com/credits/success",
"cancel_url": "https://yourdomain.com/credits/cancel"
}
Response:
{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_xxx...",
"session_id": "cs_xxx",
"amount": 1000
}
GET /api/billing/stripe/portal/
Create a Stripe customer portal session for self-service billing management.
Request:
GET /api/billing/stripe/portal/?workspace_id=uuid&return_url=https://yourdomain.com/billing
Authorization: Bearer YOUR_ACCESS_TOKEN
Response:
GET /api/billing/stripe/payment-history/
Get payment history from Stripe.
Request:
GET /api/billing/stripe/payment-history/?workspace_id=uuid&limit=10
Authorization: Bearer YOUR_ACCESS_TOKEN
Response:
{
"payments": [
{
"id": "in_xxx",
"amount": 149.00,
"currency": "USD",
"status": "paid",
"paid": true,
"date": 1704067200,
"invoice_pdf": "https://pay.stripe.com/invoice/xxx/pdf",
"hosted_invoice_url": "https://invoice.stripe.com/i/xxx",
"description": "Subscription for Professional Plan"
}
],
"has_more": false
}
GET /api/billing/stripe/upcoming-invoice/
Preview the next invoice for a workspace.
Request:
Response:
{
"amount_due": 149.00,
"currency": "USD",
"period_start": "2024-11-01T00:00:00Z",
"period_end": "2024-11-30T23:59:59Z",
"next_payment_attempt": "2024-11-01T00:00:00Z"
}
Invoices
GET /api/billing/invoices/
List all invoices for the workspace.
Request:
Response:
{
"invoices": [
{
"id": "uuid",
"invoice_number": "INV-202410-00001",
"total_amount": "149.00",
"currency": "USD",
"status": "PAID",
"issued_at": "2024-10-01T00:00:00Z",
"period_start": "2024-10-01",
"period_end": "2024-10-31",
"pdf_url": "https://stripe.com/..."
}
]
}
Next Steps
- Authentication Setup - Set up Google OAuth
- Token Management - Handle token expiration
- ASO Projects - Create and manage ASO projects