Appearance
Billing API Reference
This guide provides detailed information about the Billing API endpoints for managing subscriptions and plans.
Authentication
All billing endpoints require authentication using a User Authentication Token. Additionally, you must be the project owner to access billing information and manage subscriptions.
bash
Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKENFor more information about authentication, see the Authentication Guide.
Get Billing Information
Retrieve billing information for a project, including current plan, subscription status, and billing portal URL.
http
GET /api/v1/projects/:project_uuid/billing
Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKENExample with curl:
bash
curl -X GET "https://app.uptinio.com/api/v1/projects/PRJ123456789/billing" \
-H "Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKEN" \
-H "Content-Type: application/json"Path Parameters
| Parameter | Type | Description |
|---|---|---|
| project_uuid | string | The UUID of the project |
Response
json
{
"project": {
"uuid": "PRJ123456789",
"name": "My Team"
},
"current_plan": {
"id": 1,
"name": "Solo",
"stripe_id": "prod_xxx",
"currency": "usd",
"decimal_price": 9.99,
"description": "Perfect for individuals",
"features": {
"network_monitors_limit": 10,
"status_pages_limit": 1,
"team_members_limit": 1,
"ai_analysis_limit_per_month": 10
},
"active": true,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
"active_subscription": {
"id": 1,
"name": "default",
"status": "active",
"processor": "stripe",
"processor_id": "sub_xxx",
"trial_ends_at": null,
"ends_at": null,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z",
"plan": {
"id": 1,
"name": "Solo",
"stripe_id": "prod_xxx",
"currency": "usd",
"decimal_price": 9.99,
"description": "Perfect for individuals",
"features": {
"network_monitors_limit": 10,
"status_pages_limit": 1,
"team_members_limit": 1,
"ai_analysis_limit_per_month": 10
},
"active": true,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
},
"billing_portal_url": "https://billing.stripe.com/p/session/xxx",
"upcoming_invoice_amount": 9.99,
"plan_price": 9.99
}Response Fields
| Field | Type | Description |
|---|---|---|
| project | object | Project information |
| current_plan | object | Current plan details (see Plan object below) |
| active_subscription | object|null | Active subscription details (null if on free plan) |
| billing_portal_url | string|null | URL to Stripe billing portal for managing payment methods and invoices |
| upcoming_invoice_amount | number|null | Amount of the next invoice (if subscription exists) |
| plan_price | number | Current plan price |
Plan Object
| Field | Type | Description |
|---|---|---|
| id | integer | Plan ID |
| name | string | Plan name (e.g., "Free", "Solo", "Team", "Agency") |
| stripe_id | string | Stripe product ID |
| currency | string | Currency code (e.g., "usd") |
| decimal_price | number | Plan price in decimal format (e.g., 9.99) |
| description | string | Plan description |
| features | object | Plan features and limits (JSON object) |
| active | boolean | Whether the plan is active |
| created_at | string | ISO 8601 timestamp |
| updated_at | string | ISO 8601 timestamp |
Subscription Object
| Field | Type | Description |
|---|---|---|
| id | integer | Subscription ID |
| name | string | Subscription name |
| status | string | Subscription status (e.g., "active", "canceled", "past_due") |
| processor | string | Payment processor (e.g., "stripe") |
| processor_id | string | Processor subscription ID |
| trial_ends_at | string|null | ISO 8601 timestamp when trial ends |
| ends_at | string|null | ISO 8601 timestamp when subscription ends |
| plan | object|null | Associated plan object |
| created_at | string | ISO 8601 timestamp |
| updated_at | string | ISO 8601 timestamp |
List Available Plans
Retrieve a list of all available subscription plans.
http
GET /api/v1/billing/plans
Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKENExample with curl:
bash
curl -X GET "https://app.uptinio.com/api/v1/billing/plans" \
-H "Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKEN" \
-H "Content-Type: application/json"Response
json
[
{
"id": 1,
"name": "Free",
"stripe_id": "prod_free",
"currency": "usd",
"decimal_price": 0,
"description": "Perfect for getting started",
"features": {
"network_monitors_limit": 3,
"status_pages_limit": 1,
"team_members_limit": 1,
"ai_analysis_limit_per_month": 0
},
"active": true,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
{
"id": 2,
"name": "Solo",
"stripe_id": "prod_solo",
"currency": "usd",
"decimal_price": 9.99,
"description": "Perfect for individuals",
"features": {
"network_monitors_limit": 10,
"status_pages_limit": 1,
"team_members_limit": 1,
"ai_analysis_limit_per_month": 10
},
"active": true,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
]Create Checkout Session
Create a Stripe checkout session for upgrading or subscribing to a plan. If the project already has an active subscription, it will be swapped to the new plan immediately.
http
POST /api/v1/projects/:project_uuid/billing/checkout
Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKEN
Content-Type: application/jsonExample with curl:
bash
curl -X POST "https://app.uptinio.com/api/v1/projects/PRJ123456789/billing/checkout" \
-H "Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"stripe_product_id": "prod_xxx",
"success_url": "https://yourapp.com/billing/success",
"cancel_url": "https://yourapp.com/billing/cancel"
}'Path Parameters
| Parameter | Type | Description |
|---|---|---|
| project_uuid | string | The UUID of the project |
Request Body
json
{
"stripe_product_id": "prod_xxx",
"success_url": "https://yourapp.com/billing/success",
"cancel_url": "https://yourapp.com/billing/cancel"
}Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
| stripe_product_id | string | Yes | Stripe product ID for the plan |
| success_url | string | No | URL to redirect after successful checkout (defaults to billing page) |
| cancel_url | string | No | URL to redirect if checkout is cancelled (defaults to billing page) |
Response
New Subscription (200 OK) - Checkout session created:
json
{
"checkout_url": "https://checkout.stripe.com/c/pay/xxx",
"checkout_session_id": "cs_xxx"
}Existing Subscription (200 OK) - Subscription swapped immediately:
json
{
"message": "Subscription updated successfully",
"subscription": {
"id": 1,
"name": "default",
"status": "active",
"processor": "stripe",
"processor_id": "sub_xxx",
"plan": {
"id": 2,
"name": "Team",
"decimal_price": 29.99,
...
},
...
}
}Error Responses:
400 Bad Request - Missing required field:
json
{
"error": "stripe_product_id is required"
}403 Forbidden - User is not the project owner:
json
{
"error": "You must be the project owner to access billing"
}422 Unprocessable Entity - Stripe error:
json
{
"error": "Failed to retrieve product from Stripe",
"details": "No such product: prod_invalid"
}Downgrade Subscription
Downgrade an existing subscription to a different plan. This will swap the subscription immediately without proration.
http
POST /api/v1/projects/:project_uuid/billing/downgrade
Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKEN
Content-Type: application/jsonExample with curl:
bash
curl -X POST "https://app.uptinio.com/api/v1/projects/PRJ123456789/billing/downgrade" \
-H "Authorization: Bearer YOUR_USER_AUTHENTICATION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"stripe_product_id": "prod_xxx"
}'Path Parameters
| Parameter | Type | Description |
|---|---|---|
| project_uuid | string | The UUID of the project |
Request Body
json
{
"stripe_product_id": "prod_xxx"
}Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
| stripe_product_id | string | Yes | Stripe product ID for the plan to downgrade to |
Response
Success (200 OK):
json
{
"message": "Subscription downgraded successfully",
"subscription": {
"id": 1,
"name": "default",
"status": "active",
"processor": "stripe",
"processor_id": "sub_xxx",
"plan": {
"id": 1,
"name": "Solo",
"decimal_price": 9.99,
...
},
...
}
}Error Responses:
400 Bad Request - Missing required field:
json
{
"error": "stripe_product_id is required"
}403 Forbidden - User is not the project owner:
json
{
"error": "You must be the project owner to access billing"
}404 Not Found - No active subscription:
json
{
"error": "No active subscription found"
}422 Unprocessable Entity - Failed to downgrade:
json
{
"error": "Failed to downgrade subscription",
"details": "Error message from Stripe"
}Billing Portal
The billing portal URL returned in the billing information allows users to:
- Update payment methods
- View and download invoices
- Update billing information
- Cancel subscriptions
The portal URL is generated by Stripe and is valid for a limited time. You should request a new billing information endpoint call to get a fresh portal URL when needed.
Error Responses
All endpoints may return the following error responses:
401 Unauthorized - Missing or invalid authentication token:
json
{
"error": "Unauthorized"
}403 Forbidden - User is not the project owner:
json
{
"error": "You must be the project owner to access billing"
}404 Not Found - Project not found:
json
{
"error": "Project not found or you do not have access to it"
}Notes
- Only project owners can access billing endpoints
- Upgrades use proration (always_invoice), so you'll be charged immediately for the difference
- Downgrades don't use proration (none), so the change takes effect at the next billing cycle
- The billing portal URL expires after a period of time - request a new one when needed
- All prices are in the plan's currency (typically USD)
- Plan features are stored as a JSON object and may vary by plan
Related Endpoints
- Projects API - Manage projects
- Authentication Guide - Learn about authentication methods