# Get apiv1diagnostics Source: https://docs.facetflux.com/api-reference/diagnostics/get-apiv1diagnostics https://app.facetflux.com/api/openapi/v1.json get /api/v1/diagnostics # Get apiv1diagnostics 1 Source: https://docs.facetflux.com/api-reference/diagnostics/get-apiv1diagnostics-1 https://app.facetflux.com/api/openapi/v1.json get /api/v1/diagnostics/{id} # Get apiv1diagnostics report Source: https://docs.facetflux.com/api-reference/diagnostics/get-apiv1diagnostics-report https://app.facetflux.com/api/openapi/v1.json get /api/v1/diagnostics/{id}/report # Post apiv1diagnostics Source: https://docs.facetflux.com/api-reference/diagnostics/post-apiv1diagnostics https://app.facetflux.com/api/openapi/v1.json post /api/v1/diagnostics # Get apiv1pimproducts enrichment Source: https://docs.facetflux.com/api-reference/enrichment/get-apiv1pimproducts-enrichment https://app.facetflux.com/api/openapi/v1.json get /api/v1/pim/products/{productId}/enrichment # Post apiv1pimproducts enrich Source: https://docs.facetflux.com/api-reference/enrichment/post-apiv1pimproducts-enrich https://app.facetflux.com/api/openapi/v1.json post /api/v1/pim/products/{productId}/enrich # Post apiv1pimproducts enrichment accept Source: https://docs.facetflux.com/api-reference/enrichment/post-apiv1pimproducts-enrichment-accept https://app.facetflux.com/api/openapi/v1.json post /api/v1/pim/products/{productId}/enrichment/{suggestionId}/accept # Post apiv1pimproducts enrichment reject Source: https://docs.facetflux.com/api-reference/enrichment/post-apiv1pimproducts-enrichment-reject https://app.facetflux.com/api/openapi/v1.json post /api/v1/pim/products/{productId}/enrichment/{suggestionId}/reject # Post apiv1pimproductsenrichmentbatch Source: https://docs.facetflux.com/api-reference/enrichment/post-apiv1pimproductsenrichmentbatch https://app.facetflux.com/api/openapi/v1.json post /api/v1/pim/products/enrichment/batch # Post apiv1pimproductsenrichmentestimate Source: https://docs.facetflux.com/api-reference/enrichment/post-apiv1pimproductsenrichmentestimate https://app.facetflux.com/api/openapi/v1.json post /api/v1/pim/products/enrichment/estimate # Get apiv1pimexports download Source: https://docs.facetflux.com/api-reference/exports/get-apiv1pimexports-download https://app.facetflux.com/api/openapi/v1.json get /api/v1/pim/exports/{jobId}/download # Get apiv1pimexports status Source: https://docs.facetflux.com/api-reference/exports/get-apiv1pimexports-status https://app.facetflux.com/api/openapi/v1.json get /api/v1/pim/exports/{jobId}/status # Get apiv1pimexportsproducts Source: https://docs.facetflux.com/api-reference/exports/get-apiv1pimexportsproducts https://app.facetflux.com/api/openapi/v1.json get /api/v1/pim/exports/products/{productId} # Get apiv1pimexportsprofiles Source: https://docs.facetflux.com/api-reference/exports/get-apiv1pimexportsprofiles https://app.facetflux.com/api/openapi/v1.json get /api/v1/pim/exports/profiles # Post apiv1pimexportscatalog Source: https://docs.facetflux.com/api-reference/exports/post-apiv1pimexportscatalog https://app.facetflux.com/api/openapi/v1.json post /api/v1/pim/exports/catalog # Post apiv1pimexportsselection Source: https://docs.facetflux.com/api-reference/exports/post-apiv1pimexportsselection https://app.facetflux.com/api/openapi/v1.json post /api/v1/pim/exports/selection # API reference Source: https://docs.facetflux.com/api-reference/introduction Interactive reference for every FacetFlux REST endpoint, generated from the live OpenAPI spec. Every endpoint below is generated from the live FacetFlux OpenAPI specification, so the reference always matches what the API actually does. Each page has an interactive playground — set your API key once and send real requests against your own tenant. ## Base URL ``` https://app.facetflux.com ``` ## Authentication All endpoints take an API key as a Bearer token: ``` Authorization: Bearer ``` Mint a key under **Settings → API keys** in the app. Read-only keys can call `GET` endpoints only. See [Authentication](/authentication) for the full details. ## The endpoints * **Product Catalog** — read products, schemas, and attribute definitions. * **Diagnostics** — upload a catalog file and fetch its completeness report. * **Enrichment** — enrich products with AI and manage the resulting suggestions. * **Exports** — generate single-product, selection, and full-catalog exports. Prefer a task-oriented walkthrough? The [guides](/guides/diagnostics) explain each capability end to end before you dive into individual endpoints. # Get product by id Source: https://docs.facetflux.com/api-reference/product-catalog/get-product-by-id https://app.facetflux.com/api/openapi/v1.json get /api/v1/public/products/{id} # Get schema by id Source: https://docs.facetflux.com/api-reference/product-catalog/get-schema-by-id https://app.facetflux.com/api/openapi/v1.json get /api/v1/public/schemas/{id} # List attribute definitions in schema Source: https://docs.facetflux.com/api-reference/product-catalog/list-attribute-definitions-in-schema https://app.facetflux.com/api/openapi/v1.json get /api/v1/public/schemas/{id}/attributes # List product types in schema Source: https://docs.facetflux.com/api-reference/product-catalog/list-product-types-in-schema https://app.facetflux.com/api/openapi/v1.json get /api/v1/public/schemas/{id}/types # List products Source: https://docs.facetflux.com/api-reference/product-catalog/list-products https://app.facetflux.com/api/openapi/v1.json get /api/v1/public/products # List schemas Source: https://docs.facetflux.com/api-reference/product-catalog/list-schemas https://app.facetflux.com/api/openapi/v1.json get /api/v1/public/schemas # Search products Source: https://docs.facetflux.com/api-reference/product-catalog/search-products https://app.facetflux.com/api/openapi/v1.json get /api/v1/public/products/search # Authentication Source: https://docs.facetflux.com/authentication Every request is authenticated with a tenant-scoped API key sent as a Bearer token. FacetFlux authenticates API and MCP requests with an **API key** sent in the `Authorization` header: ``` Authorization: Bearer ``` Every key belongs to a single tenant, and every response is scoped to that tenant's data. There is no separate account ID to send — the key identifies the tenant. ## Creating a key 1. Sign in at [app.facetflux.com](https://app.facetflux.com) as a tenant admin. 2. Go to **Settings → API keys**. 3. Click **Create new key**, give it a name, and choose a permission level (see below). 4. Copy the key immediately — it's shown **once** and cannot be retrieved later. Only the last four characters are visible afterward. Treat API keys like passwords. A key grants access to your entire tenant's catalog within its permission level. If a key leaks, delete it from **Settings → API keys** and mint a new one. ## Permission levels When you create a key you pick what it's allowed to do. This is enforced on both the REST API and the MCP server. | Permission | Can read | Can write | Use it for | | ---------------- | -------- | --------- | -------------------------------------------------------------------- | | **Read-only** | Yes | No | Sync catalog data out, dashboards, reporting, read-only agents. | | **Read & write** | Yes | Yes | Integrations that push products, run enrichment, or trigger exports. | | **Admin** | Yes | Yes | Automation that also manages tenant settings. | A **read-only** key can only make `GET` requests on the REST API; any mutating call returns `403` with `read_only_api_key`. On the MCP server, read-only keys can call read tools but mutating tools return a `read_only_key` error. Choose the narrowest permission that does the job. ## Using the key ```bash cURL theme={null} curl https://app.facetflux.com/api/v1/public/products \ -H "Authorization: Bearer $FACETFLUX_API_KEY" ``` ```python Python theme={null} import os, requests resp = requests.get( "https://app.facetflux.com/api/v1/public/products", headers={"Authorization": f"Bearer {os.environ['FACETFLUX_API_KEY']}"}, ) resp.raise_for_status() print(resp.json()) ``` ```typescript TypeScript theme={null} const resp = await fetch("https://app.facetflux.com/api/v1/public/products", { headers: { Authorization: `Bearer ${process.env.FACETFLUX_API_KEY}` }, }); if (!resp.ok) throw new Error(`${resp.status} ${await resp.text()}`); console.log(await resp.json()); ``` Keep keys out of source control. Read them from an environment variable or a secrets manager, as the examples above do. # Core concepts Source: https://docs.facetflux.com/concepts The handful of objects you'll work with — products, schemas, product types, and attributes. A few objects show up across every FacetFlux endpoint. Understanding how they fit together makes the rest of the API obvious. ## Products and variants A **product** is a single catalog item. A product can have **variants** — concrete purchasable versions that differ along one or more axes (size, color, length). A cordless drill is a product; the 2 Ah and 4 Ah kits are its variants. Attribute values live at whichever level they belong to: * **Product-scoped** — the same for every variant (brand, product family, description). * **Variant-defining** — the axes that distinguish variants (voltage, capacity). * **Per-variant** — differ by variant but don't define them (weight, GTIN). When you write attribute values you target either the product or a specific variant, and the attribute's scope has to match the target. ## Schemas, product types, and attributes A **schema** is the shape of a slice of your catalog. It contains: * **Product types** — what *kind* of thing a product is. A product type determines which attributes a product is expected to have. (Product type is about structure and data — it is not the same as a merchandising category like "Summer Sale.") * **Traits** — reusable bundles of attributes that product types are composed from. * **Attribute definitions** — the typed fields themselves: a name, a data type, and optionally allowed values. You'll usually **read** schemas to interpret product data — an API response gives you attribute *values* keyed by attribute-definition id, and the schema tells you what each one means. ## Attribute data types Every attribute value is native JSON matching its definition's data type: | Data type | JSON shape | Example | | ----------------- | ---------------------- | ----------------------------------- | | Text | string | `"Bosch"` | | Translatable text | object keyed by locale | `{ "en": "Drill", "de": "Bohrer" }` | | Number / Decimal | number | `18` | | Boolean | boolean | `true` | | Enum | string (the value) | `"cordless"` | | MultiEnum | array of strings | `["cordless", "brushless"]` | Enum-typed values are always the **string value**, in `camelCase` — never a numeric index. This matches how the whole API serializes enumerations. ## Classification standards FacetFlux classifies products to industry standards — primarily **ETIM** and **eCl\@ss**. Classification maps a product to a class in the standard (for example an ETIM class) and, where enabled, to the standard's expected features. Enrichment can fill and normalize the values those classes expect. ## Credits and pricing AI operations (enrichment, some diagnostics) are billed per product. Reads of your own catalog are not. Pricing is per outcome — see the [pricing page](https://facetflux.com/pricing) for current rates. Enrichment responses include usage headers so you can track consumption programmatically; see [Enrichment](/guides/enrichment). # Diagnostics Source: https://docs.facetflux.com/guides/diagnostics Upload a catalog file and get a completeness report — fill rates, product types, and quality gaps. The diagnostic is the fastest way to see what's in a catalog. You upload a CSV or Excel file, FacetFlux profiles it, and you get back a report: how complete each column is, what product types it found, ETIM readiness, and a few sample enrichments. The first runs per tenant are free. It's a two-step flow: **start** a diagnostic (returns immediately with an id), then **poll** until it's done and fetch the report. ## Start a diagnostic The upload is a **raw-body** `POST` — the request body *is* the file bytes, not multipart form data. Two headers matter: * `Content-Type` — send the exact Excel MIME type `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` for `.xlsx`; **any other value is treated as CSV**. * `Content-Disposition` — carries the filename, e.g. `attachment; filename="catalog.csv"`. An optional `?language=` query parameter (`en` or `de`, default `en`) sets the report language. ```bash cURL theme={null} curl -X POST "https://app.facetflux.com/api/v1/diagnostics?language=en" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" \ -H "Content-Type: text/csv" \ -H 'Content-Disposition: attachment; filename="catalog.csv"' \ --data-binary @catalog.csv ``` ```python Python theme={null} import os, requests with open("catalog.csv", "rb") as f: body = f.read() resp = requests.post( "https://app.facetflux.com/api/v1/diagnostics", params={"language": "en"}, headers={ "Authorization": f"Bearer {os.environ['FACETFLUX_API_KEY']}", "Content-Type": "text/csv", "Content-Disposition": 'attachment; filename="catalog.csv"', }, data=body, ) resp.raise_for_status() diagnostic_id = resp.json()["id"] ``` A successful start returns `202 Accepted` with `{ "id": "...", "wasFree": true }`. The `id` identifies the report you'll poll for. Only one diagnostic runs per tenant at a time — starting a second while one is active returns `409`. Starts are also rate-limited to a few per hour. ## Poll for completion Poll `GET /api/v1/diagnostics/{id}` until `status` is `completed` (or `failed`): ```python Python theme={null} import time while True: r = requests.get( f"https://app.facetflux.com/api/v1/diagnostics/{diagnostic_id}", headers={"Authorization": f"Bearer {os.environ['FACETFLUX_API_KEY']}"}, ).json() if r["status"] in ("completed", "failed"): break print(r["phase"], r.get("progress")) time.sleep(2) ``` The poll response carries `status` (`queued` / `processing` / `completed` / `failed`), a human-readable `phase`, `progress`, and `error` if it failed. ## Read the report Once completed, fetch the full report: ```bash theme={null} curl "https://app.facetflux.com/api/v1/diagnostics/$DIAGNOSTIC_ID/report" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" ``` The report is built in phases, so the fields fill in as the analysis progresses: * **Profile** — `averageCompleteness` (overall score) and `columns`, each with a `fillRate`, `rowsWithValue`, `uniqueValueCount`, and `topValues`. * **Understand** — `typeGroups` (the product types it detected, each with its own completeness and per-attribute fill rates), a `qualityNarrative`, and structured `issues`. * **ETIM readiness** — `etimReadiness` per product type: the matched ETIM class, coverage percentage, and `missingFeatures` the class expects. * **Samples** — a few `samples` showing `before` values and AI `suggestions`, so you can see the kind of enrichment FacetFlux would produce. `GET /api/v1/diagnostics` returns your ten most recent reports (a bare array, newest first). The diagnostic shows what's missing. Enrichment fills it — see the Enrichment guide. # Enrichment Source: https://docs.facetflux.com/guides/enrichment Fill missing specs, normalize values, and classify products with AI — every value comes with a source. Enrichment runs AI over a product and proposes attribute values: filled specifications, normalized units, generated descriptions, classifications. Suggestions are returned for you to **accept or reject** — nothing overwrites your data until you say so. Every suggestion carries a `reasoning` and a `confidence`. ## Modes Each enrichment call takes a `mode` that controls how much evidence the AI gathers — and how much it costs per product: | Mode | Uses | Best for | | ---------- | ----------------------------------------------------------- | ------------------------------------------ | | `standard` | Product images + existing attribute values | Fast, cheap passes on data you mostly have | | `enhanced` | Everything in standard, plus linked PDFs and document URLs | Products with datasheets attached | | `deep` | Everything in enhanced, plus web search of the product page | Sparse products that need outside data | ## Enrich a single product `POST /api/v1/pim/products/{productId}/enrich?mode=standard` runs synchronously and returns a **suggestion**: ```bash cURL theme={null} curl -X POST "https://app.facetflux.com/api/v1/pim/products/$PRODUCT_ID/enrich?mode=enhanced" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" ``` ```python Python theme={null} resp = requests.post( f"https://app.facetflux.com/api/v1/pim/products/{product_id}/enrich", params={"mode": "enhanced"}, headers={"Authorization": f"Bearer {os.environ['FACETFLUX_API_KEY']}"}, ) resp.raise_for_status() suggestion = resp.json() for code, field in suggestion["fieldSuggestions"].items(): print(code, "→", field["value"], f"({field['confidence']})") ``` The response is a `PimEnrichmentSuggestion` with a `fieldSuggestions` map, keyed by attribute code. Each entry has the proposed `value`, a `reasoning` string, a `confidence` (0–1), and `accepted` / `rejected` flags. A `200` response can still carry a non-completed `status` — check `status == "completed"` and `errorMessage` before trusting the suggestions. Values are only charged and returned when enrichment actually completes. ## Accept or reject Suggestions don't change your product until you accept them: ```bash theme={null} # Accept one field curl -X POST ".../enrichment/$SUGGESTION_ID/accept" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "attributeCode": "length_mm" }' # Accept everything curl -X POST ".../enrichment/$SUGGESTION_ID/accept" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "all": true }' ``` Rejecting works the same way but always needs a specific `attributeCode`. ## Estimate and batch Before a large run, `POST /api/v1/pim/products/enrichment/estimate` with a list of `productIds` and a `mode` tells you whether you can proceed — it returns `creditsRequired`, `creditsAvailable`, and `canProceed`, and does no AI work. To enrich many products, `POST /api/v1/pim/products/enrichment/batch` accepts up to **200** `productIds`. It processes them sequentially and returns per-product `results`, `successCount`, and `failedCount`. ```python Python theme={null} resp = requests.post( "https://app.facetflux.com/api/v1/pim/products/enrichment/batch", headers={"Authorization": f"Bearer {os.environ['FACETFLUX_API_KEY']}"}, json={"productIds": product_ids[:200], "mode": "standard"}, ) resp.raise_for_status() print(resp.json()["successCount"], "enriched") ``` Enrichment is billed per product; reads are free. Cost scales with mode (`enhanced` and `deep` cost more than `standard`). Enrichment responses include `x-credits-left` and `x-credits-used` headers so you can track usage. See [pricing](https://facetflux.com/pricing) for rates. Running at scale without writing a loop? The [MCP server](/mcp) exposes these same operations as agent tools with idempotent, per-product writes. # Exports Source: https://docs.facetflux.com/guides/exports Turn your catalog into BMEcat, CSV, or channel-specific formats through reusable export profiles. Exports convert your enriched products into the formats your channels expect. Every export runs through an **export profile** — a named target that binds your attributes to a format and serializer. You list the profiles available for a schema, then export a single product, a selection, or the whole catalog. ## List export profiles `GET /api/v1/pim/exports/profiles?schemaId=...` returns the profiles that apply to a schema: ```bash theme={null} curl "https://app.facetflux.com/api/v1/pim/exports/profiles?schemaId=$SCHEMA_ID" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" ``` Each profile has a `key` (used in the export calls below), a `displayName`, the `contentType` and `fileExtension` it produces, and the `languages` it supports (`available` plus a `default`). ## Export one product `GET /api/v1/pim/exports/products/{productId}?profileKey=...&language=...` returns the file directly — the `Content-Type` matches the profile, and the body is the export: ```bash theme={null} curl "https://app.facetflux.com/api/v1/pim/exports/products/$PRODUCT_ID?profileKey=bmecat&language=de" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" \ -o product.xml ``` ## Export a selection `POST /api/v1/pim/exports/selection` bundles up to **200** products into a ZIP synchronously: ```python Python theme={null} resp = requests.post( "https://app.facetflux.com/api/v1/pim/exports/selection", headers={"Authorization": f"Bearer {os.environ['FACETFLUX_API_KEY']}"}, json={"productIds": ids[:200], "profileKey": "bmecat", "language": "de"}, ) resp.raise_for_status() open("selection.zip", "wb").write(resp.content) ``` For more than 200 products, use a catalog export job instead. ## Export the whole catalog A full-schema export runs as a background job. Start it, poll status, then download: `POST /api/v1/pim/exports/catalog` with `{ "schemaId": "...", "profileKey": "...", "language": "..." }` returns `202` with a `jobId`. ```python theme={null} job = requests.post( "https://app.facetflux.com/api/v1/pim/exports/catalog", headers=headers, json={"schemaId": schema_id, "profileKey": "bmecat", "language": "de"}, ).json() job_id = job["jobId"] ``` `GET /api/v1/pim/exports/{jobId}/status` returns `status` (`Queued` / `Processing` / `Success` / `Failed`), `progress`, and `ready` — poll until `ready` is `true`. `GET /api/v1/pim/exports/{jobId}/download` streams the artifact once the job succeeded. ```bash theme={null} curl "https://app.facetflux.com/api/v1/pim/exports/$JOB_ID/download" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" -o catalog.zip ``` Only one catalog export runs per (schema, profile) at a time — starting a duplicate returns `409`. Downloading before the job succeeds returns `409`; the artifact is retained for a limited time after completion. Job status uses capitalized values (`Success`, `Queued`, `Processing`, `Failed`) — distinct from the lowercase `status` values on products and diagnostics. Compare exact strings. # Product catalog Source: https://docs.facetflux.com/guides/product-catalog Read products, schemas, and attribute definitions to sync enriched data back into your own systems. The catalog API is the read side: pull products, and pull the schemas that tell you what a product's fields mean. It's how you sync FacetFlux's enriched data back into your PIM, storefront, or data warehouse. All catalog reads work with a **read-only** key. ## List and fetch products `GET /api/v1/public/products` returns a paged envelope: ```bash theme={null} curl "https://app.facetflux.com/api/v1/public/products?page=1&pageSize=50&status=active" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" ``` ```json theme={null} { "page": 1, "pageSize": 50, "totalCount": 1284, "data": [ { "id": "...", "skuList": ["..."], "roleValues": { "name": "..." } } ] } ``` The items live under `data` (not `items`) and the total is `totalCount`. `pageSize` is capped at 200. Optional filters: `status` (`active`, `draft`, `archived`, `requiresAttention`) and `purpose` (`standard`, `onDemand`, `internal`). Each product carries its identifiers (`skuList`, `productNumber`), its structure (`schemaId`, `primaryTypeId`, `traitIds`, `channelCodes`), and a convenience `roleValues` block with the resolved `name`, `description`, `brand`, `customerProductId`, and `primaryImageUrl` — enough to render a product card without touching the schema. * `GET /api/v1/public/products/{id}` — one product. * `GET /api/v1/public/products/search?q=...` — full-text over name, description, brand, and SKU; same paged envelope. ## Interpreting attribute values A product's detailed attribute values are keyed by attribute-definition id. To know what each one means, read the schema's attribute definitions: `GET /api/v1/public/schemas` returns each schema with its `kind` (`master`, `standard`, …), any `standardCode` / `standardVersion`, and counts of types, traits, and attributes. `GET /api/v1/public/schemas/{id}/types` lists the product types — what kind of thing each product is, and which traits it's built from. `GET /api/v1/public/schemas/{id}/attributes` returns each definition's `code`, `labels`, `dataType`, `scope`, `role`, and `unit`. Match a value's definition id here to learn its type and meaning. The `dataType` tells you the JSON shape of the value (`text`, `number`, `boolean`, `enum`, `multiEnum`, …) and `scope` tells you whether it lives on the product or a variant. See [Core concepts](/concepts) for the full data-type mapping. Schemas for shared industry standards (ETIM, eCl\@ss) are readable by any tenant, so you can resolve standard classifications even for classes you didn't create. Every field of every response is documented in the interactive API reference — with a playground to try calls against your own tenant. # FacetFlux API Source: https://docs.facetflux.com/index Enrich, classify, and export product data programmatically — or hand the whole toolset to an AI agent over MCP. FacetFlux turns messy product catalogs into clean, classified, export-ready data. Everything you can do in the app you can do over the API: run a free catalog **diagnostic**, **enrich** products with AI, read your **catalog**, and generate **exports** in the formats your channels expect. There are two ways in: A JSON API over `https://app.facetflux.com`. Authenticate with a Bearer key and call the endpoints directly, or explore them in the interactive [API reference](/api-reference/introduction). The full toolset as a Model Context Protocol server. Point Claude, Cursor, or your own agent at `https://app.facetflux.com/api/mcp` and it can read schemas, upsert products, and run imports on your behalf. ## What you can do Upload a catalog file and get a completeness report — fill rates, detected product types, and quality gaps. The first runs are free. Fill missing specs, normalize values, generate descriptions, and classify to ETIM and eCl\@ss — every value comes with a source. Turn your catalog into BMEcat, CSV, or channel-specific formats through reusable export profiles. Read products, schemas, and attribute definitions to sync your enriched data back into your own systems. ## Before you start You'll need a FacetFlux account and an API key. API access is available on any paid plan — see [pricing](https://facetflux.com/pricing). Head to [Quickstart](/quickstart) to make your first call in a couple of minutes. New to FacetFlux? The [free catalog diagnostic](https://facetflux.com) is the fastest way to see what the platform finds in your data — no code required. # MCP server Source: https://docs.facetflux.com/mcp The full FacetFlux toolset as a Model Context Protocol server — connect Claude, Cursor, or your own agent. FacetFlux exposes its toolset as a [Model Context Protocol](https://modelcontextprotocol.io) server. Point an MCP-capable client at it and an AI agent can read your schemas, search and upsert products, set attribute values, run smart imports, and poll jobs — all scoped to your tenant and governed by your API key's permission. ``` https://app.facetflux.com/api/mcp ``` Authentication is the same Bearer key as the REST API (see [Authentication](/authentication)). A **read-only** key can call read tools only; mutating tools return a `read_only_key` error. ## Connecting ```bash theme={null} claude mcp add --transport http facetflux \ https://app.facetflux.com/api/mcp \ --header "Authorization: Bearer YOUR_API_KEY" ``` Add a custom connector with the URL `https://app.facetflux.com/api/mcp` and an `Authorization: Bearer YOUR_API_KEY` header. Add an HTTP MCP server entry pointing at `https://app.facetflux.com/api/mcp` with an `Authorization` header carrying your Bearer key. Give agents the narrowest key that does the job. For an agent that only reads or drafts, mint a **read-only** key — mutating tools will be refused even if the agent tries to call them. ## What the tools cover Tools are grouped by namespace. Read tools are always available; write tools require a read & write (or admin) key. Read and build the shape of your catalog: list and inspect schemas, product types, traits, and attribute definitions; create schemas and product types; add traits and attributes; set aliases and allowed values. Search products one filter at a time, fetch a product with its variants and resolved values, upsert products by source system + external id (idempotent), batch-create, set or merge attribute values on a product or variant, manage categories/channels/traits, and set status (draft / active / archived / requiresAttention). List channels and create channel overlays that adapt a master schema to a specific distribution target. Apply column→attribute mappings as a pure transform, or run a Smart Import: start from inline CSV/JSON, run AI inference, review, and execute to create the schema and products. Poll the status and progress of long-running work (inference, catalog exports). ## Why an agent, not just the REST API The MCP tools are designed for autonomous use: writes are idempotent (upsert by your own external id), collection changes use explicit add/remove verbs to avoid read-modify-write races, and destructive operations are archival rather than hard deletes. An agent can safely iterate over a catalog — classify a product, set the values its class expects, move it to `active` — without you scripting each call. If you're building a conventional integration rather than an agent, start with the REST [Quickstart](/quickstart) and the [API reference](/api-reference/introduction). # Quickstart Source: https://docs.facetflux.com/quickstart Make your first authenticated FacetFlux API call in a couple of minutes. This guide gets you from zero to a working API call. You'll need a FacetFlux account on a paid plan ([API access is included](https://facetflux.com/pricing)). ## 1. Create an API key Sign in at [app.facetflux.com](https://app.facetflux.com) as a tenant admin, go to **Settings → API keys**, and create a key. Copy it now — it's shown only once. For a first read-only test, a **read-only** key is enough. See [Authentication](/authentication) for the full details. ```bash theme={null} export FACETFLUX_API_KEY="your-key-here" ``` ## 2. Read your catalog Every response is scoped to the tenant your key belongs to. List the first page of products: ```bash cURL theme={null} curl "https://app.facetflux.com/api/v1/public/products" \ -H "Authorization: Bearer $FACETFLUX_API_KEY" ``` ```python Python theme={null} import os, requests BASE = "https://app.facetflux.com" headers = {"Authorization": f"Bearer {os.environ['FACETFLUX_API_KEY']}"} resp = requests.get(f"{BASE}/api/v1/public/products", headers=headers) resp.raise_for_status() print(resp.json()) ``` ```typescript TypeScript theme={null} const BASE = "https://app.facetflux.com"; const headers = { Authorization: `Bearer ${process.env.FACETFLUX_API_KEY}` }; const resp = await fetch(`${BASE}/api/v1/public/products`, { headers }); if (!resp.ok) throw new Error(`${resp.status} ${await resp.text()}`); console.log(await resp.json()); ``` If you get a `401`, the key is missing or wrong. A `403 read_only_api_key` means you tried a write with a read-only key. ## 3. Pick your path Upload a catalog file and get a completeness report. The best first look at your data. Fill missing specs and classify to ETIM / eCl\@ss with AI. Generate BMEcat, CSV, or channel-specific output. Connect the MCP server and let an AI agent do the work. Prefer to click through the endpoints? The [API reference](/api-reference/introduction) has an interactive playground — paste your key once and try any call in the browser.