Merchant product families

Manage a merchant's product families — the top-level grouping that organizes related products.

A product family is the top-level bucket for related products. It carries no price of its own; it exists to organize the catalog and to scope reporting. These endpoints back the Dashboard's product-families screen.

Deleting a family cascades to the products under it, so removals are soft and can be restored. Reordering families changes how the catalog is presented, not how anything is charged.

These endpoints power the Tokeflow Dashboard UI. They are session-authenticated (JWT bearer) — the token comes from signing in to the Dashboard, not from an sk_/pk_ API key. Requests also carry the x-merchant-id header identifying the merchant in context, and the signed-in user must be a member with access to it.

The product family object

Returned by the list and retrieve endpoints on this page.

FieldTypeDescription
idstring
merchant_idstring
namestring
slugstring
descriptionstring | null
custom_plan_idstring | nullExternal plan reference ID (display only).
change_charge_behaviorstringDefault behavior when a subscription transitions between offers in this family. One of next_renew, prorated, override.
created_atstring(ISO 8601 UTC).
updated_atstring(ISO 8601 UTC).

Endpoints

GET/api/v1/merchant/product-families

Merchant

Auth: Dashboard session (JWT bearer). Merchant membership required.

List product families.

Query parameters

FieldTypeRequiredDescription
pagenumberNoPage number (1-indexed). Default 1, min 1.
limitnumberNoNumber of items per page. Default 20, min 1, max 100.
namestringNoPartial-match filter on family name
slugstringNoFilter by exact slug
change_charge_behaviorstringNoOne of next_renew, prorated, override.

Example request

curl -G https://api.tokeflow.com/api/v1/merchant/product-families \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
  -H "x-merchant-id: mrc_8a3f12d9" \
  --data-urlencode "page=1" \
  --data-urlencode "limit=20" \
  --data-urlencode "name=Streaming" \
  --data-urlencode "slug=streaming-plans"

Example response200

{
  "data": [
    {
      "id": "pfa_a1b2c3d4e5",
      "merchant_id": "mrc_a1b2c3d4e5",
      "name": "Streaming Plans",
      "slug": "streaming-plans",
      "description": "Family of streaming subscription plans",
      "custom_plan_id": "plan_external_42",
      "change_charge_behavior": "next_renew",
      "created_at": "2026-05-19T12:00:00Z",
      "updated_at": "2026-05-19T12:00:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "total_pages": 3,
    "has_next": true,
    "has_prev": false
  }
}

POST/api/v1/merchant/product-families

Merchant

Auth: Dashboard session (JWT bearer). Merchant membership required.

Create a product family.

Request fields

FieldTypeRequiredDescription
namestringYes
slugstringYesLowercase identifier, unique per merchant.
descriptionstringNo
custom_plan_idstringNoExternal plan reference ID (display only).
change_charge_behaviorstringNoDefault offer-transition behavior. Omit to use next_renew. One of next_renew, prorated, override.

Example request

curl -X POST https://api.tokeflow.com/api/v1/merchant/product-families \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
  -H "x-merchant-id: mrc_8a3f12d9" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Streaming Plans",
    "slug": "streaming-plans",
    "description": "Family of streaming subscription plans",
    "custom_plan_id": "plan_external_42",
    "change_charge_behavior": "next_renew"
  }'

Example response201

{
  "id": "pfa_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "name": "Streaming Plans",
  "slug": "streaming-plans",
  "description": "Family of streaming subscription plans",
  "custom_plan_id": "plan_external_42",
  "change_charge_behavior": "next_renew",
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

DELETE/api/v1/merchant/product-families/:id

Merchant

Auth: Dashboard session (JWT bearer). Merchant membership required.

Refuses with 409 while any product (active) or subscription (any status) references the family. Delete or move the products first; families referenced by subscriptions are kept for billing history.

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

curl -X DELETE https://api.tokeflow.com/api/v1/merchant/product-families/obj_1a2b3c4d \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
  -H "x-merchant-id: mrc_8a3f12d9"

Example response204 No Content

An empty body is returned on success.


GET/api/v1/merchant/product-families/:id

Merchant

Auth: Dashboard session (JWT bearer). Merchant membership required.

Get a product family by ID.

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

curl https://api.tokeflow.com/api/v1/merchant/product-families/obj_1a2b3c4d \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
  -H "x-merchant-id: mrc_8a3f12d9"

Example response200

{
  "id": "pfa_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "name": "Streaming Plans",
  "slug": "streaming-plans",
  "description": "Family of streaming subscription plans",
  "custom_plan_id": "plan_external_42",
  "change_charge_behavior": "next_renew",
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

PATCH/api/v1/merchant/product-families/:id

Merchant

Auth: Dashboard session (JWT bearer). Merchant membership required.

Update a product family.

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

curl -X PATCH https://api.tokeflow.com/api/v1/merchant/product-families/obj_1a2b3c4d \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
  -H "x-merchant-id: mrc_8a3f12d9" \
  -H "Content-Type: application/json" \
  -d '{}'

Example response200

{
  "id": "pfa_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "name": "Streaming Plans",
  "slug": "streaming-plans",
  "description": "Family of streaming subscription plans",
  "custom_plan_id": "plan_external_42",
  "change_charge_behavior": "next_renew",
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

POST/api/v1/merchant/product-families/:id/restore

Merchant

Auth: Dashboard session (JWT bearer). Merchant membership required.

Restore a soft-deleted product family.

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

curl -X POST https://api.tokeflow.com/api/v1/merchant/product-families/obj_1a2b3c4d/restore \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
  -H "x-merchant-id: mrc_8a3f12d9"

Example response201

{
  "id": "pfa_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "name": "Streaming Plans",
  "slug": "streaming-plans",
  "description": "Family of streaming subscription plans",
  "custom_plan_id": "plan_external_42",
  "change_charge_behavior": "next_renew",
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

Errors

Errors use the standard envelope. The most common cases here:

HTTPMeaning
400Invalid parameters or a state that does not allow this operation.
401Missing, expired, or invalid Dashboard session token.
403Authenticated, but the signed-in user lacks access to this entity.
404The record does not exist or is not visible to this entity.

On this page