Skip to content

Product configs

Product configs define the packages and memberships you sell. List them to build checkout pickers; create or update them from your own provisioning tools instead of Admin → Product Configs.

GET /api/v2/product-configs

Requires the summary scope. Pass location_id as a query parameter. Optional ?active=true returns only active configs.

Terminal window
curl "https://app.<your-domain>/api/v2/product-configs?location_id=loc_1" \
-H "Authorization: Bearer ktly_<your-token>"
{
"ok": true,
"reason_code": "product_configs_loaded",
"correlation_id": "a1b2c3d4-...",
"product_configs": [
{
"id": "pc_package_1",
"name": "10-Class Pack",
"type": "package",
"credits_total": 10,
"expiry_days": 90,
"monthly_credits": null,
"active": true,
"customer_purchasable": true,
"ghl_product_id": null,
"calendar_id": null,
"service_id": null,
"stripe_price_id": null,
"price_amount": null,
"currency": null
}
]
}
POST /api/v2/product-configs

Requires the manage scope. Idempotent via request_id. Validation mirrors Admin → Product Configs — reject nonsense combinations (membership with credits_total, package without credits, etc.).

FieldTypeRequiredNotes
location_idstringyesMust match the API client’s location
request_idstringyesIdempotency key
typestringyespackage or membership
namestringyesDisplay name
credits_totalintegerpackagePositive integer — required for package
expiry_daysintegernoOptional positive integer — package expiry
monthly_creditsintegermembershipPositive integer — required for membership
activebooleannoDefault true
customer_purchasablebooleannoDefault false
ghl_product_idstringnoOptional GHL product id when connected
calendar_idstringnoBooking family matching
service_idstringnoBooking family matching
stripe_price_idstringnoOptional Stripe price id
price_amountintegernoDisplay price in cents
currencystringnoe.g. "USD"
Terminal window
curl -X POST "https://app.<your-domain>/api/v2/product-configs" \
-H "Authorization: Bearer ktly_<your-token>" \
-H "Content-Type: application/json" \
-d '{
"location_id": "loc_1",
"request_id": "pc-create-10pack",
"type": "package",
"name": "10-Class Pack",
"credits_total": 10,
"expiry_days": 90,
"customer_purchasable": true
}'
{
"ok": true,
"reason_code": "product_config_created",
"correlation_id": "a1b2c3d4-...",
"product_config": {
"id": "pc_new_uuid",
"name": "10-Class Pack",
"type": "package",
"credits_total": 10,
"expiry_days": 90,
"active": true,
"customer_purchasable": true
}
}
PATCH /api/v2/product-configs/{id}

Requires the manage scope. Pass location_id as a query parameter. Only active, name, and customer_purchasable can be changed — type and credit rules are fixed at create time.

FieldTypeRequiredNotes
activebooleannoEnable or disable the config
namestringnoNon-empty display name
customer_purchasablebooleannoShow in customer-facing pickers
Terminal window
curl -X PATCH "https://app.<your-domain>/api/v2/product-configs/pc_package_1?location_id=loc_1" \
-H "Authorization: Bearer ktly_<your-token>" \
-H "Content-Type: application/json" \
-d '{
"active": false,
"customer_purchasable": false
}'
{
"ok": true,
"reason_code": "product_config_updated",
"correlation_id": "a1b2c3d4-...",
"product_config": {
"id": "pc_package_1",
"name": "10-Class Pack",
"type": "package",
"active": false,
"customer_purchasable": false
}
}
StatusWhen
400Validation error (missing required field, invalid type combination)
403BILLING_SUSPENDED — workspace billing is suspended
404Config not found for this location (PATCH only)

See the Overview for the full error model.