Skip to main content
POST
/
v1
/
products
Create a product
curl --request POST \
  --url https://api-eu.flexportal.io/v1/products \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'Tenant-ID: <tenant-id>' \
  --data '
{
  "productSku": "MACBOOK-PRO-16-M3",
  "name": "MacBook Pro 16\" M3 Pro",
  "category": "Laptops",
  "brand": "Apple",
  "specification": {
    "processor": "Apple M3 Pro",
    "memory": "18GB",
    "storage": "512GB SSD",
    "display": "16.2-inch Liquid Retina XDR"
  },
  "status": "active",
  "variants": [
    {
      "variantSku": "MACBOOK-PRO-16-M3-A",
      "variantName": "Grade A - Like New",
      "grade": "A",
      "listPrice": 2499,
      "acquisitionCost": 1800,
      "pricing": [
        {
          "contractLength": 12,
          "monthlyPrice": 149.99
        },
        {
          "contractLength": 24,
          "monthlyPrice": 99.99
        },
        {
          "contractLength": 36,
          "monthlyPrice": 79.99
        }
      ]
    },
    {
      "variantSku": "MACBOOK-PRO-16-M3-B",
      "variantName": "Grade B - Good",
      "grade": "B",
      "listPrice": 2199,
      "acquisitionCost": 1500,
      "pricing": [
        {
          "contractLength": 12,
          "monthlyPrice": 129.99
        },
        {
          "contractLength": 24,
          "monthlyPrice": 89.99
        },
        {
          "contractLength": 36,
          "monthlyPrice": 69.99
        }
      ]
    }
  ]
}
'
{
  "success": true,
  "message": "<string>",
  "productId": "<string>",
  "productSku": "<string>",
  "operation": "created",
  "variantResults": [
    {
      "variantSku": "<string>",
      "operation": "create"
    }
  ]
}

Overview

Create a new product with one or more variants. Products are the foundation of your subscription catalog—they define what customers can subscribe to, at what prices, and with what configurations.
This endpoint uses upsert behavior: if a product with the same productSku already exists, it will be updated instead of creating a duplicate.

Common Use Cases

New Product Launch

Add new products to your catalog when expanding your offering

Integration Sync

Sync products from your e-commerce platform or inventory system

Catalog Migration

Migrate products from another subscription platform

Partner Catalog

Onboard products from new suppliers or partners

Minimal Request Example

Create a simple product with one variant:
{
  "productSku": "MACBOOK-PRO-16",
  "name": "MacBook Pro 16\"",
  "specification": "Apple Silicon laptop",
  "category": "Laptops",
  "brand": "Apple",
  "variants": [
    {
      "variantSku": "MACBOOK-PRO-16-M3-BASE",
      "variantName": "M3 Pro, 18GB RAM, 512GB SSD",
      "grade": "A",
      "listPrice": 2499.00,
      "acquisitionCost": 1800.00,
      "pricing": [
        { "contractLength": 12, "monthlyPrice": 159.00 },
        { "contractLength": 24, "monthlyPrice": 129.00 },
        { "contractLength": 36, "monthlyPrice": 109.00 }
      ]
    }
  ]
}

Complete Request Example

Product with multiple variants for different configurations:
{
  "productSku": "MACBOOK-PRO-16",
  "name": "MacBook Pro 16\"",
  "specification": "Apple Silicon laptop",
  "category": "Laptops",
  "brand": "Apple",
  "description": "Professional laptop for creative and development work",
  "images": ["https://example.com/images/macbook-pro-16.jpg"],
  "variants": [
    {
      "variantSku": "MACBOOK-PRO-16-M3-18GB-SILVER",
      "variantName": "M3 Pro, 18GB RAM, 512GB SSD",
      "grade": "A",
      "colorName": "Silver",
      "listPrice": 2499.00,
      "acquisitionCost": 1800.00,
      "pricing": [
        { "contractLength": 6, "monthlyPrice": 199.00 },
        { "contractLength": 12, "monthlyPrice": 159.00 },
        { "contractLength": 24, "monthlyPrice": 129.00 },
        { "contractLength": 36, "monthlyPrice": 109.00 }
      ]
    },
    {
      "variantSku": "MACBOOK-PRO-16-M3MAX-64GB-BLACK",
      "variantName": "M3 Max, 64GB RAM, 1TB SSD",
      "grade": "A",
      "colorName": "Space Black",
      "listPrice": 3999.00,
      "acquisitionCost": 2800.00,
      "pricing": [
        { "contractLength": 6, "monthlyPrice": 319.00 },
        { "contractLength": 12, "monthlyPrice": 249.00 },
        { "contractLength": 24, "monthlyPrice": 199.00 },
        { "contractLength": 36, "monthlyPrice": 169.00 }
      ]
    },
    {
      "variantSku": "MACBOOK-PRO-16-M3-18GB-SILVER-B",
      "variantName": "M3 Pro, 18GB RAM, 512GB SSD",
      "grade": "B",
      "colorName": "Silver",
      "listPrice": 2499.00,
      "acquisitionCost": 1500.00,
      "pricing": [
        { "contractLength": 12, "monthlyPrice": 139.00 },
        { "contractLength": 24, "monthlyPrice": 109.00 },
        { "contractLength": 36, "monthlyPrice": 89.00 }
      ]
    }
  ]
}

Product Fields

FieldRequiredDescription
productSkuYesUnique product identifier (parent SKU)
nameYesDisplay name
specificationYesProduct specification/description
categoryYesProduct category (e.g., “Laptops”, “Phones”)
brandYesBrand/manufacturer
descriptionNoDetailed product description
imagesNoArray of product image URLs
variantsYesArray of variant configurations

Variant Fields

FieldRequiredDescription
variantSkuYesUnique variant SKU (used in orders)
variantNameYesVariant name/specification
gradeYesCondition: A, B, C, D, or E
colorNameNoColor option
listPriceNoMSRP/retail price
acquisitionCostNoYour cost to acquire
pricingYesArray of pricing tiers (see below)

Pricing Array Format

Each pricing tier in the pricing array:
FieldRequiredDescription
contractLengthYesContract duration in months (e.g., 12, 24, 36)
monthlyPriceYesMonthly subscription price
setupFeeNoOne-time setup fee
discountNoDiscount object with type (“percentage” or “fixed”) and value

Pricing Strategy

Set monthly prices based on your cost recovery goals:
// Example: Target 100% cost recovery in 24 months
const acquisitionCost = 1800;
const targetMonths = 24;
const marginPercent = 0.10; // 10% margin

const monthlyPrice = (acquisitionCost / targetMonths) * (1 + marginPercent);
// = 82.50/month for 24-month contract
Use shorter contract lengths for higher monthly prices (faster cost recovery) and longer contracts for lower monthly prices (better customer value).

Variant SKU Best Practices

Create predictable, searchable SKUs:
{PRODUCT}-{SPEC}-{CONFIG}-{GRADE}

Examples:
- MACBOOK-PRO-16-M3PRO-18GB-SILVER-A
- IPAD-PRO-12-M2-256GB-WIFI-B
- EBIKE-VANMOOF-S5-DARK-A

Upsert Behavior

When you create a product with an existing productSku:
  1. Product fields are updated with new values
  2. Existing variants (matching SKU) are updated
  3. New variants (new SKU) are added
  4. Missing variants (not in request) remain unchanged
To remove a variant, use the variant status update endpoint to set it to inactive. Variants are never automatically deleted.

Error Handling

Error CodeCauseSolution
VALIDATION_ERRORMissing required fieldsCheck details array for specific errors
DUPLICATE_SKUVariant SKU already exists on different productUse unique SKUs per variant
INVALID_PRICINGPricing array is invalidEach tier needs contractLength (integer) and monthlyPrice (number)

Authorizations

Authorization
string
header
required

API key obtained from FlexPortal dashboard

Headers

Tenant-ID
string
required

Your tenant identifier

Body

application/json
productSku
string
required
Minimum string length: 1
name
string
required
Minimum string length: 1
specification
string
required
Minimum string length: 1
category
string
required
Minimum string length: 1
brand
string
required
Minimum string length: 1
variants
object[]
required
Minimum array length: 1
description
string
images
string<uri>[]

Response

Product created

success
enum<boolean>
required
Available options:
true,
false
message
string
required
productId
string
required
productSku
string
required
operation
enum<string>
required
Available options:
created,
updated
variantResults
object[]
required