Products & Prices
Manage products and their pricing tiers
Products
All product endpoints are scoped to a project:
/api/billstack/teams/{teamId}/projects/{projectId}/productsList Products
GET /products?activeOnly=true| Parameter | Type | Default | Description |
|---|---|---|---|
activeOnly | boolean | true | Only return active products |
curl "https://your-billstack.com/.../products?activeOnly=true" \
-H "Authorization: Bearer bs_..."Response:
{
"products": [
{
"id": "pp_e5f6g7h8",
"name": "Pro Plan",
"description": "Full access to all features",
"isActive": true,
"stripeProductId": "prod_xxx",
"metadata": {},
"projectId": "proj_abc123",
"createdAt": "2026-03-30T12:00:00Z"
}
]
}Auth: Read access (session or API key with products:read).
Create Product
POST /products| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Product name |
description | string | No | Product description |
metadata | object | No | Arbitrary key-value pairs |
curl -X POST "https://your-billstack.com/.../products" \
-H "Authorization: Bearer bs_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Pro Plan",
"description": "Full access to all features"
}'Response (201):
{
"product": {
"id": "pp_e5f6g7h8",
"name": "Pro Plan",
"description": "Full access to all features",
"isActive": true,
"stripeProductId": "prod_xxx",
"metadata": {},
"projectId": "proj_abc123",
"createdAt": "2026-03-30T12:00:00Z"
}
}Creates the product in both Stripe and BillStack.
Auth: Write access (session or API key with products:write).
Get Product
GET /products/{productId}curl "https://your-billstack.com/.../products/pp_e5f6g7h8" \
-H "Authorization: Bearer bs_..."Auth: Read access.
Update Product
PATCH /products/{productId}| Field | Type | Description |
|---|---|---|
name | string | New product name |
description | string | New description |
isActive | boolean | Activate or deactivate |
metadata | object | New metadata |
curl -X PATCH "https://your-billstack.com/.../products/pp_e5f6g7h8" \
-H "Authorization: Bearer bs_..." \
-H "Content-Type: application/json" \
-d '{ "name": "Pro Plan v2" }'Auth: Write access.
Delete Product
DELETE /products/{productId}Archives the product in Stripe and removes it from the BillStack database.
curl -X DELETE "https://your-billstack.com/.../products/pp_e5f6g7h8" \
-H "Authorization: Bearer bs_..."Auth: Write access.
Prices
Price endpoints are also scoped to a project:
/api/billstack/teams/{teamId}/projects/{projectId}/pricesList Prices
GET /prices?activeOnly=true&productId=pp_xxx| Parameter | Type | Default | Description |
|---|---|---|---|
activeOnly | boolean | true | Only return active prices |
productId | string | — | Filter by BillStack product ID |
curl "https://your-billstack.com/.../prices?productId=pp_e5f6g7h8" \
-H "Authorization: Bearer bs_..."Response:
{
"prices": [
{
"id": "pri_i9j0k1l2",
"productId": "pp_e5f6g7h8",
"unitAmount": 2999,
"currency": "usd",
"type": "recurring",
"interval": "month",
"intervalCount": 1,
"isActive": true,
"stripePriceId": "price_xxx",
"metadata": {},
"createdAt": "2026-03-30T12:00:00Z"
}
]
}Auth: Read access.
Create Price
POST /prices| Field | Type | Required | Description |
|---|---|---|---|
productId | string | Yes | BillStack product ID (pp_...) |
unitAmount | number | Yes | Amount in cents (e.g., 2999 = $29.99) |
currency | string | Yes | Three-letter currency code (usd, eur, etc.) |
type | string | No | recurring (default) or one_time |
interval | string | No | day, week, month, or year (required for recurring) |
intervalCount | number | No | Number of intervals between billings (default: 1) |
metadata | object | No | Arbitrary key-value pairs |
curl -X POST "https://your-billstack.com/.../prices" \
-H "Authorization: Bearer bs_..." \
-H "Content-Type: application/json" \
-d '{
"productId": "pp_e5f6g7h8",
"unitAmount": 2999,
"currency": "usd",
"type": "recurring",
"interval": "month",
"intervalCount": 1
}'Response (201):
{
"price": {
"id": "pri_i9j0k1l2",
"productId": "pp_e5f6g7h8",
"unitAmount": 2999,
"currency": "usd",
"type": "recurring",
"interval": "month",
"intervalCount": 1,
"isActive": true,
"stripePriceId": "price_xxx",
"createdAt": "2026-03-30T12:00:00Z"
}
}Auth: Write access.
Get Price
GET /prices/{priceId}curl "https://your-billstack.com/.../prices/pri_i9j0k1l2" \
-H "Authorization: Bearer bs_..."Auth: Read access.
Update Price
PATCH /prices/{priceId}| Field | Type | Description |
|---|---|---|
isActive | boolean | Activate or deactivate the price |
metadata | object | New metadata |
Only isActive and metadata can be updated. Stripe does not allow changing the amount or interval of an existing price — create a new price instead.
curl -X PATCH "https://your-billstack.com/.../prices/pri_i9j0k1l2" \
-H "Authorization: Bearer bs_..." \
-H "Content-Type: application/json" \
-d '{ "isActive": false }'Auth: Write access.
Delete Price
DELETE /prices/{priceId}Deactivates the price in Stripe and removes it from the BillStack database. Existing subscriptions using this price are not affected.
curl -X DELETE "https://your-billstack.com/.../prices/pri_i9j0k1l2" \
-H "Authorization: Bearer bs_..."Auth: Write access.