curl --request POST \
--url https://api.bachs.io/v1/products \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Pro Plan",
"description": "Monthly access to all Pro features.",
"price": {
"currency": "USD",
"amount": "29.00",
"currency_options": [
{
"currency": "NGN",
"amount": "45000.00"
}
]
},
"billing_cycle": {
"interval": "month",
"frequency": 1
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Pro Plan',
description: 'Monthly access to all Pro features.',
price: {
currency: 'USD',
amount: '29.00',
currency_options: [{currency: 'NGN', amount: '45000.00'}]
},
billing_cycle: {interval: 'month', frequency: 1}
})
};
fetch('https://api.bachs.io/v1/products', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.bachs.io/v1/products"
payload = {
"name": "Pro Plan",
"description": "Monthly access to all Pro features.",
"price": {
"currency": "USD",
"amount": "29.00",
"currency_options": [
{
"currency": "NGN",
"amount": "45000.00"
}
]
},
"billing_cycle": {
"interval": "month",
"frequency": 1
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bachs.io/v1/products"
payload := strings.NewReader("{\n \"name\": \"Pro Plan\",\n \"description\": \"Monthly access to all Pro features.\",\n \"price\": {\n \"currency\": \"USD\",\n \"amount\": \"29.00\",\n \"currency_options\": [\n {\n \"currency\": \"NGN\",\n \"amount\": \"45000.00\"\n }\n ]\n },\n \"billing_cycle\": {\n \"interval\": \"month\",\n \"frequency\": 1\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "prod_1a2b3c4d5e6f7g8h",
"organization_id": "acct_7KpQ2mNv4XbR9dLc",
"name": "Pro Plan",
"description": "Full access, billed monthly.",
"price": {
"currency": "USD",
"price_type": "fixed",
"amount": "29.00",
"preset_amount": null,
"minimum_amount": null,
"maximum_amount": null,
"currency_options": []
},
"prices": [
{
"currency": "USD",
"amount": "29.00",
"minimum_amount": null,
"maximum_amount": null,
"is_default": true
}
],
"billing_cycle": {
"interval": "month",
"frequency": 1
},
"trial_period": null,
"status": "active",
"metadata": {
"tier": "pro"
},
"media": [],
"actor_id": "usr_abc123",
"total_payments": 0,
"total_amount": "0.00",
"created_at": "2026-07-13T14:00:00.000Z",
"updated_at": "2026-07-13T14:00:00.000Z",
"archived_at": null
}{
"detail": "Validation failed for one or more fields",
"error_code": "VALIDATION_ERROR",
"doc_url": "https://docs.bachs.io/api-reference/error-reference#general",
"errors": [
{
"field": "name",
"message": "This field is required",
"type": "missing"
}
]
}{
"detail": "Invalid API key",
"error_code": "UNAUTHORIZED"
}{
"detail": "API key does not have permission for this operation",
"error_code": "FORBIDDEN"
}Create a product
Creates a product with its pricing. Every product has a price; add a billing_cycle to make it recurring, or omit it for a one-time product. Sell products through checkout sessions and subscriptions. Requires the products:write scope.
curl --request POST \
--url https://api.bachs.io/v1/products \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Pro Plan",
"description": "Monthly access to all Pro features.",
"price": {
"currency": "USD",
"amount": "29.00",
"currency_options": [
{
"currency": "NGN",
"amount": "45000.00"
}
]
},
"billing_cycle": {
"interval": "month",
"frequency": 1
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Pro Plan',
description: 'Monthly access to all Pro features.',
price: {
currency: 'USD',
amount: '29.00',
currency_options: [{currency: 'NGN', amount: '45000.00'}]
},
billing_cycle: {interval: 'month', frequency: 1}
})
};
fetch('https://api.bachs.io/v1/products', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.bachs.io/v1/products"
payload = {
"name": "Pro Plan",
"description": "Monthly access to all Pro features.",
"price": {
"currency": "USD",
"amount": "29.00",
"currency_options": [
{
"currency": "NGN",
"amount": "45000.00"
}
]
},
"billing_cycle": {
"interval": "month",
"frequency": 1
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bachs.io/v1/products"
payload := strings.NewReader("{\n \"name\": \"Pro Plan\",\n \"description\": \"Monthly access to all Pro features.\",\n \"price\": {\n \"currency\": \"USD\",\n \"amount\": \"29.00\",\n \"currency_options\": [\n {\n \"currency\": \"NGN\",\n \"amount\": \"45000.00\"\n }\n ]\n },\n \"billing_cycle\": {\n \"interval\": \"month\",\n \"frequency\": 1\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "prod_1a2b3c4d5e6f7g8h",
"organization_id": "acct_7KpQ2mNv4XbR9dLc",
"name": "Pro Plan",
"description": "Full access, billed monthly.",
"price": {
"currency": "USD",
"price_type": "fixed",
"amount": "29.00",
"preset_amount": null,
"minimum_amount": null,
"maximum_amount": null,
"currency_options": []
},
"prices": [
{
"currency": "USD",
"amount": "29.00",
"minimum_amount": null,
"maximum_amount": null,
"is_default": true
}
],
"billing_cycle": {
"interval": "month",
"frequency": 1
},
"trial_period": null,
"status": "active",
"metadata": {
"tier": "pro"
},
"media": [],
"actor_id": "usr_abc123",
"total_payments": 0,
"total_amount": "0.00",
"created_at": "2026-07-13T14:00:00.000Z",
"updated_at": "2026-07-13T14:00:00.000Z",
"archived_at": null
}{
"detail": "Validation failed for one or more fields",
"error_code": "VALIDATION_ERROR",
"doc_url": "https://docs.bachs.io/api-reference/error-reference#general",
"errors": [
{
"field": "name",
"message": "This field is required",
"type": "missing"
}
]
}{
"detail": "Invalid API key",
"error_code": "UNAUTHORIZED"
}{
"detail": "API key does not have permission for this operation",
"error_code": "FORBIDDEN"
}Authorizations
Bearer token authentication. Pass your API key as Authorization: Bearer sk_.... See Authentication for keys, scopes, and sandbox vs production.
Body
Display name of the product. Shown to customers at checkout.
1 - 255"Pro Plan"
Primary price for the product. Provide an amount as a decimal string and a currency.
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
{
"price_type": "fixed",
"currency": "USD",
"amount": "29.00"
}
Optional description of the product. Shown to customers at checkout.
5000"Monthly access to all Pro features."
Up to 20 key/value pairs for your own reference.
{ "order_id": "ORD-9876", "tier": "pro" }
How often the product bills. Provide a cadence to make the product recurring, or omit it for a one-time product.
Show child attributes
Show child attributes
A free trial before the first charge, given as a duration like { "interval": "day", "frequency": 14 } for 14 days. The customer isn't charged until the trial ends. Only valid on a recurring product. Currently in beta.
Show child attributes
Show child attributes
Response
Product created
Unique identifier for the product, prefixed with prod_.
"prod_1a2b3c4d5e6f"
The account that owns the product.
"acct_7KpQ2mNv4XbR9dLc"
Display name of the product.
"Pro Plan"
Optional description of the product. null when not set.
"Monthly access to all Pro features."
Primary price for the product, in the product's default currency.
Show child attributes
Show child attributes
{
"price_type": "fixed",
"currency": "USD",
"amount": "29.00"
}
Status of the product. active: Live and available for use in checkouts and subscriptions. archived: Retired. Kept for reference but not available for new purchases.
active, archived "active"
Your own key-value data attached to the product, returned unchanged.
{ "order_id": "ORD-9876", "tier": "pro" }
Media items (images) attached to the product. Empty when none are set.
Show child attributes
Show child attributes
Identifier of the user or key that created the product.
"usr_abc123"
ISO 8601 timestamp when the product was created.
"2026-07-13T14:00:00.000Z"
ISO 8601 timestamp when the product was last updated.
"2026-07-13T14:00:00.000Z"
When set, the product is archived and cannot be used in new checkouts. null while the product is active.
null
How often the product bills. Provide a cadence to make the product recurring, or omit it for a one-time product.
Show child attributes
Show child attributes
A free trial before the first charge, given as a duration like { "interval": "day", "frequency": 14 } for 14 days. The customer isn't charged until the trial ends. Only valid on a recurring product. Currently in beta.
Show child attributes
Show child attributes
All prices configured on the product, one per currency. Each has currency, amount, optional minimum_amount and maximum_amount, and is_default.
Running count of completed payments for this product. Starts at 0 and increments as customers pay.
0
Running total collected for this product, as a decimal string in the product currency. Starts at "0.00".
"0.00"

