Skip to main content
GET
/
v1
/
products
/
{productId}
Get a product
curl --request GET \
  --url https://api-eu.flexportal.io/v1/products/{productId} \
  --header 'Authorization: Bearer <token>' \
  --header 'Tenant-ID: <tenant-id>'
{
  "productId": "<string>",
  "tenantId": "<string>",
  "productSku": "<string>",
  "name": "<string>",
  "specification": "<string>",
  "category": "<string>",
  "brand": "<string>",
  "status": "active",
  "createdAt": "<string>",
  "updatedAt": "<string>",
  "description": "<string>",
  "images": [
    "<string>"
  ],
  "_sync": {
    "source": "manual",
    "externalId": "<string>",
    "lastSyncedAt": "<string>",
    "syncStatus": "synced",
    "syncError": "<string>",
    "readOnlyFields": [
      "<string>"
    ]
  },
  "variants": [
    {
      "variantId": "<string>",
      "tenantId": "<string>",
      "productId": "<string>",
      "productSku": "<string>",
      "variantSku": "<string>",
      "variantName": "<string>",
      "grade": "<string>",
      "pricing": [
        {
          "contractLength": 123,
          "monthlyPrice": 123,
          "setupFee": 123,
          "discount": {
            "type": "percentage",
            "value": 123,
            "description": "<string>"
          },
          "source": "suggested",
          "calculatedAt": "<string>",
          "presetUsed": "<string>"
        }
      ],
      "status": "active",
      "createdAt": "<string>",
      "updatedAt": "<string>",
      "condition": "<string>",
      "colorName": "<string>",
      "images": [
        "<string>"
      ],
      "listPrice": 123,
      "acquisitionCost": 123
    }
  ]
}

Overview

Retrieve a single product by ID, including all its variants. Use this endpoint when you need complete product details including pricing for all configurations.

Common Use Cases

  • Product Detail Page: Display full product information with all available variants
  • Variant Selection: Show customers all available configurations and their pricing
  • Order Validation: Verify a variant exists and is active before creating an order
  • Pricing Display: Show subscription pricing for different contract lengths

Understanding Variants

Each variant represents a specific product configuration:
{
  "variantId": "var_abc123",
  "sku": "MACBOOK-PRO-16-M3-64GB-BLACK",
  "specification": "M3 Max, 64GB RAM, 1TB SSD",
  "grade": "A",
  "color": "Space Black",
  "status": "active",
  "listPrice": 3999.00,
  "acquisitionCost": 2800.00,
  "pricing": {
    "6": 249.00,
    "12": 189.00,
    "24": 149.00,
    "36": 129.00
  }
}

Variant Fields Explained

FieldDescription
skuUnique variant identifier used in orders
specificationTechnical specs (e.g., “M3 Max, 64GB”)
gradeCondition grade: A (like new) to E (refurbished)
colorColor option
statusactive or inactive
listPriceMSRP/retail price
acquisitionCostYour cost to acquire this variant
pricingMonthly prices by contract length (months)

Pricing by Contract Length

The pricing object maps contract lengths (in months) to monthly subscription prices:
{
  "pricing": {
    "6": 249.00,   // 6-month contract: €249/month
    "12": 189.00,  // 12-month contract: €189/month
    "24": 149.00,  // 24-month contract: €149/month
    "36": 129.00   // 36-month contract: €129/month
  }
}
Longer contracts typically have lower monthly prices. Configure your pricing tiers based on your cost recovery targets.

Grade Classification

Products are classified by condition:
GradeDescriptionTypical Use
ALike new, minimal wearPremium subscriptions
BLight wear, fully functionalStandard subscriptions
CVisible wear, fully functionalBudget subscriptions
DSignificant wear, functionalShort-term/value subscriptions
ERefurbished/repairedBudget/secondary market

Example: Building a Variant Selector

const product = await getProduct('prod_abc123');

// Group variants by specification
const variantsBySpec = {};
for (const variant of product.variants) {
  if (variant.status === 'active') {
    const spec = variant.specification;
    if (!variantsBySpec[spec]) {
      variantsBySpec[spec] = [];
    }
    variantsBySpec[spec].push(variant);
  }
}

// Display options to user
for (const [spec, variants] of Object.entries(variantsBySpec)) {
  console.log(`\n${spec}:`);
  for (const v of variants) {
    console.log(`  - ${v.color} (${v.grade}): €${v.pricing['24']}/mo for 24mo`);
  }
}

Authorizations

Authorization
string
header
required

API key obtained from FlexPortal dashboard

Headers

Tenant-ID
string
required

Your tenant identifier

Path Parameters

productId
string
required

The product ID

Response

Product details

productId
string
required
tenantId
string
required
productSku
string
required
name
string
required
specification
string
required
category
string
required
brand
string
required
status
enum<string>
required
Available options:
active,
discontinued
createdAt
string
required
updatedAt
string
required
description
string
images
string[]
_sync
object
variants
object[]