Merchant products

Manage a merchant's products from the Dashboard — the sellable items customers pay for, one-time or recurring.

A product is something a merchant sells. It belongs to a product family and is sold through one or more offers that set the billing terms. These endpoints back the Dashboard's products screen: create, list, update, soft-delete, and restore.

A product is either one_time or recurring; the type shapes which offers and prices make sense for it. Products are soft-deleted so historical orders keep resolving to a real record.

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 object

Returned by the list and retrieve endpoints on this page.

FieldTypeDescription
idstring
merchant_idstring
product_family_idstring | null
namestring
descriptionstring | null
typestringOne of one_time, recurring.
tier_ordernumber | null
statusstringOne of active, archived.
metadataobject | null
created_atstring(ISO 8601 UTC).
updated_atstring(ISO 8601 UTC).

Endpoints

GET/api/v1/merchant/products

Merchant

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

List products.

Query parameters

FieldTypeRequiredDescription
pagenumberNoPage number (1-indexed). Default 1, min 1.
limitnumberNoNumber of items per page. Default 20, min 1, max 100.
typestringNoOne of one_time, recurring.
statusstringNoOne of active, archived.
product_family_idstringNoFilter products to a single family
namestringNoPartial-match filter on product name
date_fromstringNoFilter products created after this date (ISO 8601)
date_tostringNoFilter products created before this date (ISO 8601)

Example request

curl -G https://api.tokeflow.com/api/v1/merchant/products \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
  -H "x-merchant-id: mrc_8a3f12d9" \
  --data-urlencode "page=1" \
  --data-urlencode "limit=20" \
  --data-urlencode "type=recurring" \
  --data-urlencode "status=active"

Example response200

{
  "data": [
    {
      "id": "prd_a1b2c3d4e5",
      "merchant_id": "mrc_a1b2c3d4e5",
      "product_family_id": "pfa_a1b2c3d4e5",
      "name": "Plano Light",
      "description": "Plano com recursos essenciais",
      "type": "recurring",
      "tier_order": 1,
      "status": "active",
      "metadata": {
        "source": "dashboard"
      },
      "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/products

Merchant

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

Create a product.

Request fields

FieldTypeRequiredDescription
product_family_idstringNoOptional product family ID for grouping related products. Required for recurring with upgrade/downgrade.
namestringYes
descriptionstringNo
typestringYesOne of one_time, recurring.
tier_ordernumberNoPosition in family. Higher = superior plan. Required when product_family_id is set.
statusstringYesOne of active, archived.
metadataobjectNoArbitrary metadata (jsonb).

Example request

curl -X POST https://api.tokeflow.com/api/v1/merchant/products \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
  -H "x-merchant-id: mrc_8a3f12d9" \
  -H "Content-Type: application/json" \
  -d '{
    "product_family_id": "pfa_12345",
    "name": "Plano Light",
    "description": "Plano com recursos essenciais",
    "type": "recurring",
    "tier_order": 1,
    "status": "active",
    "metadata": {
      "source": "dashboard"
    }
  }'

Example response201

{
  "id": "prd_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "product_family_id": "pfa_a1b2c3d4e5",
  "name": "Plano Light",
  "description": "Plano com recursos essenciais",
  "type": "recurring",
  "tier_order": 1,
  "status": "active",
  "metadata": {
    "source": "dashboard"
  },
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

DELETE/api/v1/merchant/products/:id

Merchant

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

Refuses with 409 while any offer (active) or subscription (any status, via the offer) references the product. Delete the offers first; products referenced by subscriptions are kept for billing history.

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

curl -X DELETE https://api.tokeflow.com/api/v1/merchant/products/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/products/:id

Merchant

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

Get a product by ID.

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

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

Example response200

{
  "id": "prd_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "product_family_id": "pfa_a1b2c3d4e5",
  "name": "Plano Light",
  "description": "Plano com recursos essenciais",
  "type": "recurring",
  "tier_order": 1,
  "status": "active",
  "metadata": {
    "source": "dashboard"
  },
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

PATCH/api/v1/merchant/products/:id

Merchant

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

Update a product.

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

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

Example response200

{
  "id": "prd_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "product_family_id": "pfa_a1b2c3d4e5",
  "name": "Plano Light",
  "description": "Plano com recursos essenciais",
  "type": "recurring",
  "tier_order": 1,
  "status": "active",
  "metadata": {
    "source": "dashboard"
  },
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

POST/api/v1/merchant/products/:id/archive

Merchant

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

Archive a product (status = archived).

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

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

Example response201

{
  "id": "prd_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "product_family_id": "pfa_a1b2c3d4e5",
  "name": "Plano Light",
  "description": "Plano com recursos essenciais",
  "type": "recurring",
  "tier_order": 1,
  "status": "active",
  "metadata": {
    "source": "dashboard"
  },
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

GET/api/v1/merchant/products/:id/default-offer

Merchant

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

Get the default offer for a product (null if none).

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

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

Example response200

{}

POST/api/v1/merchant/products/:id/restore

Merchant

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

Restore a soft-deleted product.

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

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

Example response201

{
  "id": "prd_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "product_family_id": "pfa_a1b2c3d4e5",
  "name": "Plano Light",
  "description": "Plano com recursos essenciais",
  "type": "recurring",
  "tier_order": 1,
  "status": "active",
  "metadata": {
    "source": "dashboard"
  },
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:00:00Z"
}

POST/api/v1/merchant/products/:id/unarchive

Merchant

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

Unarchive a product (status = active).

Path parameters

FieldTypeRequiredDescription
idstringYes

Example request

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

Example response201

{
  "id": "prd_a1b2c3d4e5",
  "merchant_id": "mrc_a1b2c3d4e5",
  "product_family_id": "pfa_a1b2c3d4e5",
  "name": "Plano Light",
  "description": "Plano com recursos essenciais",
  "type": "recurring",
  "tier_order": 1,
  "status": "active",
  "metadata": {
    "source": "dashboard"
  },
  "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