FacetFlux

FacetFlux

Verified verified 3 jul 2026
editor's choice  ] score · 45  ]

The Particle Accelerator for Product Data

Pricing: Contact Us - Available upon request (Targeting $20M+ GMV brands) Company: FacetFlux Founded: 2024 Last verified: 2026-07-03
Visit Website Verified Vendor Updated

TL;DR

FacetFlux is an API-first, headless PIM designed for mid-market e-commerce brands ($20M-$200M GMV) navigating rapid scaling. It differentiates itself with a graph-based architecture and an AI-powered 'Dirty Data' staging layer that cleanses messy supplier imports before they reach the core system.

What Users Actually Pay

No user-reported pricing yet.

Our Take

FacetFlux positions itself as a 'Particle Accelerator' for product data, prioritizing technical agility and speed over the heavy administrative workflows of legacy PIMs. Its graph-based schema allows for complex product relationships and rapid attribute changes that would cripple traditional relational databases, making it an ideal choice for brands in high-volatility categories. The platform's standout feature is the 200ms synchronization engine, which ensures that catalog updates across Shopify, Mirakl, and other headless storefronts happen in near real-time. While it excels in performance and AI-assisted ingestion, its focus on the 'scale-up' niche means it may lack the extensive legacy ERP connector libraries found in enterprise giants like Akeneo or Salsify. It is best suited for digitally native brands that have outgrown spreadsheets but require a developer-centric, headless approach to product information.

Pros

  • + Blazing fast 200ms synchronization for real-time inventory and data updates
  • + AI-driven 'Dirty Data' staging layer handles raw CSV and PDF imports without manual cleaning
  • + Graph-based database architecture supports complex, non-linear product relationships
  • + Modern spreadsheet-like interface allows for high-performance bulk editing and macros

Cons

  • - Targeting $20M+ GMV brands creates a high entry barrier for smaller retailers
  • - Relatively new platform (founded 2024) with a smaller ecosystem of community plugins
  • - Focused on headless architecture, which may require more developer resources to implement

Sentiment Analysis

+0.88Very PositiveUpdated Jun 17, 2026

Sentiment has remained stable since last capture. Sentiment has improved from 0.83 to 0.88 as the platform matures. Users highly value the speed of the graph architecture and the AI staging layer, frequently comparing its developer experience to modern tools like Linear.

Sentiment Over Time

By Source

revuo.ai+0.90

15 mentions

Sample quotes (2)
  • "FacetFlux is basically the Linear of PIMs. Fast, focused, and actually understands the modern e-comm workflow."
  • "Seeing 200ms sync times for a 50k SKU catalog is wild."
Reddit+0.85

32 mentions

Sample quotes (1)
  • "The 'Dirty Data' staging is a game changer for supplier onboarding. We used to spend days in Excel before importing; now AI does the heavy lifting."
X (Twitter)+0.88

24 mentions

Sample quotes (1)
  • "Finally a PIM that treats product data as a typed graph rather than just documents. FacetFlux is the future of headless commerce."

Agent Readiness

59/100

FacetFlux is highly agent-ready due to its API-first, headless nature and 'Dirty Data' staging layer, which is purpose-built for AI-assisted data manipulation. Its support for REST and GraphQL, combined with robust webhook triggers and clear OpenAPI documentation, makes it an ideal hub for autonomous agents to manage product catalogs, though the lack of no-code connectors like Zapier means integration currently requires developer intervention.

API Surface100
Public APIRESTGraphQLFree TieropenApi
Protocol Support40
MCP (44 tools)
SDK Availability0
Integration Ecosystem25
WebhooksShopifyMiraklWooCommerceETIM xChangeBMEcat
Developer Experience100
Docs: excellentSandboxVersioningChangelogStatus Page

Last checked Jun 17, 2026

MCP Integrations

1 server44 tools
FacetFlux MCPrevuo:facetflux
self-registeredRemoteHigh match

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 Jul 10, 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.

Shopify  ]
Marketplace Syndication

Direct syndication to online marketplaces.

Amazon  ]
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.

no
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!