Registers a product component (an ingredient) and returns it with an fcomp_
identifier you can attach to products.
Nutrient values are stored per 100 g of the component. Send nutrition_basis: "as_served" with a serving_size_g to have per-serving figures converted for
you. Component names are matched case-insensitively against a shared name table,
so registering a name another account already registered returns that same
component_id with your own nutrition attached.
Registering something you already have is a 409. That covers both ways it
happens: describing the same component twice in the same mode, and reusing a
client_reference_id on a different component. Both mean the same thing —
this ingredient is already registered, PATCH it instead — so a menu sync can
treat 409 as “switch to update” without inspecting the message.
Pass a client_reference_id to carry your own identifier for the ingredient.
It is unique within your account and mode, which is what lets you look a
component back up with
GET /v1/product_components?client_reference_id=… instead of paging your
catalogue. The same value may be used by another account, and by you in your
other mode.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Flex Documentation","colors":{"primary":"#0070FA","light":"#BAB3FF","dark":"#0B0077"},"logo":{"light":"https://mintcdn.com/flex-87/1kILreF5HcjIKLdi/logo/light.svg?fit=max\u0026auto=format\u0026n=1kILreF5HcjIKLdi\u0026q=85\u0026s=f703a75bc80df014f4849a7225b4879f","dark":"https://mintcdn.com/flex-87/1kILreF5HcjIKLdi/logo/dark.svg?fit=max\u0026auto=format\u0026n=1kILreF5HcjIKLdi\u0026q=85\u0026s=1aabf14d790c002d1740276fdbced9ab"},"favicon":"https://mintcdn.com/flex-87/liG_HQMgKKwndFp8/favicon.svg?fit=max\u0026auto=format\u0026n=liG_HQMgKKwndFp8\u0026q=85\u0026s=82a2993b4fffbf19268067f48e898bed","navbar":{"primary":{"type":"button","label":"Dashboard","href":"https://dashboard.withflex.com/"}},"footer":{"socials":{"github":"https://github.com/JoinFlexHealth","linkedin":"https://www.linkedin.com/company/withflex","x":"https://x.com/paywithflex","instagram":"https://www.instagram.com/paywithflex"}},"icons":{"library":"lucide"},"styling":{"eyebrows":"breadcrumbs","latex":true},"navigation":{"global":{"anchors":[{"anchor":"Status","icon":"wifi","href":"https://statuspage.incident.io/with-flex"},{"anchor":"Support","icon":"mail","href":"mailto:support@withflex.com"},{"anchor":"Website","icon":"laptop","href":"https://www.withflex.com"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"flex-87","hasAudioNarration":false,"actualSubdomain":"flex-87","customDomains":["docs.withflex.com"],"gitSource":{"type":"github","owner":"joinflexhealth","repo":"flex","deployBranch":"main","contentDirectory":"flex-docs","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6aee6975cd3f5bf5212d16fd","clientVersion":"0.0.4087","searchFilterCounts":[{"language":"default","tag":"API Reference","count":188},{"language":"default","tag":"Guides","count":51},{"language":"default","tag":"Integration","count":29},{"language":"default","tag":"Marketing","count":21},{"language":"default","tag":"Checkout Sessions","count":13},{"language":"default","tag":"Subscriptions","count":12},{"language":"default","tag":"Products","count":9},{"language":"default","tag":"Disputes","count":8},{"language":"default","tag":"Shopify","count":7},{"language":"default","tag":"Overview","count":7}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"#topbar-cta-button span.bg-primary-dark{background-color:#0B0077!important}html.dark #topbar-cta-button span.bg-primary-dark{background-color:#BAB3FF1A!important;border-color:#BAB3FF;border-width:1px}main img,article img,.content img,[data-content] img{border:1px solid #E8EAED!important}main img.rounded,article img.rounded,.content img.rounded,[data-content] img.rounded{border:.5px solid #E8EAED!important}.nav-logo,img.nav-logo{border:none!important}.brand-logo-grid img{border:none!important}.doc-screenshot img{border:none!important}img.no-border{border:none!important}.nav-anchor:hover .mr-4.rounded-md.p-1.shadow-sm{background:rgba(17, 24, 39, 0.05)!important;background-color:rgba(17, 24, 39, 0.05)!important;color:#1f2937!important;--tw-ring-opacity: 1 !important;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)!important;filter:none!important}.dark .nav-anchor:hover .mr-4.rounded-md.p-1.shadow-sm{background:rgba(229, 231, 235, 0.05)!important;background-color:rgba(229, 231, 235, 0.05)!important;color:#d1d5db!important;--tw-ring-opacity: 1 !important;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)!important;filter:none!important}.group:hover .group-hover\\:ring-0{--tw-ring-opacity: 1 !important;--tw-ring-color: rgba(17, 24, 39, 0.05) !important}.dark .group:hover .group-hover\\:ring-0{--tw-ring-opacity: 1 !important;--tw-ring-color: rgba(55, 65, 81, 0.4) !important}.nav-anchor:hover .secondary-opacity.group-hover\\:fill-primary-dark.group-hover\\:bg-white{background-color:currentColor!important;fill:none!important}.nav-anchor:hover .secondary-opacity{background-color:#1f2937!important}.dark .nav-anchor:hover .secondary-opacity{background-color:#d1d5db!important}.nav-anchor .mr-4.rounded-md.p-1.shadow-sm[style*=\"background\"]{background:inherit!important;background-color:inherit!important}.nav-anchor:hover .mr-4.rounded-md.p-1.shadow-sm[style*=\"background\"]{background:rgba(17, 24, 39, 0.05)!important;background-color:rgba(17, 24, 39, 0.05)!important}.dark .nav-anchor:hover .mr-4.rounded-md.p-1.shadow-sm[style*=\"background\"]{background:rgba(229, 231, 235, 0.05)!important;background-color:rgba(229, 231, 235, 0.05)!important}.nav-anchor:hover .h-4.w-4.secondary-opacity{background-color:currentColor!important}.inline-flex.items-center.gap-1\\.5.text-sm.text-gray-500 a{color:#0070FA!important}.inline-flex.items-center.gap-1\\.5.text-sm.text-gray-500 a:hover{color:#0B0077!important}html.dark .inline-flex.items-center.gap-1\\.5.text-sm a{color:#BAB3FF!important}html.dark .inline-flex.items-center.gap-1\\.5.text-sm a:hover{color:white!important}.lucide.lucide-chevron-right{stroke:#0070FA!important}html.dark .lucide.lucide-chevron-right{stroke:#BAB3FF!important}"}],"page":{"pagePath":"api-reference/products/create-product-component","slug":"/api-reference/products/create-product-component","pageMetadata":{"title":"Create Product Component","description":"Registers a product component (an ingredient) and returns it with an `fcomp_`\nidentifier you can attach to products.\n\nNutrient values are stored per 100 g of the component. Send `nutrition_basis:\n\"as_served\"` with a `serving_size_g` to have per-serving figures converted for\nyou. Component names are matched case-insensitively against a shared name table,\nso registering a name another account already registered returns that same\n`component_id` with your own nutrition attached.\n\n**Registering something you already have is a `409`.** That covers both ways it\nhappens: describing the same component twice in the same mode, and reusing a\n`client_reference_id` on a different component. Both mean the same thing —\nthis ingredient is already registered, `PATCH` it instead — so a menu sync can\ntreat `409` as \"switch to update\" without inspecting the message.\n\nPass a `client_reference_id` to carry your own identifier for the ingredient.\nIt is unique within your account and mode, which is what lets you look a\ncomponent back up with\n`GET /v1/product_components?client_reference_id=…` instead of paging your\ncatalogue. The same value may be used by another account, and by you in your\nother mode.","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/product_components","href":"/api-reference/products/create-product-component","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Registers a product component (an ingredient) and returns it with an \", _jsx(_components.code, {\n children: \"fcomp_\"\n }), \"\\nidentifier you can attach to products.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Nutrient values are stored per 100 g of the component. Send \", _jsx(_components.code, {\n children: \"nutrition_basis: \\\"as_served\\\"\"\n }), \" with a \", _jsx(_components.code, {\n children: \"serving_size_g\"\n }), \" to have per-serving figures converted for\\nyou. Component names are matched case-insensitively against a shared name table,\\nso registering a name another account already registered returns that same\\n\", _jsx(_components.code, {\n children: \"component_id\"\n }), \" with your own nutrition attached.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsxs(_components.strong, {\n children: [\"Registering something you already have is a \", _jsx(_components.code, {\n children: \"409\"\n }), \".\"]\n }), \" That covers both ways it\\nhappens: describing the same component twice in the same mode, and reusing a\\n\", _jsx(_components.code, {\n children: \"client_reference_id\"\n }), \" on a different component. Both mean the same thing —\\nthis ingredient is already registered, \", _jsx(_components.code, {\n children: \"PATCH\"\n }), \" it instead — so a menu sync can\\ntreat \", _jsx(_components.code, {\n children: \"409\"\n }), \" as “switch to update” without inspecting the message.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Pass a \", _jsx(_components.code, {\n children: \"client_reference_id\"\n }), \" to carry your own identifier for the ingredient.\\nIt is unique within your account and mode, which is what lets you look a\\ncomponent back up with\\n\", _jsx(_components.code, {\n children: \"GET /v1/product_components?client_reference_id=…\"\n }), \" instead of paging your\\ncatalogue. The same value may be used by another account, and by you in your\\nother mode.\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Create Product Component","description":"Registers a product component (an ingredient) and returns it with an `fcomp_`\nidentifier you can attach to products.\n\nNutrient values are stored per 100 g of the component. Send `nutrition_basis:\n\"as_served\"` with a `serving_size_g` to have per-serving figures converted for\nyou. Component names are matched case-insensitively against a shared name table,\nso registering a name another account already registered returns that same\n`component_id` with your own nutrition attached.\n\n**Registering something you already have is a `409`.** That covers both ways it\nhappens: describing the same component twice in the same mode, and reusing a\n`client_reference_id` on a different component. Both mean the same thing —\nthis ingredient is already registered, `PATCH` it instead — so a menu sync can\ntreat `409` as \"switch to update\" without inspecting the message.\n\nPass a `client_reference_id` to carry your own identifier for the ingredient.\nIt is unique within your account and mode, which is what lets you look a\ncomponent back up with\n`GET /v1/product_components?client_reference_id=…` instead of paging your\ncatalogue. The same value may be used by another account, and by you in your\nother mode.","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/product_components","href":"/api-reference/products/create-product-component","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":["/_mintlify/custom/flex-87/f0156321fafa1974/postcss.config.js"],"openApiReferenceData":{"operation":{"tags":["Products"],"summary":"Create Product Component","description":"Registers a product component (an ingredient) and returns it with an `fcomp_`\nidentifier you can attach to products.\n\nNutrient values are stored per 100 g of the component. Send `nutrition_basis:\n\"as_served\"` with a `serving_size_g` to have per-serving figures converted for\nyou. Component names are matched case-insensitively against a shared name table,\nso registering a name another account already registered returns that same\n`component_id` with your own nutrition attached.\n\n**Registering something you already have is a `409`.** That covers both ways it\nhappens: describing the same component twice in the same mode, and reusing a\n`client_reference_id` on a different component. Both mean the same thing —\nthis ingredient is already registered, `PATCH` it instead — so a menu sync can\ntreat `409` as \"switch to update\" without inspecting the message.\n\nPass a `client_reference_id` to carry your own identifier for the ingredient.\nIt is unique within your account and mode, which is what lets you look a\ncomponent back up with\n`GET /v1/product_components?client_reference_id=…` instead of paging your\ncatalogue. The same value may be used by another account, and by you in your\nother mode.","operationId":"v1.product_components.create","requestBody":"053756dc-138a-4d30-824c-8b9e7e7cfd68","responses":{"200":"e12e9a48-98a1-4e1a-9aff-1ce96e420725","401":"71e332d9-83bc-4dea-a3b0-8014bd74412e","403":"8b8f4c3d-cadb-4ac9-99c7-57b8badc9c0f","404":"fc6bc8ec-236b-4a99-b9a0-ed919f19c837","409":"9b8cb94f-ef82-4470-94bc-518145f8bf48","422":"f53f4d91-7673-460d-875b-815eba516255","429":"7851b792-8910-417d-b516-4b5c8550acbf"},"security":["8895d132-315f-48e7-ac67-e9e4ac8cb797"],"method":"post","type":"path","servers":["080577c1-39a5-4498-bb49-d7daab803f21"],"path":"/v1/product_components","baseUrlOptions":["https://api.withflex.com"],"title":"Create Product Component","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"description":"An envelope wrapping a single product component object.","content":{"application/json":{"schema":{"description":"An envelope wrapping a single product component object.","type":"object","required":["product_component"],"properties":{"product_component":{"description":"The product component object.","type":"object","required":["category","name"],"properties":{"name":{"description":"The component's name, e.g. `\"kale\"`. Trimmed and lowercased before storage.","type":"string","isRequired":true,"uniqueKey":"product_component.name","typeLabel":"string"},"category":{"type":"string","enum":["base","protein","topping","premium","dressing"],"x-ms-enum":{"name":"ComponentCategory","modelAsString":false,"values":[{"value":"base","name":"Base","description":"The bowl's base — a grain, green or other foundation."},{"value":"protein","name":"Protein","description":"A protein."},{"value":"topping","name":"Topping","description":"A standard topping."},{"value":"premium","name":"Premium","description":"A premium topping."},{"value":"dressing","name":"Dressing","description":"A dressing. The one category the eligibility engine gates differently."}]},"description":"The component's menu category.","example":"base","isRequired":true,"uniqueKey":"product_component.category","typeLabel":"enum\u003cstring>"},"nutrition_basis":{"oneOf":[{"type":"string","description":"The basis `nutrition` is expressed on. Defaults to `per_100g`.","enum":["per_100g","as_served"],"x-ms-enum":{"name":"NutritionBasis","modelAsString":false,"values":[{"value":"per_100g","name":"Per100g","description":"The values are already per 100 g. The default."},{"value":"as_served","name":"AsServed","description":"The values describe one `serving_size_g` portion as served, and are converted to per 100 g before being stored."}]},"example":"per_100g","uniqueKey":"product_component.nutrition_basis.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","description":"The basis `nutrition` is expressed on. Defaults to `per_100g`.","uniqueKey":"product_component.nutrition_basis.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition_basis","typeLabel":"enum\u003cstring> | null"},"serving_size_g":{"oneOf":[{"description":"The standard portion of this component, in grams. Not a per-100 g nutrient: it is never rescaled, and it is what `as_served` figures are converted by.","type":"number","format":"double","uniqueKey":"product_component.serving_size_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"The standard portion of this component, in grams. Not a per-100 g nutrient: it is never rescaled, and it is what `as_served` figures are converted by.","type":"null","format":"double","uniqueKey":"product_component.serving_size_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.serving_size_g","typeLabel":"number\u003cdouble> | null"},"nutrition":{"oneOf":[{"type":"object","description":"Nutrient values. Omit any you do not have; a missing value stays \"not supplied\" rather than becoming zero.","example":{"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},"properties":{"calories":{"oneOf":[{"description":"Energy, kcal per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.calories.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Energy, kcal per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.calories.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.calories","typeLabel":"number\u003cdouble> | null"},"total_fat_g":{"oneOf":[{"description":"Total fat, g per 100 g. Informational — the eligibility gate uses saturated fat.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.total_fat_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Total fat, g per 100 g. Informational — the eligibility gate uses saturated fat.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.total_fat_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.total_fat_g","typeLabel":"number\u003cdouble> | null"},"saturated_fat_g":{"oneOf":[{"description":"Saturated fat, g per 100 g. This is the fat the eligibility gate uses.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.saturated_fat_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Saturated fat, g per 100 g. This is the fat the eligibility gate uses.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.saturated_fat_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.saturated_fat_g","typeLabel":"number\u003cdouble> | null"},"trans_fat_g":{"oneOf":[{"description":"Trans fat, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.trans_fat_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Trans fat, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.trans_fat_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.trans_fat_g","typeLabel":"number\u003cdouble> | null"},"carbohydrate_g":{"oneOf":[{"description":"Carbohydrate, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.carbohydrate_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Carbohydrate, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.carbohydrate_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.carbohydrate_g","typeLabel":"number\u003cdouble> | null"},"fiber_g":{"oneOf":[{"description":"Fiber, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.fiber_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Fiber, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.fiber_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.fiber_g","typeLabel":"number\u003cdouble> | null"},"protein_g":{"oneOf":[{"description":"Protein, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.protein_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Protein, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.protein_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.protein_g","typeLabel":"number\u003cdouble> | null"},"sodium_mg":{"oneOf":[{"description":"Sodium, mg per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.sodium_mg.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Sodium, mg per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.sodium_mg.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.sodium_mg","typeLabel":"number\u003cdouble> | null"},"added_sugar_g":{"oneOf":[{"description":"Added sugar, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.added_sugar_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Added sugar, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.oneOf.0.added_sugar_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.oneOf.0.added_sugar_g","typeLabel":"number\u003cdouble> | null"}},"uniqueKey":"product_component.nutrition.oneOf.0","typeLabel":"object"},{"type":"null","description":"Nutrient values. Omit any you do not have; a missing value stays \"not supplied\" rather than becoming zero.","uniqueKey":"product_component.nutrition.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition","typeLabel":"object | null"},"vegan":{"oneOf":[{"description":"Whether the component is vegan. Defaults to `false`.","type":"boolean","uniqueKey":"product_component.vegan.oneOf.0","typeLabel":"boolean"},{"description":"Whether the component is vegan. Defaults to `false`.","type":"null","uniqueKey":"product_component.vegan.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.vegan","typeLabel":"boolean | null"},"gluten_free":{"oneOf":[{"description":"Whether the component is gluten-free. Defaults to `false`.","type":"boolean","uniqueKey":"product_component.gluten_free.oneOf.0","typeLabel":"boolean"},{"description":"Whether the component is gluten-free. Defaults to `false`.","type":"null","uniqueKey":"product_component.gluten_free.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.gluten_free","typeLabel":"boolean | null"},"canonical_food_key":{"oneOf":[{"description":"The join key into Flex's national price book. Optional here — the eligibility engine, not this endpoint, is what requires it for a non-dressing component.\n\nStored normalized: lowercased, trimmed, and with hyphens folded into underscores, so `Goat-Cheese` is saved and returned as `goat_cheese`. The price book is snake_case throughout, and this is what makes your spelling and ours the same key.","type":"string","uniqueKey":"product_component.canonical_food_key.oneOf.0","typeLabel":"string"},{"description":"The join key into Flex's national price book. Optional here — the eligibility engine, not this endpoint, is what requires it for a non-dressing component.\n\nStored normalized: lowercased, trimmed, and with hyphens folded into underscores, so `Goat-Cheese` is saved and returned as `goat_cheese`. The price book is snake_case throughout, and this is what makes your spelling and ours the same key.","type":"null","uniqueKey":"product_component.canonical_food_key.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.canonical_food_key","typeLabel":"string | null"},"client_reference_id":{"oneOf":[{"description":"Your own identifier for this ingredient — a menu item id, POS SKU, or whatever your catalogue keys on.\n\nUnique within your account and mode, so a re-sync that reuses one is a `409` rather than a second component pointing at the same ingredient. That is what makes it usable as a sync key: register once, then look the component up with `GET /v1/product_components?client_reference_id=…` instead of paging your whole catalogue. Another account may use the same value for their own ingredient, and so may you in your other mode.","type":"string","example":"example_value","uniqueKey":"product_component.client_reference_id.oneOf.0","typeLabel":"string"},{"description":"Your own identifier for this ingredient — a menu item id, POS SKU, or whatever your catalogue keys on.\n\nUnique within your account and mode, so a re-sync that reuses one is a `409` rather than a second component pointing at the same ingredient. That is what makes it usable as a sync key: register once, then look the component up with `GET /v1/product_components?client_reference_id=…` instead of paging your whole catalogue. Another account may use the same value for their own ingredient, and so may you in your other mode.","type":"null","example":"example_value","uniqueKey":"product_component.client_reference_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.client_reference_id","typeLabel":"string | null"},"metadata":{"oneOf":[{"description":"Key-value pairs to store on the component. Yours to read back; Flex does not interpret them.","type":"object","additionalProperties":{"type":"string","uniqueKey":"product_component.metadata.oneOf.0.additionalProperties","typeLabel":"string"},"example":{"order_id":"8842","channel":"shopify"},"uniqueKey":"product_component.metadata.oneOf.0","typeLabel":"object"},{"description":"Key-value pairs to store on the component. Yours to read back; Flex does not interpret them.","type":"null","additionalProperties":{"type":"string","uniqueKey":"product_component.metadata.oneOf.1.additionalProperties","typeLabel":"string"},"example":{"order_id":"8842","channel":"shopify"},"uniqueKey":"product_component.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.metadata","typeLabel":"object | null"}},"example":{"name":"string","category":"base","nutrition_basis":"per_100g","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":"example_value","metadata":{"order_id":"8842","channel":"shopify"}},"isRequired":true,"uniqueKey":"product_component","typeLabel":"object"}},"example":{"product_component":{"name":"string","category":"base","nutrition_basis":"per_100g","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":"example_value","metadata":{"order_id":"8842","channel":"shopify"}}},"uniqueKey":"","typeLabel":"object"},"example":{"product_component":{"name":"string","category":"base","nutrition_basis":"per_100g","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":"example_value","metadata":{"order_id":"8842","channel":"shopify"}}},"examples":{"Example":{"title":"Example","value":{"product_component":{"name":"string","category":"base","nutrition_basis":"per_100g","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":"example_value","metadata":{"order_id":"8842","channel":"shopify"}}}}},"exampleType":"examples"}},"required":true,"exampleType":"examples"},"responses":{"e12e9a48-98a1-4e1a-9aff-1ce96e420725":{"description":"An envelope wrapping a single product component object.","content":{"application/json":{"schema":{"description":"An envelope wrapping a single product component object.","type":"object","required":["product_component"],"properties":{"product_component":{"description":"The product component object.","type":"object","required":["category","component_id","component_nutrition_id","created_at","gluten_free","name","nutrition","shared","test_mode","vegan"],"properties":{"component_id":{"description":"The component's unique identifier. This is the id `component_items` on `PATCH /v1/products/{id}` accepts.","type":"string","example":"fcomp_01J9XR8M3K7VZ8N2YB4WJ6T0RA","isRequired":true,"uniqueKey":"product_component.component_id","typeLabel":"string"},"component_nutrition_id":{"description":"The identifier of the nutrition record holding your figures for this component.","type":"string","example":"fcn_01J9XR8M3K7VZ8N2YB4WJ6T0RA","isRequired":true,"uniqueKey":"product_component.component_nutrition_id","typeLabel":"string"},"name":{"description":"The component's name, normalized to lowercase.","type":"string","isRequired":true,"uniqueKey":"product_component.name","typeLabel":"string"},"shared":{"description":"Whether the underlying name row is shared across partners rather than owned by you. `true` for everything registered through this endpoint today, which is why the name cannot be changed.","type":"boolean","isRequired":true,"uniqueKey":"product_component.shared","typeLabel":"boolean"},"test_mode":{"description":"Whether these figures belong to test mode.","type":"boolean","isRequired":true,"uniqueKey":"product_component.test_mode","typeLabel":"boolean"},"category":{"description":"The component's menu category.","type":"string","isRequired":true,"uniqueKey":"product_component.category","typeLabel":"string"},"nutrition":{"description":"Nutrient values, per 100 g.","type":"object","properties":{"calories":{"oneOf":[{"description":"Energy, kcal per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.calories.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Energy, kcal per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.calories.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.calories","typeLabel":"number\u003cdouble> | null"},"total_fat_g":{"oneOf":[{"description":"Total fat, g per 100 g. Informational — the eligibility gate uses saturated fat.","type":"number","format":"double","uniqueKey":"product_component.nutrition.total_fat_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Total fat, g per 100 g. Informational — the eligibility gate uses saturated fat.","type":"null","format":"double","uniqueKey":"product_component.nutrition.total_fat_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.total_fat_g","typeLabel":"number\u003cdouble> | null"},"saturated_fat_g":{"oneOf":[{"description":"Saturated fat, g per 100 g. This is the fat the eligibility gate uses.","type":"number","format":"double","uniqueKey":"product_component.nutrition.saturated_fat_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Saturated fat, g per 100 g. This is the fat the eligibility gate uses.","type":"null","format":"double","uniqueKey":"product_component.nutrition.saturated_fat_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.saturated_fat_g","typeLabel":"number\u003cdouble> | null"},"trans_fat_g":{"oneOf":[{"description":"Trans fat, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.trans_fat_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Trans fat, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.trans_fat_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.trans_fat_g","typeLabel":"number\u003cdouble> | null"},"carbohydrate_g":{"oneOf":[{"description":"Carbohydrate, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.carbohydrate_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Carbohydrate, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.carbohydrate_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.carbohydrate_g","typeLabel":"number\u003cdouble> | null"},"fiber_g":{"oneOf":[{"description":"Fiber, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.fiber_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Fiber, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.fiber_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.fiber_g","typeLabel":"number\u003cdouble> | null"},"protein_g":{"oneOf":[{"description":"Protein, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.protein_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Protein, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.protein_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.protein_g","typeLabel":"number\u003cdouble> | null"},"sodium_mg":{"oneOf":[{"description":"Sodium, mg per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.sodium_mg.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Sodium, mg per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.sodium_mg.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.sodium_mg","typeLabel":"number\u003cdouble> | null"},"added_sugar_g":{"oneOf":[{"description":"Added sugar, g per 100 g.","type":"number","format":"double","uniqueKey":"product_component.nutrition.added_sugar_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"Added sugar, g per 100 g.","type":"null","format":"double","uniqueKey":"product_component.nutrition.added_sugar_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.nutrition.added_sugar_g","typeLabel":"number\u003cdouble> | null"}},"example":{"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},"isRequired":true,"uniqueKey":"product_component.nutrition","typeLabel":"object"},"vegan":{"description":"Whether the component is vegan.","type":"boolean","isRequired":true,"uniqueKey":"product_component.vegan","typeLabel":"boolean"},"gluten_free":{"description":"Whether the component is gluten-free.","type":"boolean","isRequired":true,"uniqueKey":"product_component.gluten_free","typeLabel":"boolean"},"created_at":{"description":"When these figures were first recorded.","type":"string","example":"string","isRequired":true,"uniqueKey":"product_component.created_at","typeLabel":"string"},"serving_size_g":{"oneOf":[{"description":"The standard portion, in grams. Not a per-100 g nutrient.","type":"number","format":"double","uniqueKey":"product_component.serving_size_g.oneOf.0","typeLabel":"number\u003cdouble>"},{"description":"The standard portion, in grams. Not a per-100 g nutrient.","type":"null","format":"double","uniqueKey":"product_component.serving_size_g.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.serving_size_g","typeLabel":"number\u003cdouble> | null"},"canonical_food_key":{"oneOf":[{"description":"The join key into Flex's national price book, or `null` if not yet mapped.","type":"string","uniqueKey":"product_component.canonical_food_key.oneOf.0","typeLabel":"string"},{"description":"The join key into Flex's national price book, or `null` if not yet mapped.","type":"null","uniqueKey":"product_component.canonical_food_key.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.canonical_food_key","typeLabel":"string | null"},"client_reference_id":{"oneOf":[{"description":"Your own identifier for this ingredient, or `null` if you did not set one.","type":"string","uniqueKey":"product_component.client_reference_id.oneOf.0","typeLabel":"string"},{"description":"Your own identifier for this ingredient, or `null` if you did not set one.","type":"null","uniqueKey":"product_component.client_reference_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.client_reference_id","typeLabel":"string | null"},"metadata":{"oneOf":[{"description":"The key-value pairs you stored on this component, or `null` if none.","type":"object","additionalProperties":{"type":"string","uniqueKey":"product_component.metadata.oneOf.0.additionalProperties","typeLabel":"string"},"uniqueKey":"product_component.metadata.oneOf.0","typeLabel":"object"},{"description":"The key-value pairs you stored on this component, or `null` if none.","type":"null","additionalProperties":{"type":"string","uniqueKey":"product_component.metadata.oneOf.1.additionalProperties","typeLabel":"string"},"uniqueKey":"product_component.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.metadata","typeLabel":"object | null"},"updated_at":{"oneOf":[{"type":"string","description":"When these figures were last changed, or `null` if never.","example":"string","uniqueKey":"product_component.updated_at.oneOf.0","typeLabel":"string"},{"type":"null","description":"When these figures were last changed, or `null` if never.","uniqueKey":"product_component.updated_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"product_component.updated_at","typeLabel":"string | null"}},"example":{"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"},"isRequired":true,"uniqueKey":"product_component","typeLabel":"object"}},"example":{"product_component":{"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"}},"uniqueKey":"","typeLabel":"object"},"example":{"product_component":{"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"}},"examples":{"Example":{"title":"Example","value":{"product_component":{"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"}}}},"exampleType":"examples"}},"exampleType":"examples"},"71e332d9-83bc-4dea-a3b0-8014bd74412e":{"description":"Unauthorized","content":{"application/json":{"schema":{"title":"HttpError","description":"The error response returned when a request cannot be completed.","type":"object","required":["code","detail"],"properties":{"code":{"description":"A short machine-readable error code identifying the type of error.","type":"string","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"detail":{"description":"A human-readable explanation of what went wrong.","type":"string","isRequired":true,"uniqueKey":"detail","typeLabel":"string"}},"example":{"code":"string","detail":"string"},"uniqueKey":"","typeLabel":"HttpError · object"},"example":{"code":"string","detail":"string"},"examples":{"Example":{"title":"Example","value":{"code":"string","detail":"string"}}},"exampleType":"examples"}},"exampleType":"examples"},"8b8f4c3d-cadb-4ac9-99c7-57b8badc9c0f":{"description":"Forbidden","content":{"application/json":{"schema":{"title":"HttpError","description":"The error response returned when a request cannot be completed.","type":"object","required":["code","detail"],"properties":{"code":{"description":"A short machine-readable error code identifying the type of error.","type":"string","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"detail":{"description":"A human-readable explanation of what went wrong.","type":"string","isRequired":true,"uniqueKey":"detail","typeLabel":"string"}},"example":{"code":"string","detail":"string"},"uniqueKey":"","typeLabel":"HttpError · object"},"example":{"code":"string","detail":"string"},"examples":{"Example":{"title":"Example","value":{"code":"string","detail":"string"}}},"exampleType":"examples"}},"exampleType":"examples"},"fc6bc8ec-236b-4a99-b9a0-ed919f19c837":{"description":"Not Found","content":{"application/json":{"schema":{"title":"HttpError","description":"The error response returned when a request cannot be completed.","type":"object","required":["code","detail"],"properties":{"code":{"description":"A short machine-readable error code identifying the type of error.","type":"string","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"detail":{"description":"A human-readable explanation of what went wrong.","type":"string","isRequired":true,"uniqueKey":"detail","typeLabel":"string"}},"example":{"code":"string","detail":"string"},"uniqueKey":"","typeLabel":"HttpError · object"},"example":{"code":"string","detail":"string"},"examples":{"Example":{"title":"Example","value":{"code":"string","detail":"string"}}},"exampleType":"examples"}},"exampleType":"examples"},"9b8cb94f-ef82-4470-94bc-518145f8bf48":{"description":"Conflict","content":{"application/json":{"schema":{"title":"HttpError","description":"The error response returned when a request cannot be completed.","type":"object","required":["code","detail"],"properties":{"code":{"description":"A short machine-readable error code identifying the type of error.","type":"string","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"detail":{"description":"A human-readable explanation of what went wrong.","type":"string","isRequired":true,"uniqueKey":"detail","typeLabel":"string"}},"example":{"code":"string","detail":"string"},"uniqueKey":"","typeLabel":"HttpError · object"},"example":{"code":"string","detail":"string"},"examples":{"Example":{"title":"Example","value":{"code":"string","detail":"string"}}},"exampleType":"examples"}},"exampleType":"examples"},"f53f4d91-7673-460d-875b-815eba516255":{"description":"Validation Error","content":{"application/json":{"schema":{"description":"The error response returned when request validation fails (HTTP 422).","type":"object","required":["detail"],"properties":{"detail":{"description":"The list of validation errors, one entry per invalid field.","type":"array","items":{"description":"Validation errors have their own schema to provide context for invalid requests eg. mismatched types and out of bounds values. There may be any number of these per 422 UNPROCESSABLE ENTITY error.","type":"object","required":["loc","msg","type"],"properties":{"loc":{"description":"The location as a [`Vec`] of [`String`]s -- often in the form `[\"body\", \"field_name\"]`, `[\"query\", \"field_name\"]`, etc. They may, however, be arbitarily deep.","type":"array","items":{"type":"string","uniqueKey":"detail.items.[INDEX].loc.items.[INDEX]","typeLabel":"string"},"isRequired":true,"uniqueKey":"detail.items.[INDEX].loc","typeLabel":"string[]"},"msg":{"description":"The message accompanying the validation error item.","type":"string","isRequired":true,"uniqueKey":"detail.items.[INDEX].msg","typeLabel":"string"},"type":{"description":"The type of error, often \"type_error\" or \"value_error\", but sometimes with more context like as \"value_error.number.not_ge\"","type":"string","isRequired":true,"uniqueKey":"detail.items.[INDEX].type","typeLabel":"string"}},"example":{"loc":["string"],"msg":"string","type":"string"},"uniqueKey":"detail.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"detail","typeLabel":"object[]"}},"example":{"detail":[{"loc":["string"],"msg":"string","type":"string"}]},"uniqueKey":"","typeLabel":"object"},"example":{"detail":[{"loc":["string"],"msg":"string","type":"string"}]},"examples":{"Example":{"title":"Example","value":{"detail":[{"loc":["string"],"msg":"string","type":"string"}]}}},"exampleType":"examples"}},"exampleType":"examples"},"7851b792-8910-417d-b516-4b5c8550acbf":{"description":"Too Many Requests","content":{"application/json":{"schema":{"title":"HttpError","description":"The error response returned when a request cannot be completed.","type":"object","required":["code","detail"],"properties":{"code":{"description":"A short machine-readable error code identifying the type of error.","type":"string","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"detail":{"description":"A human-readable explanation of what went wrong.","type":"string","isRequired":true,"uniqueKey":"detail","typeLabel":"string"}},"example":{"code":"string","detail":"string"},"uniqueKey":"","typeLabel":"HttpError · object"},"example":{"code":"string","detail":"string"},"examples":{"Example":{"title":"Example","value":{"code":"string","detail":"string"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"8895d132-315f-48e7-ac67-e9e4ac8cb797":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Use a Bearer token to access this API.","scopes":["products:write"],"schemeName":"BearerAuth"}}},"servers":{"080577c1-39a5-4498-bb49-d7daab803f21":{"url":"https://api.withflex.com"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Use a Bearer token to access this API.","scopes":["products:write"],"schemeName":"BearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Use a Bearer token to access this API.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"BearerAuth","name":"Authorization"}],"title":"BearerAuth"}]},"originalFileLocation":"openapi.json"},"subdomain":"flex-87","siteName":"Flex Documentation","title":"Create Product Component - Flex Documentation","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-28T22:54:20.426Z","originalFileLocation":"api-reference/products/create-product-component.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Registers a product component (an ingredient) and returns it with an fcomp_ identifier you can attach to products. Nutrient values are stored per 100 g of the component. Send nutrition_basis: \u0026quot;as_served\u0026quot; with a serving_size_g to have per-serving figures converted for you. Component names are matched case-insensitively against a shared name table, so registering a name another account already registered returns that same component_id with your own nutrition attached. Registering something you already have is a 409. That covers both ways it happens: describing the same component twice in the same mode, and reusing a client_reference_id on a different component. Both mean the same thing — this ingredient is already registered, PATCH it instead — so a menu sync can treat 409 as \u0026quot;switch to update\u0026quot; without inspecting the message. Pass a client_reference_id to carry your own identifier for the ingredient. It is unique within your account and mode, which is what lets you look a component back up with GET /v1/product_components?client_reference_id=… instead of paging your catalogue. The same value may be used by another account, and by you in your other mode.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Flex Documentation\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Create Product Component - Flex Documentation\">\u003cmeta data-mint-head property=\"og:description\" content=\"Registers a product component (an ingredient) and returns it with an fcomp_ identifier you can attach to products. Nutrient values are stored per 100 g of the component. Send nutrition_basis: \u0026quot;as_served\u0026quot; with a serving_size_g to have per-serving figures converted for you. Component names are matched case-insensitively against a shared name table, so registering a name another account already registered returns that same component_id with your own nutrition attached. Registering something you already have is a 409. That covers both ways it happens: describing the same component twice in the same mode, and reusing a client_reference_id on a different component. Both mean the same thing — this ingredient is already registered, PATCH it instead — so a menu sync can treat 409 as \u0026quot;switch to update\u0026quot; without inspecting the message. Pass a client_reference_id to carry your own identifier for the ingredient. It is unique within your account and mode, which is what lets you look a component back up with GET /v1/product_components?client_reference_id=… instead of paging your catalogue. The same value may be used by another account, and by you in your other mode.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Flex Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.withflex.com/api-reference/products/create-product-component\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://flex-87.mintlify.site/_mintlify/api/og/v2?division=Products\u0026amp;title=Create+Product+Component\u0026amp;description=Registers+a+product+component+%28an+ingredient%29+and+returns+it+with+an+%60fcomp_%60%0Aidentifier+you+can+attach+to+products.%0A%0ANutrient+values+are+stored+per+100+g+of+th\u0026amp;theme=166c4e73f0167deeef40f76e\u0026amp;signature=2d98033f1b2c0d4269ae8245b0aa8bc8de00dc5ca4cfdef1894ccf2159bec11d\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Create Product Component - Flex Documentation\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Registers a product component (an ingredient) and returns it with an fcomp_ identifier you can attach to products. Nutrient values are stored per 100 g of the component. Send nutrition_basis: \u0026quot;as_served\u0026quot; with a serving_size_g to have per-serving figures converted for you. Component names are matched case-insensitively against a shared name table, so registering a name another account already registered returns that same component_id with your own nutrition attached. Registering something you already have is a 409. That covers both ways it happens: describing the same component twice in the same mode, and reusing a client_reference_id on a different component. Both mean the same thing — this ingredient is already registered, PATCH it instead — so a menu sync can treat 409 as \u0026quot;switch to update\u0026quot; without inspecting the message. Pass a client_reference_id to carry your own identifier for the ingredient. It is unique within your account and mode, which is what lets you look a component back up with GET /v1/product_components?client_reference_id=… instead of paging your catalogue. The same value may be used by another account, and by you in your other mode.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://flex-87.mintlify.site/_mintlify/api/og/v2?division=Products\u0026amp;title=Create+Product+Component\u0026amp;description=Registers+a+product+component+%28an+ingredient%29+and+returns+it+with+an+%60fcomp_%60%0Aidentifier+you+can+attach+to+products.%0A%0ANutrient+values+are+stored+per+100+g+of+th\u0026amp;theme=166c4e73f0167deeef40f76e\u0026amp;signature=2d98033f1b2c0d4269ae8245b0aa8bc8de00dc5ca4cfdef1894ccf2159bec11d\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/flex-87/uZDAr5goax7LGN2W/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Flex Documentation\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0070FA\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.withflex.com/api-reference/products/create-product-component\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/products/create-product-component.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.withflex.com/#organization\",\"name\":\"Flex Documentation\",\"url\":\"https://docs.withflex.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/flex-87/1kILreF5HcjIKLdi/logo/light.svg?fit=max\u0026auto=format\u0026n=1kILreF5HcjIKLdi\u0026q=85\u0026s=f703a75bc80df014f4849a7225b4879f\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.withflex.com#website\",\"name\":\"Flex Documentation\",\"url\":\"https://docs.withflex.com\",\"publisher\":{\"@id\":\"https://docs.withflex.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.withflex.com/api-reference/products/create-product-component#webpage\",\"url\":\"https://docs.withflex.com/api-reference/products/create-product-component\",\"name\":\"Create Product Component\",\"description\":\"Registers a product component (an ingredient) and returns it with an fcomp_ identifier you can attach to products. Nutrient values are stored per 100 g of the component. Send nutrition_basis: \\\"as_served\\\" with a serving_size_g to have per-serving figures converted for you. Component names are matched case-insensitively against a shared name table, so registering a name another account already registered returns that same component_id with your own nutrition attached. Registering something you already have is a 409. That covers both ways it happens: describing the same component twice in the same mode, and reusing a client_reference_id on a different component. Both mean the same thing — this ingredient is already registered, PATCH it instead — so a menu sync can treat 409 as \\\"switch to update\\\" without inspecting the message. Pass a client_reference_id to carry your own identifier for the ingredient. It is unique within your account and mode, which is what lets you look a component back up with GET /v1/product_components?client_reference_id=… instead of paging your catalogue. The same value may be used by another account, and by you in your other mode.\",\"dateModified\":\"2026-10-28T22:54:20.426Z\",\"isPartOf\":{\"@id\":\"https://docs.withflex.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.withflex.com/api-reference/products/create-product-component#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.withflex.com/api-reference/products/create-product-component#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"API Reference\",\"item\":\"https://docs.withflex.com/api-reference/shipping-rates/list-shipping-rates\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Products\",\"item\":\"https://docs.withflex.com/api-reference/products/list-product-components\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Create Product Component\",\"item\":\"https://docs.withflex.com/api-reference/products/create-product-component\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.withflex.com/api-reference/products/create-product-component#apireference\",\"headline\":\"Create Product Component\",\"name\":\"Create Product Component\",\"description\":\"Registers a product component (an ingredient) and returns it with an fcomp_ identifier you can attach to products. Nutrient values are stored per 100 g of the component. Send nutrition_basis: \\\"as_served\\\" with a serving_size_g to have per-serving figures converted for you. Component names are matched case-insensitively against a shared name table, so registering a name another account already registered returns that same component_id with your own nutrition attached. Registering something you already have is a 409. That covers both ways it happens: describing the same component twice in the same mode, and reusing a client_reference_id on a different component. Both mean the same thing — this ingredient is already registered, PATCH it instead — so a menu sync can treat 409 as \\\"switch to update\\\" without inspecting the message. Pass a client_reference_id to carry your own identifier for the ingredient. It is unique within your account and mode, which is what lets you look a component back up with GET /v1/product_components?client_reference_id=… instead of paging your catalogue. The same value may be used by another account, and by you in your other mode.\",\"url\":\"https://docs.withflex.com/api-reference/products/create-product-component\",\"mainEntityOfPage\":{\"@id\":\"https://docs.withflex.com/api-reference/products/create-product-component#webpage\"},\"dateModified\":\"2026-10-28T22:54:20.426Z\",\"publisher\":{\"@id\":\"https://docs.withflex.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.withflex.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Flex Documentation\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Flex Documentation","nav":{"global":{"anchors":[{"anchor":"Status","icon":"wifi","href":"https://statuspage.incident.io/with-flex"},{"anchor":"Support","icon":"mail","href":"mailto:support@withflex.com"},{"anchor":"Website","icon":"laptop","href":"https://www.withflex.com"}]},"tabs":[{"tab":"Welcome","pages":[{"title":"Welcome","href":""}]},{"tab":"Guides","pages":[{"title":"Guides","href":"/developer-guides/introduction"}]},{"tab":"API Reference","groups":[{"group":"API Overview","pages":[{"title":"Introduction to the Flex API","sidebarTitle":"Introduction","href":"/api-reference/introduction"},{"title":"Expanding Resources","sidebarTitle":"Expanding Resources","href":"/api-reference/expanding-resources"}]},{"group":"API Reference","pages":[{"group":"Shipping Rates","pages":[{"title":"List Shipping Rates","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/shipping_rates","href":"/api-reference/shipping-rates/list-shipping-rates"},{"title":"Create Shipping Rate","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/shipping_rates","href":"/api-reference/shipping-rates/create-shipping-rate"},{"title":"Get Shipping Rate","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/shipping_rates/{id}","href":"/api-reference/shipping-rates/get-shipping-rate"},{"title":"Update Shipping Rate","deprecated":null,"version":null,"openapi":"/openapi.json put /v1/shipping_rates/{id}","href":"/api-reference/shipping-rates/update-shipping-rate"}]},{"group":"Disputes","pages":[{"title":"List Disputes","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/disputes","href":"/api-reference/disputes/list-disputes"},{"title":"Count Disputes","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/disputes/count","href":"/api-reference/disputes/count-disputes"},{"title":"Get Dispute","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/disputes/{dispute_id}","href":"/api-reference/disputes/get-dispute"},{"title":"Update Dispute","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/disputes/{dispute_id}","href":"/api-reference/disputes/update-dispute"},{"title":"Close Dispute","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/disputes/{dispute_id}/close","href":"/api-reference/disputes/close-dispute"}]},{"group":"Events","pages":[{"title":"Retry Event","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/events/{id}/retry","href":"/api-reference/events/retry-event"}]},{"group":"Checkout Sessions","pages":[{"title":"List Checkout Sessions","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/checkout/sessions","href":"/api-reference/checkout-sessions/list-checkout-sessions"},{"title":"Create Checkout Session","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions","href":"/api-reference/checkout-sessions/create-checkout-session"},{"title":"Get Checkout Session","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/checkout/sessions/{id}","href":"/api-reference/checkout-sessions/get-checkout-session"},{"title":"Get Line Items","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/checkout/sessions/{id}/line_items","href":"/api-reference/checkout-sessions/get-line-items"},{"title":"Confirm Checkout Session","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/confirm","href":"/api-reference/checkout-sessions/confirm-checkout-session"},{"title":"Capture Checkout Session","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/capture","href":"/api-reference/checkout-sessions/capture-checkout-session"},{"title":"Preview Capture Allocation","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/capture_allocation","href":"/api-reference/checkout-sessions/preview-capture-allocation"},{"title":"Reauth Checkout Session","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/reauth","href":"/api-reference/checkout-sessions/reauth-checkout-session"},{"title":"Refund Checkout Session","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/refund","href":"/api-reference/checkout-sessions/refund-checkout-session"},{"title":"Preview Refund Allocation","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/refund_allocation","href":"/api-reference/checkout-sessions/preview-refund-allocation"},{"title":"Cancel Auth Checkout Session","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/cancel","href":"/api-reference/checkout-sessions/cancel-auth-checkout-session"},{"title":"Resend Checkout Session Receipts","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/receipts/resend","href":"/api-reference/checkout-sessions/resend-checkout-session-receipts"},{"title":"Resend Checkout Session Lomn","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/checkout/sessions/{id}/lomn/resend","href":"/api-reference/checkout-sessions/resend-checkout-session-lomn"}]},{"group":"Coupons","pages":[{"title":"List Coupons","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/coupons","href":"/api-reference/coupons/list-coupons"},{"title":"Create Coupon","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/coupons","href":"/api-reference/coupons/create-coupon"},{"title":"Get Coupon","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/coupons/{id}","href":"/api-reference/coupons/get-coupon"}]},{"group":"Customers","pages":[{"title":"List customers","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/customers","href":"/api-reference/customers/list-customers"},{"title":"Create or update a customer","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/customers","href":"/api-reference/customers/create-or-update-a-customer"},{"title":"Retrieve a customer","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/customers/{id}","href":"/api-reference/customers/retrieve-a-customer"},{"title":"Delete a customer","deprecated":null,"version":null,"openapi":"/openapi.json delete /v1/customers/{id}","href":"/api-reference/customers/delete-a-customer"},{"title":"Update a customer","deprecated":null,"version":null,"openapi":"/openapi.json patch /v1/customers/{id}","href":"/api-reference/customers/update-a-customer"},{"title":"List a customer's payment methods","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/customers/{id}/payment_methods","href":"/api-reference/customers/list-a-customers-payment-methods"},{"title":"Retrieve a customer's payment method","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/customers/{id}/payment_methods/{pm_id}","href":"/api-reference/customers/retrieve-a-customers-payment-method"}]},{"group":"Exports","pages":[{"title":"List Exports","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/exports","href":"/api-reference/exports/list-exports"},{"title":"Create Export","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/exports","href":"/api-reference/exports/create-export"},{"title":"Get Export","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/exports/{id}","href":"/api-reference/exports/get-export"},{"title":"Cancel Export","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/exports/{id}/cancel","href":"/api-reference/exports/cancel-export"},{"title":"Create Export Url","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/exports/{id}/presigned_url","href":"/api-reference/exports/create-export-url"}]},{"group":"Invoices","pages":[{"title":"List Invoices","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/invoices","href":"/api-reference/invoices/list-invoices"},{"title":"Get Invoice","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/invoices/{id}","href":"/api-reference/invoices/get-invoice"},{"title":"Mark Invoice Uncollectible","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/invoices/{id}/mark_uncollectible","href":"/api-reference/invoices/mark-invoice-uncollectible"}]},{"group":"Products","pages":[{"title":"List Product Components","description":"Returns the product components you have registered, newest first.\n\nOnly components you have recorded nutrition for are listed: the underlying name\ntable is shared across accounts, so listing it would return tens of thousands of\nrows that belong to nobody.\n\nResults are paginated — the default `limit` is 10, so reading back a full menu\ntakes several requests. Pass the last object's `component_nutrition_id` as\n`starting_after` to fetch the next page, and keep going until a page comes back\nshorter than your `limit`.\n\nRather than paging the whole catalogue to find one ingredient, filter it:\n`client_reference_id` returns the single component carrying your own identifier,\n`name` matches the shared component name case-insensitively, and `category` and\n`canonical_food_key` narrow by those fields. Metadata is filtered with\n`metadata[key]=value`, with multiple keys AND-ed. Filters combine with each other\nand with the pagination cursors.","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/product_components","href":"/api-reference/products/list-product-components"},{"title":"Create Product Component","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/product_components","href":"/api-reference/products/create-product-component"},{"title":"Get Product Component","description":"Retrieves one of your product components by its `fcomp_` identifier, with the\nnutrition you recorded for it. Nutrient values are per 100 g.\n\nA component you have not registered nutrition for is a 404, even when the name\nitself exists in Flex's shared component table.","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/product_components/{id}","href":"/api-reference/products/get-product-component"},{"title":"Update Product Component","deprecated":null,"version":null,"openapi":"/openapi.json patch /v1/product_components/{id}","href":"/api-reference/products/update-product-component"},{"title":"List Products","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/products","href":"/api-reference/products/list-products"},{"title":"Create Product","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/products","href":"/api-reference/products/create-product"},{"title":"Processing Status","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/products/processing_status","href":"/api-reference/products/processing-status"},{"title":"Get Product","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/products/{id}","href":"/api-reference/products/get-product"},{"title":"Update Product","deprecated":null,"version":null,"openapi":"/openapi.json patch /v1/products/{id}","href":"/api-reference/products/update-product"}]},{"group":"Payment Intents","pages":[{"title":"List Payment Intents","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/payment_intents","href":"/api-reference/payment-intents/list-payment-intents"},{"title":"Get Payment Intent","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/payment_intents/{id}","href":"/api-reference/payment-intents/get-payment-intent"},{"title":"Send Receipt","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/payment_intents/{id}/receipt","href":"/api-reference/payment-intents/send-receipt"},{"title":"Cancel Payment Intent","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/payment_intents/{id}/cancel","href":"/api-reference/payment-intents/cancel-payment-intent"}]},{"group":"Payment Links","pages":[{"title":"List Payment Links","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/payment_links","href":"/api-reference/payment-links/list-payment-links"},{"title":"Create Payment Link","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/payment_links","href":"/api-reference/payment-links/create-payment-link"},{"title":"Get Payment Link","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/payment_links/{id}","href":"/api-reference/payment-links/get-payment-link"},{"title":"Update Payment Link","deprecated":null,"version":null,"openapi":"/openapi.json patch /v1/payment_links/{id}","href":"/api-reference/payment-links/update-payment-link"}]},{"group":"Payouts","pages":[{"title":"List Payouts","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/payouts","href":"/api-reference/payouts/list-payouts"}]},{"group":"Prices","pages":[{"title":"List Prices","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/prices","href":"/api-reference/prices/list-prices"},{"title":"Create Price","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/prices","href":"/api-reference/prices/create-price"},{"title":"Get Price","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/prices/{id}","href":"/api-reference/prices/get-price"},{"title":"Update Price","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/prices/{id}","href":"/api-reference/prices/update-price"}]},{"group":"Promo Codes","pages":[{"title":"List Promo Codes","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/promo_codes","href":"/api-reference/promo-codes/list-promo-codes"},{"title":"Create Promo Code","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/promo_codes","href":"/api-reference/promo-codes/create-promo-code"},{"title":"Get Promo Code","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/promo_codes/{id}","href":"/api-reference/promo-codes/get-promo-code"},{"title":"Update Promo Code","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/promo_codes/{id}","href":"/api-reference/promo-codes/update-promo-code"}]},{"group":"Refunds","pages":[{"title":"List Refunds","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/refunds","href":"/api-reference/refunds/list-refunds"},{"title":"Create Refund","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/refunds","href":"/api-reference/refunds/create-refund"},{"title":"Get Refund","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/refunds/{refund_id}","href":"/api-reference/refunds/get-refund"},{"title":"Update Refund","deprecated":null,"version":null,"openapi":"/openapi.json patch /v1/refunds/{refund_id}","href":"/api-reference/refunds/update-refund"}]},{"group":"Reviews","pages":[{"title":"List Reviews","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/reviews","href":"/api-reference/reviews/list-reviews"},{"title":"Get Review","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/reviews/{review_id}","href":"/api-reference/reviews/get-review"}]},{"group":"Subscriptions","pages":[{"title":"List Subscriptions","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/subscriptions","href":"/api-reference/subscriptions/list-subscriptions"},{"title":"Get Subscription","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/subscriptions/{id}","href":"/api-reference/subscriptions/get-subscription"},{"title":"Cancel Subscription","deprecated":null,"version":null,"openapi":"/openapi.json delete /v1/subscriptions/{id}","href":"/api-reference/subscriptions/cancel-subscription"},{"title":"Update Subscription","deprecated":null,"version":null,"openapi":"/openapi.json patch /v1/subscriptions/{id}","href":"/api-reference/subscriptions/update-subscription"},{"title":"Resend Subscription Receipts","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/subscriptions/{id}/receipts/resend","href":"/api-reference/subscriptions/resend-subscription-receipts"},{"title":"Get Refund Preview","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/subscriptions/{id}/refund_preview","href":"/api-reference/subscriptions/get-refund-preview"},{"title":"Pause Subscription","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/subscriptions/{id}/pause","href":"/api-reference/subscriptions/pause-subscription"},{"title":"Update Pause","deprecated":null,"version":null,"openapi":"/openapi.json patch /v1/subscriptions/{id}/pause","href":"/api-reference/subscriptions/update-pause"},{"title":"Resume Subscription","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/subscriptions/{id}/resume","href":"/api-reference/subscriptions/resume-subscription"},{"title":"Stop a failed resume and keep the subscription paused","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/subscriptions/{id}/resume/cancel","href":"/api-reference/subscriptions/stop-a-failed-resume-and-keep-the-subscription-paused"}]},{"group":"Balance Transactions","pages":[{"title":"List Balance Transactions","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/balance_transactions","href":"/api-reference/balance-transactions/list-balance-transactions"}]},{"group":"Setup Intents","pages":[{"title":"List Setup Intents","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/setup_intents","href":"/api-reference/setup-intents/list-setup-intents"},{"title":"Create Setup Intent","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/setup_intents","href":"/api-reference/setup-intents/create-setup-intent"},{"title":"Get Setup Intent","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/setup_intents/{id}","href":"/api-reference/setup-intents/get-setup-intent"}]},{"group":"Captures","pages":[{"title":"List captures","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/captures","href":"/api-reference/captures/list-captures"},{"title":"Retrieve a capture","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/captures/{capture_id}","href":"/api-reference/captures/retrieve-a-capture"},{"title":"Update a capture","deprecated":null,"version":null,"openapi":"/openapi.json patch /v1/captures/{capture_id}","href":"/api-reference/captures/update-a-capture"}]},{"group":"Files","pages":[{"title":"List Files","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/files","href":"/api-reference/files/list-files"},{"title":"Create File","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/files","href":"/api-reference/files/create-file"},{"title":"Retrieve File","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/files/{id}","href":"/api-reference/files/retrieve-file"}]}]}]},{"tab":"Compliance","pages":[{"title":"Compliance","href":"/compliance/introduction"}]},{"tab":"Marketing","pages":[{"title":"Marketing","href":"/merchant-success/introduction"}]},{"tab":"Changelog","pages":[{"title":"Changelog","href":"/changelog"}]}]},"basePath":"","title":"Create Product Component - Flex Documentation","buildId":"dpl_FWZhTb2vab28gFGFH4ojka6qEznQ","deploymentId":"dpl_FWZhTb2vab28gFGFH4ojka6qEznQ","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-CBsVopKK.js","utils-DZAk68jJ.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-D32AYZrP.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-D_A5_cny.js","snippetPresets-xNRfS9th.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BIB25-tq.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-CydJ4w4j.js","shallow-CYPBeQSG.js","getApiPlaygroundDisplay-A5xJVBOu.js","CodeSnippet-BVRTgi3m.js","CodeSnippets-DjD6BSlt.js","Page-Dr40SSJq.js","getPastedJson-D4V4JyrR.js","icon-uhcnG22T.js","MethodPill-CM-ZQdGH.js","DuplicateIcon-B_WnOiNf.js","createIcon-CJsb8utt.js","DynamicMarkdown-D-2HDKEp.js","SectionHeading-KP5xmMgQ.js","axios-vUo_bRtp.js","Markdown-D_k0dg6k.js","clsx-DK3K4Z1S.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-DE3EVdvd.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-fN9H9n9g.js"]}