Products

List Product Components

Changed on

Returns the product components you have registered, newest first.

Only components you have recorded nutrition for are listed: the underlying name table is shared across accounts, so listing it would return tens of thousands of rows that belong to nobody.

Results are paginated — the default limit is 10, so reading back a full menu takes several requests. Pass the last object's component_nutrition_id as starting_after to fetch the next page, and keep going until a page comes back shorter than your limit.

Rather than paging the whole catalogue to find one ingredient, filter it: client_reference_id returns the single component carrying your own identifier, name matches the shared component name case-insensitively, and category and canonical_food_key narrow by those fields. Metadata is filtered with metadata[key]=value, with multiple keys AND-ed. Filters combine with each other and with the pagination cursors.

get/v1/product_components

Request

  • Base URL
    https://api.withflex.com
  • URL
    https://api.withflex.com/v1/product_components
  • Auth
    HTTP bearer

Query parameters

limitinteger nullable

A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.

offsetinteger nullable

Number of objects to skip before returning results.

starting_afterstring nullable

A cursor for use in pagination. starting_after is a component_nutrition_id that defines your place in the list — pass the one from the last object of the previous page to fetch the next.

Example:fcn_01J9XR8M3K7VZ8N2YB4WJ6T0RA
ending_beforestring nullable

A cursor for use in pagination. ending_before is a component_nutrition_id that defines your place in the list.

Example:fcn_01J9XR8M3K7VZ8N2YB4WJ6T0RA
client_reference_idstring nullable

Only return the component carrying this client_reference_id. The value is unique within your account and mode, so this returns at most one component — it is the direct answer to "have I registered this ingredient already?".

Example:example_value
category'base' | 'protein' | 'topping' | 'premium' | 'dressing'

A component's menu category.

An enum on the way in and a plain string on the way out, deliberately. product_component_nutrition.category is text with no CHECK constraint (per the company convention that the backend owns validation), so a row written by a backfill or by raw SQL can hold a value outside this set. Being strict on write keeps bad values out; being tolerant on read means such a row is still retrievable instead of 500ing on serialization.

The variants mirror [flex_core::product_metadata::VALID_CATEGORIES], which is what the write path actually validates against; test_component_category_matches_flex_core pins the two together so a category added there cannot be silently unreachable through the API.

  • base: The bowl's base — a grain, green or other foundation.
  • protein: A protein.
  • topping: A standard topping.
  • premium: A premium topping.
  • dressing: A dressing. The one category the eligibility engine gates differently.
Example:base

Only return components in this menu category.

canonical_food_keystring nullable

Only return components carrying this price-book join key.

namestring nullable

Only return components with this name, matched case-insensitively. Names are shared across accounts, so this is the dedupe lookup for a component you have no id for.

metadataobject

Filter by metadata key-value pairs using bracket syntax. For example: metadata[lookup_key]=premium-plan. Multiple keys use AND logic.

{
  "lookup_key": "premium-plan"
}

Response

An envelope wrapping a list of product component objects.

Example response

{
  "product_components": [
    {
      "component_id": "fcomp_01J9XR8M3K7VZ8N2YB4WJ6T0RA",
      "component_nutrition_id": "fcn_01J9XR8M3K7VZ8N2YB4WJ6T0RA",
      "name": "string",
      "shared": true,
      "test_mode": true,
      "category": "string",
      "serving_size_g": 0,
      "nutrition": {
        "calories": 0,
        "total_fat_g": 0,
        "saturated_fat_g": 0,
        "trans_fat_g": 0,
        "carbohydrate_g": 0,
        "fiber_g": 0,
        "protein_g": 0,
        "sodium_mg": 0,
        "added_sugar_g": 0
      },
      "vegan": true,
      "gluten_free": true,
      "canonical_food_key": "string",
      "client_reference_id": "string",
      "metadata": {},
      "created_at": "string",
      "updated_at": "string"
    }
  ]
}

Changes