FacetFlux

FacetFlux

Featured Revuo-affiliated verified 22 aug 2026
editor's choice  ] score · 43  ]

AI product data enrichment for industrial suppliers

Pricing: Freemium - Free for up to 100 Products; Paid starting from $49 Company: FacetFlux Founded: 2024 Last verified: 2026-08-22
Visit Website Improve Catalog Verified Vendor Updated

TL;DR

FacetFlux is an AI-powered data enrichment platform specifically designed for industrial manufacturers to transform messy catalog data into structured, standards-compliant formats like ETIM and eCl@ss. Its primary differentiator is its "citation-backed" AI, which provides source URLs for every specification it discovers, solving the lack of transparency often found in automated enrichment.

What Users Actually Pay

No user-reported pricing yet.

Our Take

FacetFlux occupies a highly specialized niche at the intersection of industrial engineering and modern AI. While generalist AI tools struggle with technical industrial taxonomies, FacetFlux is purpose-built for the complexities of BMEcat schemas and electrical/mechanical product standards. It acts as a processing layer rather than a permanent PIM, making it an excellent 'cleanup' tool for companies preparing data for distributor portals or procurement systems. Its market position is strong among mid-to-large industrial suppliers where manual data entry for 100,000+ SKUs is cost-prohibitive. The entry-point diagnostic tool is a clever friction-reduction strategy, allowing technical managers to prove the ROI of AI enrichment before committing to a subscription. However, the platform's utility is currently limited to the industrial sector; consumer goods brands would likely find the taxonomy tools overkill. Its current reliance on a manual 'upload/download' or API-first workflow, while efficient for large batches, may feel less integrated than tools offering native connectors to Shopify or Amazon. Overall, it is best suited for industrial manufacturers who are under pressure from distributors to provide high-quality, standardized digital catalogs (ETIM/eCl@ss) and need a verifiable way to scale their product data management without massive head-count increases.

Pros

  • + Specialized support for industrial standards like ETIM, eCl@ss, and BMEcat.
  • + Citations for AI-enriched data ensure technical accuracy and trust.
  • + High-scale processing capabilities proven up to 300,000 SKUs.
  • + Low-barrier entry with a free, comprehensive catalog diagnostic tool.
  • + Built-in translation features tailored for technical specifications.

Cons

  • - Pricing for AI enrichment ($0.30–$0.60 per SKU) can be high for low-margin products at scale.
  • - Lack of a pre-built integration ecosystem (Zapier, Make, etc.) for non-technical users.
  • - Very new product (founded 2024) with limited third-party community support or peer case studies.
  • - Niche focus limits its applicability outside of industrial and technical B2B sectors.

Agent Readiness

56/100

FacetFlux is exceptionally 'agent-ready' for an early-stage SaaS. It provides a modern REST API documented via Mintlify (OpenAPI), but its standout feature is the native support for the Model Context Protocol (MCP). This allows AI agents like Claude or local LLMs to autonomously interact with the catalog data and enrichment tools. While it lacks no-code connectors like Zapier, its programmatic interface and structured data focus make it ideal for autonomous agent-led workflows.

API Surface100
Public APIRESTFree TieropenApi
Protocol Support40
MCP (44 tools)
SDK Availability0
Integration Ecosystem25
WebhooksMCP (Model Context Protocol)Excel/CSV/BMEcat Import/Export
Developer Experience85
Docs: excellentSandboxVersioningChangelog

Last checked Aug 1, 2026

MCP Integrations

1 server44 tools
FacetFlux MCPrevuo:facetflux
Bring a keyself-registeredVerified by RevuoRemoteHigh match

Needs a self-provisionable API key

Allows AI tools like Codex, Claude Code et al. to help manage your product data

44 tools
  • pim.schemas.set.productNumberTemplateSet the schema's product-number template. C = category code character, N = sequential digit, any other character = literal. Example: 'CCCC-NNNNNNNN' renders 'PUMP-00000001'. Pass null to clear. Response: { schemaId, productNumberTemplate }. Errors: { error: { code: 'not_found', ... } }.
  • pim.products.byExternalId.getGet a single product by its source system + externalId. Useful for reconciling products imported from a supplier feed or upstream system without first calling pim.products.search. Same response shape as pim.products.get. Response: { product?: {...}, attributes?: [...], variants?: [...], channelStatuses?: [...] }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • pim.attributeDefinitions.createCreate an attribute definition in a schema, or return the existing one if `code` already exists. DataType is required and immutable once values exist. Optional fields: traitId (binds the def to a trait), unit, scope (product|variantDefining|perVariant), role (None|Name|Description|Brand|...), isRequired, isTranslatable, isSearchable, isFilterable. To populate enum allowed values use pim.attributeDefinitions.allowedValues.set after creation. Response: { attributeDefinition: {...}, created: bool }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • pim.traits.createCreate a trait in a schema, or return the existing one if `code` already exists. Traits are reusable groups of attribute definitions; products opt in to traits to gain their attributes. To bind attribute definitions to the trait after creation, use pim.traits.attributes.add (or set `traitId` directly when creating attribute definitions). Response: { trait: {...}, created: bool }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • pim.products.traits.addAssign one or more traits to a product. Traits add their attribute definitions to the product's editable surface. Idempotent. Response: { productId, traitIds, added: count }. Errors: { error: { code: 'not_found', ... } }.
  • pim.products.batch.createBulk create-or-upsert products by (sourceSystem, externalId). All inputs share the same schemaId and sourceSystem. Up to 200 products per call; route larger payloads through the Phase-3 imports.* path. Per-row results report which were created vs updated. Channel-code application is a second pass — per-row failures appear in `channelWarnings` (typically: an unknown channel code) without failing the batch; the product itself is still created/updated. Response: { sourceSystem, schemaId, results: [{ productId, externalId, action }], channelWarnings: [{ externalId, productId, message }] }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • pim.products.categories.removeRemove product from one or more categories. Idempotent — non-assigned categories are no-ops. Response: { productId, categoryIds, removed: count }. Errors: { error: { code: 'not_found', ... } }.
  • pim.products.channels.addPublish product on one or more channels. Channel codes must already exist for the tenant (otherwise the underlying invariant rejects the write). Idempotent. Response: { productId, channelCodes, added: count }. Errors: { error: { code: 'not_found' | 'unprocessable', ... } }.
  • pim.traits.getGet a trait by id, with its trait-scoped attribute definitions resolved. Response: { trait: {...}, attributeDefinitions: [...] }. Errors: { error: { code: 'not_found', ... } }.
  • imports.smartImports.deleteDelete a SmartImport record. Does NOT delete any PIM data created during execution — only the import record itself. Response: { smartImportId, deleted: bool }. Errors: { error: { code: 'not_found', ... } }.
  • pim.products.traits.removeUnassign one or more traits from a product. Note: existing attribute values for the trait's attributes are NOT deleted automatically — call pim.products.attributes.set with mode=replace afterwards if you want to drop them. Idempotent. Response: { productId, traitIds, removed: count }. Errors: { error: { code: 'not_found', ... } }.
  • imports.mappings.applyPure transform: apply column→attribute mappings to a list of source records and return per-row attribute payloads ready for downstream writes. NO DB writes happen here. Each rule maps `sourceColumn` (a key in the record) to `destinationAttributeDefinitionId` (an attribute definition in the target schema), with an optional `role` tag (uniqueIdentifier, productGroup, name, brand, category, mainImage, productType). The mapping engine performs type coercion against the destination's DataType (e.g. string '42' → 42 for Number) and reports per-row errors and warnings. Recommended downstream flow: use the role-tagged values (especially uniqueIdentifier) as the externalId for `pim.products.batch.create`, then write the per-row attributes via `pim.products.attributes.set`. Response: { targetSchemaId, ruleCount, recordCount, skippedRules: [{ ruleIndex, reason }], items: [{ rowIndex, isSuccess, attributes: [{ attributeDefinitionId, code, dataType, value }], roles: { [role]: value }, errors: [...], warnings: [...] }] }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • imports.smartImports.listList SmartImports for the current tenant, newest first. Excludes the heavy `rawProducts` list from each entry — call imports.smartImports.get to fetch one in full. Optional `status` filter narrows by lifecycle state. Response: { smartImports: [{ id, status, mode, originalFileName, productCount, variantCount, createdAt, updatedAt }] }. Errors: { error: { code: 'bad_input', ... } }.
  • jobs.getPoll a background job's state. Status values: queued, processing, success, failed. `progress` is a 0.0–1.0 fraction (null when the job hasn't reported any). Tenant-scoped: agents can only see jobs in their own tenant. Response: { jobId, kind, status, progress, retryCount, started, lastAlive, cancellationRequested }. Errors: { error: { code: 'not_found', ... } }.
  • pim.attributeDefinitions.allowedValues.setReplace the allowed-value list for an enum/multiEnum attribute definition. Idempotent on `value`: values present in input but not in storage are inserted, values present in both have their labels/sortOrder/isActive updated, values present in storage but absent from input are deleted. After this call HasAllowedValues is true iff the resulting list is non-empty. Response: { attributeDefinitionId, added, updated, deleted }. Errors: { error: { code: 'not_found' | 'unprocessable', ... } }.
  • pim.products.categories.addAdd product to one or more categories. Idempotent — already-assigned categories are no-ops. Response: { productId, categoryIds, added: count }. Errors: { error: { code: 'not_found', ... } }.
  • pim.products.channels.removeUnpublish product from one or more channels. Idempotent. Response: { productId, channelCodes, removed: count }. Errors: { error: { code: 'not_found', ... } }.
  • pim.schemas.getGet a PIM schema by id, with productTypes, traits, attributeDefinitions, and channels embedded. Use the optional `fields` param to limit the response to specific top-level keys when the full payload is too large. Allowed `fields` values: schema, productTypes, traits, attributeDefinitions, channels. Response: { schema?: {...}, productTypes?: [...], traits?: [...], attributeDefinitions?: [...], channels?: [...] }. Errors: { error: { code: 'not_found' | 'forbidden', ... } }.
  • imports.smartImports.startUpload + analyze inline file content. Supported formats: 'csv' (text/csv) and 'wawiJson' (WAWI-style JSON product feed with FTITLES/FVALUES/DETAIL fields). XLSX is intentionally not supported via MCP in v1 — agents that need XLSX should convert to CSV client-side or use the HTTP API. Returns a SmartImport in Analyzed state with field inventory ready for inference. Response: { smartImport: {...} }. Errors: { error: { code: 'bad_input' | 'unprocessable', ... } }.
  • pim.products.attributes.setSet or merge attribute values on a product (or a specific variant). `mode=merge` (default) upserts only the provided values; existing values for other attributes are left untouched. `mode=replace` upserts the provided values AND deletes any other existing attribute values on the entity, leaving exactly the provided set. Each value is sent as native JSON matching its definition's DataType (string for Text, number for Number/Decimal, bool for Boolean, ["..."] for MultiEnum / arrays, {"en":"...","de":"..."} for translatable Text). When `variantId` is set, the variant must belong to `productId` and the same tenant; attribute scope must match the target entity (product-scoped defs onto product, variantDefining/perVariant defs onto variant) — mismatches are reported in `skipped` with reason `scope_mismatch`. Other skip reasons: `missing_attribute_definition_id`, `definition_not_in_schema`, `value_parse_error: <detail>`. In `mode=replace`, attributes the caller listed but whose value couldn't parse are NOT deleted — only attributes the caller didn't mention at all. Response: { productId, variantId, applied, deleted, skipped: [{ attributeDefinitionId, reason }] }. Errors: { error: { code: 'not_found' | 'bad_input' | 'unprocessable', ... } }.
  • pim.products.status.setSet the product's lifecycle status. Allowed values: draft, active, archived, requiresAttention. Use this for 'soft delete' (status=archived); there is no hard delete via MCP in v1. Response: { productId, status }. Errors: { error: { code: 'not_found', ... } }.
  • pim.productTypes.listList product types in a schema. ProductTypes are the flat product classification within a schema (NOT to be confused with categories, which are sales navigation). Response: { productTypes: [{ id, schemaId, code, labels, defaultTraitIds, parentCode, level, isActive, productCount }] }. Errors: { error: { code: 'not_found', ... } }.
  • pim.traits.attributes.removeUnbind attribute definitions from a trait — clears their `traitId` only when it equals the given trait. Definitions bound to other traits are left untouched. Idempotent. Response: { traitId, attributeDefinitionIds, unbound: count, skipped: [{ id, reason }] }. Errors: { error: { code: 'not_found', ... } }.
  • pim.channels.attributeConfig.setReplace the channel's per-attribute config overlay. Each entry binds an attribute definition to per-channel `isRequired`, `labelOverrides`, `exportKey`, and `sortOrder`. The channel's underlying schema must contain every referenced attribute definition; mismatches are skipped. Pass [] to clear the overlay (the channel falls back to the schema's defaults). Response: { channelId, applied: count, skipped: [{ attributeDefinitionId, reason }] }. Errors: { error: { code: 'not_found', ... } }.
  • pim.products.searchSearch products in the current tenant. At most one filter dimension is honored at a time (in priority order: query > schemaId > productTypeId > categoryId > channelCode > traitId). If none are set, returns the tenant's products in default order. Pagination: 1-indexed `page` + `pageSize` (max 50). Response: { products: [{ id, schemaId, primaryTypeId, traitIds, categoryIds, channelCodes, skuList, productNumber, status, purpose, sourceSystem, sourceSystemProductId, updatedAt }], page, pageSize, totalCount, totalPages }. Errors: { error: { code: 'bad_input', ... } }.
  • pim.attributeDefinitions.getGet an attribute definition by id, with full metadata (validation rules, allowed-value count, guidance text, unit conversion config). To enumerate the actual allowed values, call pim.attributeDefinitions.allowedValues.list (Phase 2). Response: { attributeDefinition: {...} }. Errors: { error: { code: 'not_found', ... } }.
  • pim.productTypes.createCreate a product type in a schema, or return the existing one if `code` already exists in the schema. ProductType is the flat product classification within a schema (NOT category/sales nav). Response: { productType: {...}, created: bool }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • pim.schemas.set.defaultChannelsSet the schema's default channel codes — the codes auto-assigned to new products in this schema. This replaces the existing list. Pass [] to clear. Response: { schemaId, defaultChannelCodes }. Errors: { error: { code: 'not_found', ... } }.
  • pim.schemas.listList PIM schemas in the current tenant. By default returns only tenant-owned, editable schemas (Master + Recipient). To inspect Import (file-import) or Standard (eClass/ETIM/UNSPSC) or Connector schemas, pass `kind` explicitly. Response: { schemas: [{ id, name, kind, contentLanguage, productTypeCount, traitCount, categoryCount, attributeDefinitionCount, isReadOnly, updatedAt }] }. Errors: { error: { code: 'bad_input', ... } }.
  • pim.channels.createCreate a channel for the current tenant, or return the existing one if `code` already exists. Channels are thin distribution-target overlays on a master schema. To customize per-channel attribute requirements after creation, use pim.channels.attributeConfig.set. Response: { channel: {...}, created: bool }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • imports.smartImports.reviewReplace the SmartImport's inferred schema with the agent's adjusted version, transitioning the import to Reviewed. The schema shape is the same one returned in imports.smartImports.get's `inferredSchema` field — typically the agent fetches it, edits names/codes/grouping in its own context, and submits the result here. Response: { smartImport: {...} }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • imports.smartImports.runInferenceEnqueue the AI inference job for a SmartImport. The SmartImport must be in Analyzed state; transitions to Inferring. Inference runs as a background job — poll imports.smartImports.get periodically until status becomes Inferred (or Failed). Response: { smartImport: {...} }. Errors: { error: { code: 'not_found' | 'unprocessable', ... } }.
  • pim.attributeDefinitions.aliases.setReplace the attribute definition's alias list. Aliases are alternate names used during import matching (e.g. 'Gewicht' as a German alias for 'weight'). Pass [] to clear. Response: { attributeDefinitionId, aliases }. Errors: { error: { code: 'not_found', ... } }.
  • pim.products.getGet a single product with its variants and resolved attribute values. Use the optional `fields` whitelist to skip heavy sections when payload size matters. Allowed `fields` values: product, attributes, variants, channelStatuses. Attribute values are returned in their native JSON shape (string/number/bool/{lang:value}/["..."]) matching the PimValue wire format used by the HTTP API. Each attribute carries its definition code + dataType so the agent can interpret the value without a separate lookup. Response: { product?: {...}, attributes?: [{ attributeDefinitionId, code, dataType, scope, unit, value, updatedAt }], variants?: [{ id, sku, name, ean, gtin, attributes: [...] }], channelStatuses?: [...] }. Errors: { error: { code: 'not_found', ... } }.
  • pim.attributeDefinitions.listList attribute definitions in a schema. Pass `traitId` to scope to a single trait, or pass `includeGlobalOnly=true` to get only global (non-trait-scoped) attributes. Response: { attributeDefinitions: [{ id, schemaId, traitId, code, labels, dataType, unit, isRequired, isTranslatable, scope, role, hasAllowedValues, allowedValueCount }] }. Errors: { error: { code: 'not_found', ... } }.
  • pim.traits.listList traits in a schema. Traits are reusable groups of attribute definitions; products opt in to traits to gain their attributes. Response: { traits: [{ id, schemaId, code, labels, sortOrder, isActive }] }. Errors: { error: { code: 'not_found', ... } }.
  • pim.channels.listList channels (distribution targets) for the current tenant. Optionally scope to a single schema. Response: { channels: [{ id, code, labels, country, schemaId, minReadinessPercent, tags, isActive, attributeConfigCount }] }. Errors: { error: { code: 'bad_input', ... } }.
  • pim.products.archiveSoft-archive a product. Equivalent to pim.products.status.set with status=archived. Response: { productId, status: 'archived' }. Errors: { error: { code: 'not_found', ... } }.
  • pim.schemas.set.defaultAiRoleSet the schema's default LLM role/context (the system-prompt-style preamble used in AI ops). Pass null to clear. Response: { schemaId, defaultAiRole }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • imports.smartImports.executeFinalize a SmartImport: create the PIM schema, traits, attribute definitions, products, variants, and attribute values. Synchronous — may take seconds for large imports. The SmartImport must be in Reviewed state. Transitions to Complete (or Failed on error). Response: { smartImport: {...} } with createdSchemaId, importedProductCount, importedVariantCount populated. Errors: { error: { code: 'not_found' | 'unprocessable', ... } }.
  • pim.products.createCreate or upsert a single product by (sourceSystem, externalId). Re-running the same call returns the same productId and updates the existing record — never creates a duplicate. For ad-hoc creates with no upstream system, pass sourceSystem='mcp' (or another stable string the agent owns) so subsequent runs from the same agent stay idempotent. Response: { productId, sourceSystem, externalId, action: 'created'|'updated' }. Errors: { error: { code: 'not_found' | 'bad_input', ... } }.
  • pim.schemas.createCreate a tenant-owned PIM schema, or return the existing one if `name` already exists for this tenant. Only Master and Recipient kinds are creatable via MCP — Standard (eClass/ETIM/UNSPSC) and Connector schemas are platform-managed. Response: { schema: {...}, created: bool }. Errors: { error: { code: 'bad_input', ... } }.
  • pim.traits.attributes.addBind one or more attribute definitions to a trait by setting their `traitId`. Each attribute definition in the list has its `traitId` updated to the given trait. Idempotent — already-bound definitions are no-ops. Definitions in other schemas or other tenants are skipped with a reason. Response: { traitId, attributeDefinitionIds, bound: count, skipped: [{ id, reason }] }. Errors: { error: { code: 'not_found', ... } }.
  • imports.smartImports.getGet a SmartImport by id. By default returns the metadata + field inventory + inferred schema (when present); the raw products list is omitted unless explicitly requested since it can be large. Response: { smartImport: {...}, fieldInventory?, inferredSchema?, rawProductCount, errorMessage? }. Errors: { error: { code: 'not_found', ... } }.

Last checked Aug 24, 2026

Screenshot

FacetFlux screenshot

[ features ]

Product Data Management

Core capabilities for managing product data including import, validation, versioning, and localization.

Bulk Import/Export

Ability to import and export large volumes of product data via CSV, Excel, or other formats.

yes  ]
Data Validation Rules

Configurable rules to validate product data quality and completeness.

yes  ]
Version History

Track changes to product data over time with ability to rollback.

no
Inheritance/Variants

Support for product variants with inherited attributes from parent products.

yes  ]
Localization Support

Multi-language support for product content.

yes  ]
Number of Languages

How many languages are supported out of the box.

16

Supplier Portal

Capabilities for supplier onboarding, data collection, and collaboration.

Supplier Self-Service

Portal where suppliers can directly update their product information.

no
Supplier Onboarding Workflow

Structured process for onboarding new suppliers with approvals.

yes  ]
Data Quality Scoring

Automated scoring of supplier-provided data quality.

yes  ]
Supplier Performance Tracking

Analytics on supplier data quality and response times.

no
Branded Portal

White-label supplier portal with custom branding.

no

Compliance & Security

Security certifications, compliance features, and access control capabilities.

SOC 2

SOC 2 Type I or Type II certification.

None
ISO 27001

ISO 27001 information security certification.

no
GDPR Tools

Built-in tools for GDPR compliance (data export, deletion, consent).

no
Audit Trail

Complete audit log of all data changes.

no
Role-Based Access Control

Granular permissions based on user roles.

no
SSO Support

Single Sign-On integration support.

None

eCommerce Integrations

Connectivity with other systems including DAM, ERP, e-commerce platforms, and marketplaces.

DAM Integration

Integration with Digital Asset Management systems.

no
ERP Integration

Native integrations with ERP systems.

E-commerce Connectors

Pre-built connectors for e-commerce platforms.

Marketplace Syndication

Direct syndication to online marketplaces.

API Access

Type of API available for custom integrations.

REST
Webhook Support

Outbound webhooks for event-driven integrations.

no

Listing AI & Automation

Artificial intelligence and automation capabilities for content generation, categorization, and optimization.

AI Content Generation

AI-powered generation of product descriptions and content.

yes  ]
AI Image Enhancement

AI tools for image optimization, background removal, etc.

no
Automated Categorization

AI-powered automatic product categorization.

yes  ]
Smart Attribute Extraction

Automatic extraction of product attributes from descriptions or images.

yes  ]
AI/MT Translation

Built-in machine translation for product content.

no

eCommerce Publishing & Channels

Capabilities for distributing product content across multiple channels and formats.

Multi-channel Publishing

Publish product data to multiple channels from a single source.

yes  ]
Print Catalog Generation

Generate print-ready catalogs and datasheets.

no
Headless/API-first

API-first architecture for headless commerce.

yes  ]
Digital Shelf Analytics

Analytics on product performance across digital channels.

no
Scheduled Publishing

Schedule product updates to go live at specific times.

no

Reviews

0 reviews
Write a Review

No reviews yet. Be the first to review FacetFlux!