# An improved CSV experience
Source: https://docs.cernel.com/blog/an-improved-csv-experience
A ground-up redesign of CSV import and export: column analysis that maps your file for you, catalog and vendor import modes, reusable export templates, and a preview of every change before it runs.
**June 22, 2026**
Not every catalog lives in Shopify. Plenty of product data sits in spreadsheets: a supplier's price list, an export from an ERP, a hand-maintained master file. CSV is the one format every one of those systems can read and write, which is exactly why it is the most universal way to get product data into Cernel and back out again.
This release rebuilds the CSV experience from the ground up. Importing now reads your file for you and proposes a complete mapping before you commit. Exporting becomes template-based, so the layout your downstream systems expect is saved once and reused on demand. The result is product data that moves in and out of Cernel in a way that is more standardized, faster, and safer.
CSV import and export also have a proper home now. In the sidebar, open **CSV** under **Tools**, where you will find two tabs: **CSV Import** and **CSV Export Templates**.
## Imports that read the file for you
The biggest change is what happens the moment you upload a file. Cernel analyzes it column by column: it streams statistics about the values it finds, works out the data format of each column, and classifies the role each one plays. It recognizes a product title, a product URL, an image URL, a product identifier (such as SKU or GTIN), or a regular attribute, and then proposes how every column should map onto your Cernel attributes and identifiers.
You are never staring at a blank mapping screen. You review Cernel's suggestions, adjust anything that needs a human eye, and add any columns it set aside. Where it recommends a new attribute, you accept it with a single click.
Before anything is written to your catalog, you get an import preview: how many products will be **created**, how many will be **updated**, and which new attributes or identifiers the import will add. Nothing happens until you have seen the impact and clicked **Run import**.
## Two ways to bring a file in
When you start an import, Cernel asks where the file is coming from. The answer changes how the file is matched to your catalog.
### From catalog
Choose **From catalog** when the file is an export of your own catalog. It already has the structure and column names you maintain, so Cernel preserves your headers as they are and is built for predictable round-trips: export, edit or enrich, then re-import in the same shape.
### From vendor
Choose **From vendor** for the differently-shaped files you receive from suppliers. Each vendor sends something a little different, and Cernel maps every one of them onto your existing attributes and identifier types, so many shapes converge into a single, consistent catalog. For identifiers it uses a two-pass approach: a first, bias-free pass that decides which columns are identifiers at all, then a second pass that assigns each one its identifier type.
A quick way to remember which to pick: you made the file, choose **From catalog**; they made it, choose **From vendor**.
## Exports you can reuse
Exporting is now built around templates. A **CSV export template** is a saved column layout: the attributes and identifiers to include, the output header names, and the column order. Define it once, then run it from the **Products** page whenever you need a fresh file, and every export comes out in exactly the same shape.
That consistency is what makes the round-trip work. Because a **From catalog** import preserves your headers and a template reproduces them on the way out, an export, edit, re-import cycle lines up column for column with no manual fix-up in between.
You are not locked into templates. You can still pick columns ad hoc at export time, and you can turn on **Export only values Cernel produced** to leave imported data out of the file, so it carries only what Cernel generated or you edited.
## Why it matters
Taken together, these changes make CSV a first-class way to run Cernel rather than a fallback. You can operate entirely on CSV, with no store, PIM, or API connection: import your catalog, enrich it, and export the enriched data back out. The file reads itself in, the preview tells you what will change before it does, and templates keep every file you send out in the shape your other systems expect.
The full reference walks through every screen of importing and exporting, plus advanced options and troubleshooting.
# Decide what goes live: Jobs and Review
Source: https://docs.cernel.com/blog/jobs-and-review
Enrichment now separates running a job from approving its results. Track every run on the Jobs page, then approve, edit, or reject each proposed value on the new Review surface, with the prompt and reasoning behind it.
**June 28, 2026**
AI enrichment can fill thousands of attribute values in minutes. The harder question has always been the one that comes next: which of those values do you trust enough to put in front of customers? For a long time, generating content and deciding what to keep were tangled together in a single view, which made it hard to move fast and stay in control at the same time.
This release pulls the two apart. A **job** runs your agents and proposes values. The new **Review** surface is where you decide what actually goes live. When review is turned on, nothing reaches your products or your integrations until you approve it. The result is enrichment you can run at scale and still stand behind.
You will find **Review** at the top of the Products area, as a tab next to **Catalog**, and you can drop straight into a single run from the **Jobs** page.
## Two steps, clearly separated
Enrichment now happens in two distinct stages. First a job processes your selected products with the agents linked to your attributes and proposes new values. Then those values wait for a decision.
What happens to them depends on one toggle. With **Review** on, proposed values are held as pending and collected on the Review surface for your approval. With it off, they are applied to your products automatically as soon as they are generated. The toggle starts from your organization's approve-before-push setting, and you can override it for any single run.
## A queue built for decisions
The Review surface lists one row per product, with a card for every proposed value. Each card shows the attribute, the language, and a status: **In review**, **Approved**, **Rejected**, **Failed**, **Skipped**, or **Outdated**. You can narrow the queue by language, by job, or by attribute, and you can hide the values that failed or were skipped once you have dealt with them.
Three actions cover everything you will want to do:
* **Approve** keeps a value and saves it to the product.
* **Reject** discards it and leaves the current value untouched.
* **Dismiss** clears a failed or skipped value once you have seen it, since there is nothing there to approve.
Approvals and rejections can carry an optional comment, which is useful when a teammate reviews the same catalog later. When you trust the output, select many values, or whole product rows, and decide in bulk. For a large bulk decision, Cernel asks you to confirm first.
## The reasoning behind every value
Reviewing well means understanding what you are looking at, so each product opens into a detail view with three columns. On the left is the **current value** saved on the product today. In the middle are the **pending** values awaiting your call. On the right is an **inspector** that explains the value you have selected.
The inspector shows where the value came from and, if it was translated, which language it was translated from. It also opens up the work behind the value: the attributes the agent used as inputs, the agent's own reasoning, and the exact prompt that produced the result. A reviewer is never left guessing why the AI wrote what it wrote. From here you can edit a value before approving it, approve everything still pending on the product at once, and step through products with Previous and Next.
## Jobs, focused on tracking
With decisions moved to Review, the **Jobs** page is now a clean record of what has run. Each row shows the job's status, its progress, whether an automation or a person started it, and when. Open a job and you land in the Review surface scoped to just that run, where decided values stay in place so you can see the full picture of what the job produced. Earlier runs are tucked under **Show older jobs**, and a badge on the sidebar keeps the count of active jobs in view wherever you are.
## Why it matters
Generating content and approving it are different jobs, and they deserve different tools. By separating them, Cernel lets your agents do the heavy lifting while you keep a fast, clear checkpoint before anything ships. You get the scale of AI enrichment and the confidence of having looked at every value that mattered, with the prompt and reasoning right there when you need them.
The full reference walks through running enrichment, the Jobs page, and every part of the Review surface, plus advanced options and troubleshooting.
# Blog
Source: https://docs.cernel.com/blog/overview
Longer-form stories about the bigger Cernel releases: what changed, why we built it, and how to get the most out of it.
The blog is where we go deeper than the changelog. Each post is a longer write-up of a major release or a piece of product thinking, the kind of thing worth reading start to finish. For a running list of every change, big or small, see the [Changelog](/release-notes/changelog).
## Latest posts
**June 28, 2026** · Enrichment now separates running a job from approving its results: track every run on the Jobs page, then approve, edit, or reject each proposed value on the new Review surface, with the prompt and reasoning behind it.
**June 22, 2026** · A ground-up redesign of CSV import and export: column analysis that maps your file for you, catalog and vendor import modes, and reusable export templates.
# AI Agents
Source: https://docs.cernel.com/features/ai-agents
Create reusable AI instructions that generate product content consistently across your entire catalog.
AI Agents are reusable sets of instructions that tell Cernel's AI exactly how to generate content for your products. Set up an agent once (define the prompt, style, and behavior) then assign it to categories in your taxonomy. When you run enrichment, agents generate attribute values for hundreds or thousands of products at once, consistently and on-brand.
## How it works
An AI agent is a configured AI with a specific job: generate product descriptions, extract materials from images, classify products by gender, create meta titles, whatever content your products need.
You build an agent by defining its **prompt** (the instructions the AI follows), selecting the **attribute type** it produces (Text, HTML, Single Select, Multi Select, External Data, or Media), and optionally referencing **Data Sources** for brand guidelines and context. Once created, you link the agent to an attribute on one or more categories in your Cernel Taxonomy. The agent then generates content for every product in those categories when you run enrichment.
The key concept: agents are independent from categories. You create them once and reuse them wherever they're needed. Change an agent's prompt, and every category using that agent picks up the update.
### Why you would use this
Instead of writing separate prompts for every category, create an agent and assign it wherever it applies. One "Product Description" agent can serve your entire catalog.
Agents reference your Data Sources (brand guidelines, tone of voice, product terminology). Every product gets content that sounds like your brand, not generic AI output.
Use different agents for different categories. A footwear description agent knows to mention cushioning and sole type. A clothing description agent focuses on fit and fabric. Same attribute, different expertise.
Update an agent's prompt and re-run enrichment to regenerate content with the new instructions. No need to reconfigure every category. The agent update cascades automatically.
**Key concept: Agent.** A configured AI with specific instructions, called prompts, that generates data for your products. Agents are created once and linked to attributes across categories in your Cernel Taxonomy.
## Planning your agents
Before creating agents, think about what content your products need. A typical setup includes:
* A **product description** agent (Text or HTML) for your main product copy
* A **meta title** and **meta description** agent (Text) for SEO
* A **materials** or **features** agent (Multi Select) for structured attributes
* Specialized agents for specific product types (e.g., technical specs for electronics)
Each agent handles one attribute type and can be reused across many categories. Start with your most important content types and expand from there.
## Creating an agent
In the sidebar, click **Agents** under the **Tools** section. You'll see your agents grouped by attribute type, with each agent showing its name and creation date.
Click **Create Agent** to open the agent creation wizard. The wizard walks you through each configuration step.
Choose what type of content this agent will generate:
* **Text**: Plain text like product descriptions and meta titles
* **HTML**: Rich formatted content with HTML markup
* **Single Select**: Choose one value from a list (e.g., Gender: Male / Female / Unisex)
* **Multi Select**: Choose multiple values from a list (e.g., Materials: Cotton, Polyester)
* **External Data**: Data fetched from an external source (e.g., GTIN matching)
* **Media**: Image content generated or sourced by AI
* **Picker** (Preview): Instead of generating a value, it *selects* the best one, or several, from a set of candidates. See [Picker agent](#picker-agent) below.
You have two ways to write your prompt. You can describe what you want in plain language and let Cernel's AI generate a complete prompt for you, or you can write the prompt yourself from scratch.
**Option A: Describe your intent (recommended)**
Type a short description of what the agent should do, for example: "Write a 150-word product description that's professional but approachable, focusing on materials and fit." Cernel's AI analyzes your intent and generates a full, optimized prompt with the right structure, references, and instructions.
Under the description box, **Select agent type (optional)** lets you pin the type of content the agent generates, Text, HTML, Single Select, Multi Select, External Data, or Media, before you generate the prompt. Leave it untouched and Cernel detects the right type from your description; pick a type to lock it in when you already know what you want (for example, choosing **Single Select** for a gender classifier so it isn't mistaken for a text field).
Pin the agent type when your description could read more than one way. "Tag the season" might generate as free text, but selecting **Single Select** (or **Multi Select**) guarantees the agent returns picks from a fixed list of options.
**Option B: Write your own prompt**
Click **I want to write my own prompt** to open the prompt editor directly. Be specific about:
* **What to generate**: the exact type of content (e.g., "a 150-word product description")
* **Tone and style**: your brand voice (e.g., "professional but approachable")
* **What to include**: specific details the output must cover
* **What to avoid**: content or phrasing to exclude
**Referencing your product's attributes and data**
Whether you wrote the prompt yourself or the AI generated it, type `/` in the prompt editor to reference the product's own attributes and data directly in your instructions. The reference menu lets you insert:
* **Product Data** - product title, images, GTIN, brand, and other product attributes
* **Product Defining Attributes** - the values that make this product a distinct variant, such as its Size or Color, resolved from wherever the variant axis was introduced in the product hierarchy
* **[Data Sources](/features/data-sources)** - entries from your organization's context library (brand voice, product rules, compliance guidelines)
* **Category Attributes** - other attribute values already generated on the same product
Each reference appears as a labeled **pill** inline with your prompt text. When the AI runs, the pill is replaced with the actual content. This keeps your prompts clean and maintainable - store your brand guide once in **Tools > Data Sources** and reference it wherever you need it. Update the Data Source, and every agent using it picks up the change automatically.
The reference picker shows a clickable **breadcrumb trail** at the top of each submenu (for example, `Data Sources > Models > ToV`), so you can jump straight back to a parent level when you've dug too deep. Search inside the picker is space-tolerant: type `Specifications type 1` and it matches entries named `specifications_type_1`.
Start simple. A focused 3-4 sentence prompt often outperforms a lengthy one. You can always add detail after reviewing the initial results.
Before saving, test your agent on real products in the [Agent Sandbox](/features/sandbox). Select up to 10 products (or click **5 Random** to pick a quick sample) and run the sandbox. You'll see the AI-generated output for each product, including the reasoning behind its choices and the source data it used.
If the output isn't quite right, use the **agent chat** on the left side of the screen to tell the AI what to change. For example: "Make the descriptions shorter" or "Don't mention competitor brands." You can reference specific products in the chat using `@` to point out exactly what needs improving. The AI updates your prompt automatically based on your feedback, and the sandbox re-runs on the same products so you can see the change.
Each refinement creates a new version of your prompt. Use the **undo** and **redo** buttons to compare versions and go back if a change didn't improve things. Keep iterating: adjust the prompt through chat, review the new results, and repeat until you're happy. See [Agent Sandbox](/features/sandbox) for the full reference, including @-mentions, the detail drawer, and per-type behavior.
Test with products from different categories and price points. An agent that works well for running shoes might need adjustment for dress shoes. Catching these edge cases in the sandbox saves time later.
Once you're satisfied with the output, save the agent. It's now available to link to attributes on any category in your taxonomy.
You've created an AI agent. Next, link it to an attribute on a category in your Cernel Taxonomy to start generating content for products.
## Linking an agent to a category
Go to your **Catalog** in the sidebar and select the category where you want this agent to generate content.
Find the attribute you want the agent to generate (or create one first, see [Cernel Taxonomy](/features/cernel-taxonomy)). Click the settings icon on the attribute row.
In the attribute configuration panel, select the agent from the dropdown. The agent is now linked and will generate values for this attribute whenever you run enrichment on products in this category.
Each attribute can only have one agent linked at a time. If you select a new agent, it replaces the previous one. You can also unlink an agent to stop it from generating values for that attribute.
The agent is linked. Products in this category (and all subcategories) will use this agent when you run enrichment.
## Running enrichment
From the product table, select the products you want to generate content for. You can select individual products or use bulk selection to pick all products in a category.
Click **Enrich Products**. The enrichment modal shows the available attributes (those with linked agents) and how many products will be processed. Select the attributes you want to generate and click **Start Enrichment**.
Enrichment runs as a background job. You can track progress from the **Dashboard**, which shows active jobs with their status: Pending, Running, Completed, or Failed.
Once the job completes, review the AI-generated content. Each product shows the generated values alongside the original data. You can approve, edit, or reject each result before it gets pushed to your connected integrations.
You've successfully run enrichment and reviewed the results. Approved content is ready to sync to your connected integrations like Shopify.
## Advanced configuration
The Prompt Template Library gives you pre-built agents for common content types. Each template includes a tested prompt, the right attribute type, and configuration that's ready to use.
To use a template:
1. On the **Agents** page, click **Create Agent** to open the agent creation wizard
2. During the creation flow, you can choose from pre-built templates for common attribute types (Text, HTML, Single Select, Multi Select, External Data, Media)
3. Click a template card to preview it - the wizard opens with all fields pre-filled
4. Give the agent a name, review the pre-filled prompt, and save
Templates are starting points, not final configurations. After creating the agent, edit the prompt to add your brand voice, reference your [Data Sources](/features/data-sources), and adjust the instructions for your specific products.
**Recommended workflow for new users:**
1. Connect your product source ([Shopify](/get-started/connecting-shopify), CSV, Feed, or API)
2. Apply AI recommendations from the Dashboard
3. Create agents from templates for each recommended attribute
4. Test on 5-10 products and review quality
5. Customize prompts - add your brand voice via [Data Sources](/features/data-sources)
6. Scale up - enrich your full catalog or set up [Automations](/features/automations)
When reviewing generated content, you can view the **Agent Reasoning**, which is a breakdown of how the AI arrived at its output. This is helpful for understanding why the AI chose specific wording or values, and for refining your prompts.
Some agents can depend on the output of other agents. For example, a "Meta Description" agent might reference the output of a "Product Description" agent to create a shorter summary. Configure dependencies in the agent creation wizard under the dependencies step.
When you run enrichment, Cernel processes dependent agents in the correct order automatically.
Advanced users can adjust the AI model configuration for each agent, including parameters that control creativity, length, and consistency of the output. These settings are available in the agent configuration under LLM settings.
By default, when an agent enriches a variant it can draw on values the variant inherits from its parent products, so a variant with no image of its own can still be described from the parent's image. See [When I enrich a variant, does it use the parent product's data?](/features/product-detail#when-i-enrich-a-variant-does-it-use-the-parent-products-data-like-its-images) for how that lookup works.
You can turn this off per agent. In an agent's settings for a category, alongside the product-level options, switch off **Use parent product data**. With it off, that agent enriches each variant from the variant's own values only. Turn it off when your parent products hold placeholder or copied data that would otherwise leak into variant content.
The category, the governing agent settings, and the variant-defining attributes (such as size or colour) are still read through the parent even when this is off. Only inherited attribute *values* are withheld. If the agent needs an attribute that only the parent holds, enrichment fails for that variant, and Cernel warns you of this when you switch the setting off.
External Data agents that search the web for **text data** (specifications, descriptions, materials sourced from manufacturer sites) have two modes. You pick the mode in the search configuration step when you build the agent.
**Classic mode.** You define exactly which search queries to run and which sites Cernel pulls results from. Cernel searches those sources, then extracts and combines the results following your prompt. Best when you already know the canonical sources for a product type (e.g., a single supplier portal or a fixed list of vendor pages) and want predictable, repeatable searches.
**Agentic mode.** Cernel plans and runs the searches for you, one product at a time, based on the product's own details. You don't write search queries, the agent reads the product and decides what to look up. You still control which domains are in scope through two lists in **Website Filtering**:
* **Block these domains**: results from these domains are excluded
* **Restrict to these domains**: when non-empty, only these domains are considered
Enter domains without the `http://` or `https://` prefix. Write `example.com`, not `https://example.com/`. An entry that includes the protocol prefix never matches any result: a blocked domain won't be excluded, and a restricted list won't return any results.
Use Agentic mode when products vary too much for one query template to cover them. For example, sourcing technical specs across thousands of SKUs from manufacturers you don't enumerate up front.
**Product Matching** appears in both modes. It tells the agent which web result actually belongs to the product in front of it. You can:
* **Match by \[identifier]**: pick a product identifier such as SKU, GTIN, or EAN. The agent requires that identifier to appear in the result to count as a match. Highest accuracy when you have identifiers in your catalog.
* **Match by Broad search**: match on the product's title and details instead. More flexible, but more likely to surface inaccurate results.
* **Custom match criteria (optional)**: add extra words or codes a result must contain. Leave blank to match on the title automatically.
**What to Extract** (the prompt at the bottom of the search step) tells the AI what to pull out of the matched results and how to present it. Type `/` to insert references to product data, Data Sources, or other attribute values, exactly like the prompt step for a Text agent.
Try Agentic mode first when your products are highly varied or when you don't have a fixed list of vendor sites. Switch to Classic when you have a small, known set of sources and want full control over the queries.
Create an External Data agent in **image mode** to search the web for product images, extract them from pages, and return a curated list. Image mode uses the same Classic configuration described above for text, you define the search queries and extraction prompt yourself. (Agentic mode is for text data only.)
The pipeline has three stages:
1. **Search:** The agent runs web searches using queries you define (e.g., product name + brand + "product photo")
2. **Extract:** Cernel visits the search result pages and extracts images, guided by your extraction prompt
3. **Output:** A deduplicated list of images is returned as the attribute value, ready for review
To set it up:
1. Create an agent with **External Data** as the attribute type, then switch to **Image** mode
2. Define search queries that reference product data (e.g., `{product_name} {brand} product photo`)
3. Write an extraction prompt that tells the AI what images to look for (e.g., "Extract high-resolution product photos, ignore thumbnails and navigation images")
4. Link the agent to an External Data attribute on your taxonomy and run enrichment
**Chaining with Media agents:** Once you have web-sourced images, pass them to a Media agent that selects the best image, generates variations, or creates styled photography. Set up the dependency in the Media agent's configuration so it references the External Data attribute's output. Cernel processes agents in the correct order automatically.
Be specific in search queries - include brand name, product type, and image style (e.g., "on model", "flat lay"). Use the extraction prompt to filter noise like navigation icons, banners, and ads.
Media agents that generate images have extra settings in the **Advanced Settings** tab of the agent wizard. They control both how the image looks and the metadata Cernel attaches to it.
**Image output**
* **Aspect Ratio**: the shape of the generated image (for example, `9:16` for a tall product shot).
* **Resolution**: the output image quality. Leave it on **Default** to use the model's native output.
* **File Format**: the output file type: **Default (model output)**, **PNG**, **JPEG**, or **WebP**.
**Alt Text Instructions**
Tell the AI how to write each image's alt text, the short description used for accessibility and SEO. For example: *"Describe the product, its color, and the setting in one sentence."* Leave the field empty to use Cernel's default alt text.
**File Name Instructions**
Tell the AI how to name the generated image file. For example: *"Use the product name and color, separated by hyphens."* Descriptive file names help with image SEO and keep your media library organized. Leave the field empty to use Cernel's default naming.
Both instruction fields work like the main prompt editor: type `/` to insert references to product data, [Data Sources](/features/data-sources), or other attribute values, so the alt text and file name can pull in details like the product title or color automatically.
Keep alt text instructions to a single, factual sentence. Search engines and screen readers both favor concise, descriptive alt text over keyword-stuffed phrases.
**Preview feature.** Background recoloring is in early access. Behavior may change, so review the results before relying on them for production imagery.
Media agents that generate images can replace the background of every image they produce with a single, exact color. This is ideal for product and studio photos that need a clean, consistent backdrop, for example, when every image tile on a product page has to look identical. Lifestyle photos with real surroundings won't look natural against a solid background, so leave recoloring off for those.
To turn it on, open the Media agent, go to the **Advanced Settings** tab, and switch on **Recolor background**. Three controls appear:
* **Background color**: the solid color the background becomes, entered as a hex value (for example, `#FFFFFF`).
* **Mode**: how Cernel treats shadows behind the product:
* **Replace background**: best for product shots; removes shadows as well.
* **Preserve shadows**: best for studio shots of models; keeps the natural shadows.
* **Hybrid (clean background, keep shadows)**: keeps only the clearest shadows near the product or model and recolors everything else to your exact color. Choose it when the background must match a precise color but you still want some depth.
* **Processing engine**: how firmly Cernel trims the edges around the subject:
* **Standard (recommended)**: keeps the most natural edges; the right choice for most images.
* **Alternative**: trims edges more firmly. Pick this if you notice a faint halo around the product or model, though it can give harder edges around fine details like hair.
In **Settings > Global Prompts**, you can configure system-level prompt instructions that apply to all agents. Use this for organization-wide rules like "never use superlatives" or "always mention sustainability" that should apply regardless of the specific agent.
Each agent has a **Languages** tab with one instruction box per enabled language, so you can give a single agent language-specific guidance without changing your organization-wide language settings. A toggle keeps or replaces the organization's language instructions for that agent. See [Give an agent its own language instructions](/features/languages#give-an-agent-its-own-language-instructions) for the full walkthrough.
Re-running enrichment on products that already have approved values will generate new values. The previous approved content will be overwritten if you approve the new results. Review carefully before approving regenerated content.
## Picker agent
**Preview feature.** The Picker agent is in early access, and its behavior may change before it's generally available.
Most agents *generate* a new value for an attribute. A **Picker** agent does something different: it **selects** the best value, or values, from a set of candidates. Think of choosing the single cleanest packshot, the strongest tagline, or the top few options from a longer list. Reach for it when the right answer already exists among several choices and you want the AI to pick rather than write.
### How a Picker agent works
A Picker runs as a **two-phase pipeline**: first it gathers candidates, then it picks from them.
**Phase 1: Find candidates.** A **search prompt** lists the candidates to choose from. Reference product data with `{{placeholders}}` such as `{{images}}` or `{{title}}` (for example, *"List all available product images: "*). By default, candidates are read straight from the prompt. You can optionally widen the net with **Data access**:
* **Products**: let the agent search your product catalog (useful for "shop-a-look" or look-alike picks). Pin a category and filters to focus the search.
* **Data Sources**: let the agent browse your organization's reusable content to source candidates.
**Phase 2: Select.** The **Strategy** controls how the agent picks from the candidates:
* **AI ranks them**: a second AI pass scores the candidates against a **Rubric** you write (for example, *"Pick the cleanest, frontal packshot with a plain background."*). A rubric is required for this strategy.
* **Random pick**: skip the AI and choose at random. It's fast, free, and reproducible: set a **Seed** and the same candidates always produce the same pick (handy for tests). Leave the seed blank for a fresh pick each run.
### Output
In the **Output** section, choose what the agent produces:
* **Values**: whether the agent selects a **Single value** or **Multiple values**.
* **What it picks**: whether the candidates are **Images** or **Text**.
Candidates are sampled without replacement, so the same value is never picked twice.
For **Multiple values**, a **How many?** control sets how the count is enforced. It decides both how many values the agent keeps and whether a thin set of candidates passes or fails the enrichment:
* **All that fit**: every candidate the agent finds is kept, in alphabetical order. No selection step runs.
* **At most N**: the agent keeps up to N values, fewer when only some candidates fit, and none (saving no value) when none of them do. Choose this when a partial result is still useful.
* **At least N**: the agent must find at least N values. If it finds fewer, nothing is saved and the agent reports an error.
* **Exactly N**: the agent must find exactly N values. If it finds fewer, nothing is saved and the agent reports an error.
* **Between N and M**: the agent keeps between N and M values. If it finds fewer than N, nothing is saved and the agent reports an error.
So **At most** and **All that fit** never fail on a thin candidate set: they save whatever fits, down to no value at all. **At least**, **Exactly**, and **Between** enforce a floor and fail the run loudly when the agent cannot reach it. The step heading and config summary reflect your choice, for example *Up to 3* or *Exactly 3*.
### What a text Picker outputs
When a Picker outputs **Text** and has **Products** data access turned on, it picks whole products from your catalog, so you can choose what each pick actually carries. An **Each pick outputs** setting appears with three options:
* **Product title** (the default): every pick is the title of the product the agent chose.
* **An attribute**: every pick is the chosen attribute's value on the product the agent picked. Pick the attribute with the selector that appears. Products without a value for that attribute are skipped.
* **What the prompt asks for**: the agent reads your search prompt to decide what to output, for example *"pick a product's material"*. It falls back to the title when the prompt names nothing.
An **Image** Picker always outputs the image, so this setting applies to text output only.
### Creating a Picker agent
Start a new agent (see [Creating an agent](#creating-an-agent)) and select the **Picker** type. Cernel opens the **Configure Picker** step.
Choose **Single value** or **Multiple values**, and whether the candidates are **Images** or **Text**. For multiple values, set **How many?** (All that fit, At most, At least, Exactly, or Between) to control how many values are kept and whether a thin candidate set fails the run. See [Output](#output).
Write the **search prompt** that lists the candidates, referencing product data with `{{placeholders}}`. Turn on **Data access** to Products or Data Sources if you want the agent to look beyond the prompt.
For a **Text** Picker with **Products** access, set **Each pick outputs** to control what each pick carries: the product title, a named attribute, or whatever the search prompt asks for. See [What a text Picker outputs](#what-a-text-picker-outputs).
Pick a **Strategy**. For **AI ranks them**, write a **Rubric** describing what makes a good pick. For **Random pick**, optionally set a **Seed** for reproducible results.
Save the agent and link it to an attribute on a category, just like any other agent.
Try a Picker in the [agent sandbox](/features/sandbox) before linking it to a category, so you can see which candidate it selects and refine your rubric.
## Frequently asked questions
Just edit the agent. Go to **Agents**, find the agent, and update its prompt. Because the agent is linked to categories (not copied), every category using that agent will use the updated prompt the next time you run enrichment. You don't need to update each category separately.
Check three things:
1. **Your agent prompt**: make sure it includes specific style and tone instructions, not just what to generate. Open the agent, run the sandbox, and use the agent chat to tell the AI exactly what to adjust.
2. **Data Sources**: reference a Data Source containing your brand guidelines in the prompt. Type `/` in the prompt editor to insert one.
3. **Global Prompts**: check **Settings > Global Prompts** for any system-level instructions that might conflict with your agent's style.
Use the sandbox to test changes on a few products before running enrichment on your full catalog.
A Picker's **How many?** setting controls this. **At least**, **Exactly**, and **Between** enforce a floor: if the agent finds fewer values than you asked for, nothing is saved and the run reports an error. Switch to **At most** or **All that fit** when a partial result is still useful. Those keep however many candidates fit, down to none (which saves no value), instead of failing the enrichment. See [Output](/features/ai-agents#output).
No. Each agent is configured for a specific attribute type (Text, HTML, Single Select, Picker, etc.). If you need similar content in different formats, create separate agents (one for Text and one for HTML, for example) with similar prompts.
Not directly, but you can create a new agent and apply the same template, then modify the prompt. For complex agents, note your prompt configuration before creating the new one.
Cernel warns you before deleting an agent that's in use. If you proceed, the agent is unlinked from all categories. The attributes remain, but they no longer have an agent generating values. Previously generated content is not deleted.
Yes. Open the Media agent, go to the **Advanced Settings** tab, and fill in **Alt Text Instructions** and **File Name Instructions**. These tell the AI how to describe and name each generated image. You can reference product data (like the title or color) by typing `/` in either field. Leave a field empty to use Cernel's default. See [Media agents: image output, alt text, and file names](/features/ai-agents#advanced-configuration).
You can enrich an entire category at once, regardless of size. Cernel processes enrichment as background jobs, so large batches run without blocking the rest of the platform. You can monitor progress from the Dashboard.
Yes. By default, enrichment results go through a review step. You can enable **Approve Before Push** in **Settings > Platform** to require explicit approval before any content syncs to your connected integrations. This gives you full control over what gets published.
## What's next
Set up your category structure and link agents to attributes so you can run enrichment.
Connect your Shopify store to import products and push enriched content back.
# Attributes
Source: https://docs.cernel.com/features/attributes
Configure the data fields that AI generates for your products: types, prompts, values, and how they apply across categories.
Attributes are the data fields that AI fills in for your products: descriptions, meta titles, materials, colors, and more. You configure attributes on categories in your Cernel Taxonomy, link AI agents to them, and Cernel generates the values at scale. Seven attribute types cover everything from plain text to structured selections to images, including a Picker that selects the best value from a set of candidates.
## How it works
Each attribute defines a specific piece of product data that you want AI to generate. You create an attribute on a category, choose its type, and link an AI agent that knows how to produce that content. When you run enrichment, the agent generates values for every product in that category.
Attributes set at a parent category automatically apply to all subcategories beneath it. Add "Meta Description" to *Apparel* and every subcategory (*Shoes*, *Tops*, *Accessories*) gets it too. You can also add specialized attributes further down the tree that only apply to specific product types.
### Why you would use this
Instead of deciding case-by-case what content each product should have, configure it once at the category level. Every product in that category automatically has the right fields.
Use Text for meta titles, HTML for rich descriptions, Single Select for gender classification, Multi Select for materials. Each type has specialized configuration for accurate AI output.
## The seven attribute types
Plain text content without formatting. Best for short-to-medium content like product descriptions, meta titles, meta descriptions, and search keywords.
**Configuration:** Prompt instructions, model behavior (Precise / Balanced / Creative), and optional agent dependencies on other attributes.
Rich formatted content with HTML markup, including headings, paragraphs, lists, and bold text. Best for long-form descriptions, size guides, and care instructions that need visual structure.
**Configuration:** Prompt instructions plus **Build Output Template**, which lets you define the exact block structure (headings, paragraphs, lists) the AI should produce, with per-block instructions.
One value chosen from a predefined list of classification options. Best for classifications like Gender (Male / Female / Unisex), Season (Spring / Summer / Autumn / Winter), or Age Group (Adult / Kids).
**Configuration:** Define the classification options, write prompt instructions, and optionally turn on **Force classification** so the AI always picks an option even when evidence is limited (rather than leaving the field empty).
Multiple values chosen from a predefined list of classification options. Best for attributes where products can carry several values, like Materials (Cotton, Polyester, Elastane) or Features (Waterproof, Breathable, Lightweight).
**Configuration:** Define the classification options, write prompt instructions, and optionally turn on **Force classification**. Classification options can be auto-translated into your enabled languages.
Data the agent finds on the web, rather than generated purely from the product's existing fields. External Data operates in one of two modes, chosen in the agent wizard under **What should the agent find?**:
* **Text data**: The agent searches the web (Google and/or AI Search) using queries you define, then extracts textual data such as GTINs, supplier specifications, ingredients, or any other attribute you can describe. Use this when your products don't carry the data natively and you want Cernel to source it.
* **Product images**: The agent uses the same search infrastructure, but targets product imagery. It follows search results and extracts relevant photos, returning a deduplicated list of images ready to review. Use this when you're missing imagery for products and want Cernel to find real photos from the web.
**Configuration:** Search sources (Google queries, AI Search prompt), optional site filtering (exclude or allow specific domains), and product matching criteria (GTIN, SKU, EAN, etc.) so results are tied to the right product. See [AI Agents](/features/ai-agents) for the full set-up walkthrough.
Image content generated or sourced by AI. Best for product lifestyle images, styled photography, or any visual content you'd otherwise need a photographer for.
**Configuration:** Prompt instructions describing the shot, plus image settings like aspect ratio, resolution, and file format. Preview and iterate on results in the agent sandbox before you save.
One or more values selected from a set of candidates, rather than generated. Best when the right answer already exists among several choices: the cleanest packshot out of all product images, the strongest tagline, or a few look-alike products from your catalog.
**Configuration:** A search prompt that lists the candidates (optionally with Data access to your Products or Data Sources), a Strategy (**AI ranks them** against a rubric you write, or **Random pick**), and the output: **Single value** or **Multiple values**, how many to pick, and **Image** or **Text** candidates. Picker is an early-access Preview feature. See [Picker agent](/features/ai-agents#picker-agent) for the full set-up walkthrough.
## Adding an attribute to a category
In Cernel, creating an attribute and setting up the AI that fills it in happen in one place: the **Add New Attribute** wizard. You open it from a category's attributes panel, give the attribute a name, and then either create a fresh agent for it or link an existing one. The agent you choose determines the attribute's type (Text, HTML, Single Select, Multi Select, External Data, Media, or Picker), so you don't have to pick a type up front.
In the sidebar under **Catalog**, expand the taxonomy tree and click the category where you want to add the attribute. The attribute will apply here and, automatically, to every subcategory beneath it.
View the attributes for the selected category. You'll see any attributes already configured, both those defined directly on this category and those flowing down from a parent. Click **Add Attribute** to open the wizard.
In the first step, give the attribute a clear, descriptive name, like *Meta Description* or *Materials*. This name appears as a column in the product table and as an option in the enrichment modal.
Name attributes by what the content *is*, not how it's used. "Meta Description" is clearer than "SEO Text", and "Materials" is clearer than "Tag 2". Consistent naming makes the product table easier to scan.
In the next step, pick how this attribute should be generated:
* **Create new agent**: Build an agent specifically for this attribute. The wizard continues into the full agent creation flow, where you choose the attribute type (via a template or directly), describe what you want the AI to do, configure the prompt, and test it in a sandbox on real products.
* **Use existing agent**: Reuse an agent you've already built (for example, a product description agent you use across several categories). The attribute takes on that agent's type automatically.
If you're not ready to hook up an agent yet, tick **Create attribute only, skip agent setup** in the first step to add the attribute as a placeholder and link an agent later.
See [AI Agents](/features/ai-agents) for the full agent creation walkthrough, including writing prompts, referencing Data Sources, setting agent dependencies, and using the sandbox to iterate.
Before the wizard finishes, the sandbox runs your agent on real products so you can verify the output. Use the agent chat to adjust the prompt, run it again, and step through versions with undo and redo until you're happy.
When you save, the attribute is created on the category and the agent is linked to it. The attribute now applies to this category and all its subcategories, and it's ready for enrichment.
Attribute and agent are set up together. Run enrichment on products in this category to generate values.
## Advanced configuration
When you add an attribute to a category, it automatically applies to all subcategories beneath it:
* An attribute on *Apparel* is available on *Shoes*, *Tops*, *Accessories*, and every category below them
* A more specialized attribute on *Running Shoes* only affects *Running Shoes* and its children; siblings like *Casual Shoes* are unaffected
Place broadly useful attributes (Meta Title, Meta Description) high in the tree, and reserve deeper categories for specialized ones (Cushioning Type, Drop Height).
If a subcategory needs slightly different output for an attribute that's already set at a parent (for example, a more technical description for *Running Shoes* than for *Shoes* overall), link a different agent to the same attribute on the subcategory. The subcategory's agent takes precedence for products there, while the rest of the tree continues to use the parent's agent.
This is how specialization works in Cernel: you don't override fields inside a single attribute configuration. Instead, you choose which agent generates that attribute where it matters.
HTML attributes let you define the exact structure of the generated HTML inside the agent's prompt configuration, using **Build Output Template**. Instead of hoping the AI picks the right format, you specify the blocks it should produce:
* Heading levels (H1, H2, H3)
* Paragraphs and bold text
* Bullet and numbered lists
* Line breaks
Each block can carry its own instructions (for example, "one short opening paragraph" or "three bullets covering fit, material, and care"). The AI follows this template for every product, so formatting stays consistent across the catalog.
Inside the agent wizard, advanced options let you tune how the AI behaves when generating this attribute:
* **Model behavior**: choose between Precise, Balanced, and Creative to trade off consistency against variation
* **Agent dependencies**: mark other attributes as required or optional inputs so one agent can build on another's output (for example, a Meta Description agent that reads the Product Description)
* **Force classification** (Single Select and Multi Select): require the AI to always pick an option even when confidence is low, rather than leave the field empty
These settings are configured on the agent, so they apply wherever that agent is linked.
For External Data attributes, the agent wizard exposes the configuration that drives the web search:
* **Search sources**: up to three Google queries plus an AI Search prompt, each of which can reference product data using `/` (for example, `{product_name} {brand} product photo`)
* **Site filtering**: exclude specific domains or restrict the search to an allow-list
* **Product matching criteria**: identifiers such as GTIN, SKU, or EAN that tie results back to the right product
The same configuration powers both **Text data** and **Product images** modes; only the extraction target changes. See [AI Agents](/features/ai-agents) for the end-to-end setup.
Each attribute can be mapped to fields in your connected integrations. In the **Integrations** section of the configuration modal, you can:
* View existing import and export mappings
* Add new mappings to Shopify fields or metafields
* Configure bidirectional sync behavior
This determines how enriched values flow back to your store.
For Single Select and Multi Select attributes, the allowed options can be translated into your enabled languages. Cernel shows translation status for each option and warns if any are missing. You can auto-translate options or enter translations manually.
Removing an attribute from a category also removes it from all subcategories beneath it. Previously generated values for products in those categories will be lost.
## Frequently asked questions
**Text** produces plain, unformatted content, ideal for meta titles, short descriptions, and fields where HTML isn't supported. **HTML** produces structured content with headings, paragraphs, and lists, ideal for long-form descriptions, product pages, and any field that renders HTML.
Use **Build Output Template** on HTML attributes to control the exact structure of the output, block by block.
The most common cause is that the attribute has no AI agent linked. This happens when an attribute was created with **Create attribute only, skip agent setup** and not revisited. Open the attribute, verify an agent is assigned, and re-run enrichment.
Yes. If two categories at the same level both need a "Description" attribute, you can create it on each one. However, if the categories share a parent, it's more efficient to add the attribute to the parent, and it will automatically apply to both.
Each attribute row in a category's attributes list carries a source badge. A **Direct** badge means the attribute is configured on this category. An **Inherited from \[Category Name]** badge means it was set higher up in the taxonomy and is flowing down. Use the inherited badge to know where to go upstream if you want to change the setup for everything beneath.
Yes. On the Dashboard, the **AI Recommendations** widget analyzes your taxonomy and suggests attributes that could improve your product data. You can apply all recommendations at once or review each one individually.
When **Force classification** is on, the AI must always pick one of your classification options, even when evidence is limited. When it's off, the AI can leave a product unclassified if it isn't confident. Turn it on for attributes where every product must have a value (like Gender); leave it off when it's acceptable for some products to stay empty rather than get a guess.
## What's next
Create the agents that generate values for your attributes.
Set up your category structure to organize where attributes apply.
# Automations
Source: https://docs.cernel.com/features/automations
Automatically enrich products as they arrive or change - no manual intervention required.
Automations let you set up rules that automatically enrich products as they're created or updated. Pick a taxonomy and category, choose which attributes to generate, optionally narrow with filters, and Cernel handles the rest. Every product that matches your rule is enriched without anyone lifting a finger.
## How it works
An automation watches for products in a specific taxonomy and category. When a product arrives or changes in a way that matches your conditions, Cernel automatically runs enrichment using the agents linked to the attributes you selected. The results appear as jobs you can review from the Dashboard and on the automation's **Run history** tab.
You configure automations by completing a one-page sentence builder: three lines that read as a single sentence and let you fill in each slot from the same screen.
### Why you would use this
Products get descriptions, meta titles, and structured attributes the moment they arrive or change. No one has to remember to trigger enrichment.
Every product that matches your rules gets the same treatment. No products slip through without content.
**Key concept: the automation sentence.** Each automation reads as one editable sentence: *"New and updated products in **\[taxonomy › category]** will automatically enrich **\[attributes]** narrowed to only products matching **\[filters]**"*. Click any slot to change it; the rest of the sentence updates around your choice.
## Before you begin
To create an automation, you need:
1. **A category with attributes:** the category must have attributes configured with linked AI agents
2. **At least one linked agent:** only attributes with agents appear in the attribute picker
## Creating an automation
Go to **Tools > Automations** in the sidebar. You'll see a list of existing automations, each shown as a compact sentence summary so you can scan the configuration at a glance.
Click **Create automation** to open a blank automation on its own page. Give it a name in the **Unnamed automation** field at the top, then fill in the sentence below.
Click **Pick a taxonomy and category**. A popover opens with a taxonomy selector at the top and an expandable category tree below. Pick a taxonomy, then choose any category in the tree, or pick **Unclassified products** to target products that haven't been classified yet.
Switching taxonomies or categories after you've chosen attributes or filters clears them: attributes and filters are scoped to the category you picked.
Click the **Pick attributes** slot in the second line of the sentence. Choose one or more attributes. Only attributes that have an AI agent linked appear here. Add as many as you need; each one becomes a chip in the sentence, and **+ Another attribute** adds the next.
The picker lists the attributes the category carries itself first, and then, under a **From subcategories** heading, the attributes defined at categories below it. Each subcategory attribute is labelled with the category it comes from, so you can pick attributes for a whole branch (for example every attribute across Clothing › Shoes, Pants, and Tops) from one automation on the parent category. Picking these attributes is safe: at run time each product only gets the attributes that apply to its own category, so a Shoes attribute simply resolves to nothing on a Pants product.
The third sentence line starts as *"All products are included."* To restrict the automation to a subset, click **Narrow down with a filter** and add one or more conditions on attribute values or product properties. Each filter becomes a chip; **+ AND** adds another condition.
Filters are optional. Leave them empty if you want every product in the category to be enriched.
Below the sentence, the **enrichment options** control how each run behaves: product scope, whether values go through Review, whether to fill only missing fields, and per-language generate/translate/skip choices. The defaults work for most automations, so you can skip this and adjust later. See [Enrichment options](#enrichment-options) for what each control does.
Toggle **Active** in the top-right if you want the automation running immediately, then click **Create automation**.
Your automation is created and appears in the Automations list. Matching products will be enriched automatically with the selected attributes.
## Enrichment options
Below the sentence builder, every automation carries the same **enrichment options** as a manual enrichment run, so an automation and a hand-started run behave identically. These options are saved with the automation and applied to every run it triggers.
* **Product Scope**: whether the automation enriches the matched products only, includes their child products, or runs only on the children. Pick **Include child products** or **Only child products** when your enrichment should reach variants beneath the products that match.
* **Review**: when on, generated values are held as *pending* on the [Review surface](/features/jobs-and-enrichment#reviewing-proposed-values) for approval before they go live. When off, values are applied to your products automatically. The starting position follows your organization's approve-before-push setting, and you can override it per automation.
* **Only enrich missing fields**: when on, existing values are left untouched and enrichment runs only for attributes that are currently empty. Use this when you want an automation to backfill new products without overwriting content you have already reviewed or hand-edited.
* **Language Configuration**: for each language, choose whether the AI **generates** content from scratch, **translates** it from another language, or **skips** it. Use **Translate from** to set the source language for a translated language, and **Apply to all** to set the same mode for every language at once.
A language cannot be both a target for enrichment and a translation source for another language at the same time. If you select the same language for both, the page flags the conflict so you can resolve it before saving.
## Managing automations
Click any row in the Automations list to open the automation's detail page. The detail page uses the same sentence builder as creation: edit any slot in place, then click **Save changes**. Toggle **Active** in the top-right to pause or resume without losing the configuration, and use the red **delete** icon to remove an automation permanently.
### List-view actions
You don't have to open the detail page for quick changes. Each row in the Automations list carries two controls:
* **Active toggle**: the switch on the right of each row pauses or resumes the automation in place. A paused automation stops processing products until you switch it back on.
* **Row menu**: opens a short menu whose one action, **Delete**, removes the automation permanently. Deleting from here warns you first, just like the detail page does. The built-in **Cernel Classification Automation** can't be deleted, so it shows no row menu.
To edit an automation's configuration or view its run history, click anywhere else on the row to open its [detail page](#managing-automations).
## Viewing run history
Each automation detail page has a **Run history** tab next to **Overview**. The tab lists the runs that have processed products for this automation:
Each row shows:
* **Status**: Done (green), Running (blue), Pending (yellow), or Failed (red)
* **Products**: How many products the run processed
* **Started**: Relative time the run began
Expand a row to see the individual products processed in that run, with links into the product detail view.
## Multi-taxonomy and Unclassified products
Each automation is scoped to one taxonomy and category. If you have several taxonomies on the same products, create one automation per taxonomy / category combination; they run independently and write into different attribute sets.
You can also pick **Unclassified products** as the category. An Unclassified automation targets products that haven't been classified into the chosen taxonomy yet, and is limited to setting the **classifying attribute** of that taxonomy so the automation can place the product in the right category before any further enrichment runs.
Cernel ships with a built-in **Cernel Classification Automation** that classifies unclassified products into the Cernel Taxonomy. It appears in the Automations list with a **System** badge and can be paused but not edited or deleted.
## Frequently asked questions
Yes. A newly created product, or an existing product that changes (for example through an integration sync), becomes eligible, and the automation enriches it if it matches your conditions. Each automation processes a given product only once, so a product that has already run through an automation is not enriched by it again, even on a later change. To enrich a batch of products on demand, use manual enrichment from the products table instead.
No. Each automation fires on a given product at most once. After it runs on a product, that product is permanently excluded from that same automation, even if the product is later edited or synced again. There is no cooldown that reopens it. A different automation can still process the same product, and you can always re-enrich on demand with manual enrichment from the products table.
Check three things:
1. **Is the automation active?** Paused automations don't process products. Check the **Active** toggle, either the switch on the automation's row in the list or the **Active** switch on its detail page.
2. **Do the conditions match?** If you set filters, products must match them. Open the automation and check the sentence; remove a filter temporarily to test.
3. **Are the attributes still configured?** The selected attributes must have AI agents linked. Check the category's attribute configuration.
Changes take effect for the next products that match. Products currently being processed complete with the previous configuration; products evaluated after you save use the new sentence.
Yes. You can create multiple automations with different attributes and filters for the same category. Each runs independently when its conditions are met. For example:
* **Automation 1:** Cernel Taxonomy › Apparel → Meta Title, Meta Description (basic SEO for everything)
* **Automation 2:** Cernel Taxonomy › Apparel, filtered to *has images* → Product Description, Materials (rich content only where the AI can see the product)
Yes. When you pick attributes, the picker offers the ones the chosen category carries itself and, under a **From subcategories** heading, the ones defined at categories below it, each labelled with the category it comes from. So a single automation on a parent category can cover attributes that differ from leaf to leaf, instead of one automation per leaf. Each product still only gets the attributes that apply to its own category, so an attribute from a sibling branch simply resolves to nothing on products it doesn't apply to.
Open the automation and switch to the **Run history** tab. Failed runs show a red **Failed** badge; expand the row to see which specific products encountered errors and follow the link into the product detail view.
Optional. If you're importing a large batch and don't want each new or updated product to enqueue a job, pause the relevant automations first, complete the import, then resume them and manually enrich the batch on your own schedule.
Yes. Use the **Language Configuration** panel in the automation's [enrichment options](#enrichment-options). Set any language to **Skip** to leave it out, **Generate** to write fresh content for it, or **Translate** to derive it from another language. Only the languages you set to Generate or Translate are enriched by the automation.
It depends on the **Review** toggle in the automation's [enrichment options](#enrichment-options). With Review on, generated values wait on the Review surface for your approval before they go live. With Review off, they're applied to your products automatically. The toggle starts from your organization's approve-before-push setting, and you can override it per automation.
It's a built-in system automation that classifies products into the Cernel Taxonomy when they don't have a Cernel category yet. You can pause it from the list view if you want to take full control of classification, but it can't be edited or deleted.
## What's next
Make sure your agents are configured before setting up automations. Automations use linked agents to generate content.
Manually enrich products that automations don't cover, or kick off a one-off run for a specific batch.
# Cernel Taxonomy
Source: https://docs.cernel.com/features/cernel-taxonomy
Organize your product catalog into a structured category hierarchy that drives AI enrichment.
The Cernel Taxonomy is a hierarchical category structure maintained by Cernel. When you import your products, Cernel automatically classifies each one into the right category, like *Apparel > Shoes > Running Shoes*. You then decide which attributes and AI agents apply at each level of the tree, so every product type gets the right content, generated the right way, without you having to organize the catalog by hand.
## How it works
The Cernel Taxonomy is a hierarchical tree of categories maintained by Cernel. When your products are imported, Cernel automatically classifies each product into the appropriate category in the tree, so your catalog is organized without any manual setup on your side. Each product in Cernel belongs to a category in this tree.
Categories are more than just labels. They determine which attributes exist for a product and which AI agents generate those attribute values. When you add an attribute to a category, say "Meta Description" to *Shoes*, that attribute automatically applies to all subcategories beneath it, like *Running Shoes*, *Casual Shoes*, and *Boots*. You configure once at the right level, and it cascades down.
This means a running shoe automatically gets the same attribute structure as every other shoe, but you can also add attributes specific to *Running Shoes* (like "Cushioning Type") without affecting the rest of the tree.
### Why you would use this
Products of the same type always have the same attributes. No more missing descriptions on some products while others have full detail.
Set up attributes and agents at a parent category and they automatically apply to every subcategory. Change a prompt for "Shoes" and every shoe product in your catalog picks up the update.
**Key concept: Categories and attributes.** Attributes set at a parent category automatically apply to all subcategories. You don't need to configure the same attribute on every individual category. Set it at the right level and it flows down the tree.
## Step-by-step guide
### Viewing your taxonomy
In the left sidebar, look under **Catalog**. Your taxonomy tree is displayed here, showing all categories and their nested subcategories. Click any category to expand it and see its children.
Click on a category name to view the products within it. The main content area shows a product table filtered to that category, with columns for each configured attribute.
### Planning where to place your attributes
The Cernel Taxonomy is already built and your products are already classified into it. Your job is to decide at which level of the tree each attribute belongs, so the attribute applies to exactly the right set of products:
* **Top level** (e.g., *All Products*): Meta Title, Meta Description, since every product needs these
* **Mid level** (e.g., *Apparel*): Materials, Care Instructions, since all clothing needs these
* **Leaf level** (e.g., *Running Shoes*): Cushioning Type, Drop Height, since only this product type needs these
Think in terms of "what content does this product type need?" Place broadly useful attributes high in the tree so they apply to many products at once, and place specialized attributes further down where they only affect the relevant product types.
### Configuring category attributes
With a category selected, click to view its **Category Attributes**. This shows all attributes configured for this category, including those applied from parent categories.
Attributes show a source badge indicating where they come from. If an attribute was set on a parent category, you'll see "Inherited from \[Parent Name]", meaning it was configured higher up in the tree and applies here automatically.
Click **Create Attribute** to create a new attribute for this category. Choose the attribute type, give it a name, and configure its settings.
Available attribute types:
* **Text**: Plain text content (descriptions, meta titles)
* **HTML**: Rich formatted content with HTML markup
* **Single Select**: One value from a predefined list (e.g., Gender)
* **Multi Select**: Multiple values from a predefined list (e.g., Materials)
* **External Data**: Data fetched from an external source
* **Media**: Image content generated or sourced by AI
* **Picker** (Preview): The best value or values selected from a set of candidates (see [Picker agent](/features/ai-agents#picker-agent))
After creating the attribute, link an AI agent to it. The agent defines how AI generates values for this attribute. Click the settings icon on the attribute row and select an agent from your configured agents.
You've configured an attribute on this category. It now applies to all subcategories beneath it, and the linked agent will generate values when you run enrichment on products in these categories.
### Using AI recommendations
The **AI Recommendations** widget on the Dashboard analyzes your taxonomy and suggests attributes that could improve your product data. It shows which categories could benefit and what attributes to add.
You can:
* **Apply all**: add all recommended attributes at once
* **Review individually**: open each recommendation to see what it suggests and decide whether to apply it
Recommendations are based on your product data and category structure. They're a good starting point, especially when setting up a new taxonomy.
## Advanced configuration
When you add an attribute to a category, it automatically applies to all subcategories beneath it. For example, adding "Meta Description" to *Apparel & Accessories* means every subcategory (*Shoes*, *Tops*, *Accessories*, and all their children) will have that attribute.
You can also add attributes at a more specific level. Adding "Cushioning Type" to *Running Shoes* makes that attribute available only for running shoes and any categories nested below it, without affecting *Casual Shoes* or other siblings.
This lets you define common attributes at the top of the tree and specialized attributes further down, keeping your configuration minimal and your product data consistent.
If a parent category has an attribute linked to an agent, subcategories use that same agent by default. However, you can override this by linking a different agent to the same attribute on a subcategory. The subcategory's agent takes precedence for products in that specific category.
This is useful when you need slightly different prompts for different product types, for example a general "Product Description" agent for *Shoes* but a more technical version for *Running Shoes*.
You can enrich all products in a category at once. Select the category, then use the enrichment action to generate attribute values for all products within it. This is more efficient than enriching products one by one.
The enrichment modal lets you choose which attributes to generate and see how many products will be affected.
Removing an attribute from a category also removes it from all subcategories beneath it. Existing generated values for products in those categories will be deleted. Make sure you want to remove the attribute from the entire branch before confirming.
## Frequently asked questions
Yes. You can link different agents to the same attribute on different categories. Each category can have its own agent generating content tailored to that product type.
Attributes set at a parent category automatically apply to all subcategories. Check the source badge on each attribute, which shows which parent category the attribute comes from. You don't need to remove or reconfigure these; they're working as designed.
The taxonomy supports multiple levels of nesting. You can control how many levels of categories are displayed in the sidebar under **Settings > Platform**.
Cernel automatically classifies your products into the Cernel Taxonomy on import, so the taxonomy itself is set up for you. On top of that, Cernel analyzes your categories and suggests which ones could benefit from additional AI-generated attributes. You'll see these suggestions when Cernel scans your categories for improvement opportunities.
The built-in Cernel Taxonomy is the same for every Cernel customer, so its category names are fixed and can't be renamed. A category's name is set when the category is created and isn't editable afterward. For a built-in category you also can't edit its description. What you can adjust is its **Additional Instructions**, the guidance that tells the AI how to sort products into that category's subcategories.
## What's next
Build your own category hierarchies and let AI classify products into them.
Create and configure the AI agents that generate content for your taxonomy's attributes.
Import your Shopify catalog so you have products to classify into your taxonomy.
# Custom Taxonomies
Source: https://docs.cernel.com/features/custom-taxonomies
Build your own category hierarchies and let AI classify your products into them.
Alongside the built-in [Cernel Taxonomy](/features/cernel-taxonomy), you can build your own taxonomies: category hierarchies that match how your business thinks about its catalog. You define the categories and describe them in plain language, then Cernel's AI reads each product and places it into the right category automatically. Test the result on a handful of products before you classify the whole catalog.
## Why build a custom taxonomy
The Cernel Taxonomy is a general-purpose hierarchy that works out of the box. A custom taxonomy is useful when you need categories that are specific to your business: a merchandising structure, a marketplace's required categories, an internal reporting hierarchy, or a partner's classification scheme. You can keep several taxonomies side by side and classify the same products into each one.
Describe each category in plain language. The AI uses your descriptions and instructions to decide which products belong where, so you never sort products by hand.
Try your categories and prompt on a few products in the sandbox, refine the wording, and only classify the full catalog once the results look right.
### Key concepts
* **Taxonomy**: a hierarchy of categories. You can have more than one. The Cernel Taxonomy is a built-in **System taxonomy** whose category descriptions are locked; taxonomies you create are fully editable.
* **Defining attribute**: every taxonomy has one product attribute that stores each product's category in that taxonomy. You name it when you create the taxonomy (for example, `category`). This attribute is a **Taxonomy Classification** agent, which assigns products into the hierarchy automatically.
* **Category**: a node in the tree. Each category has a **Description** (what belongs here) and **Additional Instructions** (how to sort products into its subcategories).
* **Classification**: the AI walks the tree from the top, choosing a subcategory at each level until it reaches the most specific category that fits the product. A taxonomy can also be set up to place a product in [more than one category](#placing-products-in-more-than-one-category).
## Building a taxonomy
Go to **Tools > Taxonomies** in the sidebar. The list shows every taxonomy in your organization with its **Name** and **Defining Attribute**. Each row has an actions menu (the **...** button) for renaming, deleting, or hiding the taxonomy from your own view, and a taxonomy you have hidden carries a **Hidden** badge. Click **Add Taxonomy**.
Give the taxonomy a **Taxonomy Name** (for example, "Product Categories") and a **Defining Attribute Name** (for example, `category`). The defining attribute is the product attribute that will hold each product's category in this taxonomy. If an attribute with that name already exists, Cernel reuses it.
By default, each product is placed in exactly one category in the taxonomy. If you want products to be able to belong to several categories at once, open the options menu (the **...** button) in this dialog and turn on **Allow multiple categories per product**. This is a permanent choice for the taxonomy: it cannot be changed after the taxonomy is created. See [Placing products in more than one category](#placing-products-in-more-than-one-category).
Open the new taxonomy to reach its detail page. Under **Category Structure**, use **Add Category** to create a top-level category and **Add Subcategory** to nest categories beneath it. To create many categories at once, use **Import JSON** and paste an array of categories.
Click any category to open its editor on the right. Each category has two fields:
* **Description**: a general description of the category and the products it contains. The AI uses this to decide which products belong here.
* **Additional Instructions**: guidance on how the AI should sort products from this category into its subcategories (for example, "Classify by primary function first, then by target audience").
Edits save automatically when you click away from a field. The top-level category has only Additional Instructions, since nothing sits above it.
Keep descriptions concrete and product-focused. "Waterproof outerwear such as rain jackets and shell coats" guides the AI far better than "Jackets".
In **Classification Settings**, tune how the AI classifies products into this taxonomy:
* **Classification Prompt**: extra instructions sent to the model for the whole taxonomy. Each category's description and additional instructions should do most of the work; use this prompt only for global rules (for example, "Prefer the most specific category. When in doubt, use the closest parent category.").
* **Automatic Activation Depth**: how many levels deep Cernel automatically activates categories when a product is classified into them. Set it to `0` to disable automatic activation so only the top-level category stays active.
Use **Test Products** to see how your categories and prompt perform before classifying the whole catalog. Search for products or click **5 random** to pick a sample (up to 10), then click **Run**. Cernel classifies each product with your current settings and shows the category it chose, along with the AI's reasoning. Any existing classification is ignored, so you always see a fresh result.
Adjust your category descriptions, additional instructions, or the classification prompt, then **Run again** until the results look right.
Your Classification Settings save automatically when you click away from a field, the same as category edits, so there is no separate Save button. The **Run** button stays disabled until your most recent change is saved, so click out of the field you just edited and it becomes available.
## Classifying products into your taxonomy
Creating a taxonomy does not reclassify your catalog on its own. To populate it, run its classification:
On the **Products** page, run the taxonomy's defining attribute (a **Taxonomy Classification** agent) as an enrichment on the products you want to classify. Cernel walks the tree and assigns each product to the most specific category that fits.
Set up the classification in [Automations](/features/automations) to run on a schedule or when products change, so new products are classified without manual steps.
On the Products page, use the taxonomy selector (**Select taxonomy**) to view your catalog organized by any taxonomy you have built. As products are classified, the matching categories activate (up to your activation depth) and each product's category in that taxonomy is filled in.
Switching your view to a custom taxonomy does not change or remove a product's category in any other taxonomy. Each taxonomy stores its own classification independently, so a product can belong to a category in the Cernel Taxonomy and a different category in your custom taxonomy at the same time.
## Placing products in more than one category
Most taxonomies place each product in a single category. Some catalogs need more: a jacket that is genuinely both waterproof and insulated, or a product a marketplace expects to appear under two departments. For these cases you can set up a taxonomy that assigns each product to more than one category.
This is a per-taxonomy choice you make when you create the taxonomy, by turning on **Allow multiple categories per product** under the options menu in the Create Taxonomy dialog. It is permanent for that taxonomy and cannot be changed later, so leave it off unless you know a product should be able to sit in several categories at once. Because taxonomies are independent, a product can be placed in one category in a single-category taxonomy and in several categories in a multi-category taxonomy at the same time.
### Multicategory Agent Settings
When a taxonomy allows multiple categories, its **Classification Settings** show an extra **Multicategory Agent Settings** section with two controls that shape the result:
* **Max Categories per Product**: the most categories one product can be placed in, from 1 to 5 (3 by default). This is a ceiling, not a target. The AI still assigns fewer categories when only one fits, so raising the limit does not force extra categories onto products.
* **Categories and Their Subcategories Together**: off by default. When on, a product can sit in a category and in one of that category's own subcategories at the same time (for example, both "Shoes" and "Running Shoes"). When off, only the most specific matching category is kept.
### How multiple categories are chosen
Instead of walking straight down to a single category, the AI works level by level. At each branch it keeps every subcategory that genuinely fits the product, not just the single best one, and repeats this until nothing more specific applies. A final pass reviews the full set of proposed categories together and drops any that do not hold up, always keeping at least one. The result is a set of categories that each fit the product, with the AI's reasoning saved alongside, up to your Max Categories per Product limit.
### Editing a product's categories by hand
You can always override the AI. In the category editor for a product's classification in a multi-category taxonomy, tick or untick the categories the product belongs to and save. The editor lets you select one or more categories, so you can add a category the AI missed or remove one that does not belong.
## Advanced configuration
Use **Import JSON** on the Category Structure card to add many categories at once. Paste an array where each entry has an `external_id` (a unique reference within the import) and a `name`. Use `parent_external_id` to nest a category under another entry in the same paste. Entries without a `parent_external_id` are added at the top level.
Categories can be active or inactive. Deactivating a category hides it and its subcategories when you browse products by category, but products already classified in them keep their classification. You must deactivate a category's subcategories before deactivating it. Use the **Show inactive** toggle to reveal inactive categories in the tree. Automatic Activation Depth controls how far down the tree Cernel turns categories on as it classifies products.
If you keep several taxonomies but only work in some of them, you can hide the ones you don't use so they stay out of your way. On **Tools > Taxonomies**, open a taxonomy's actions menu (the **...** button) and choose **Hide**. A hidden taxonomy no longer appears in the taxonomy selector when you browse products by category, and it carries a **Hidden** badge in the Taxonomies list. Choose **Show** from the same menu to bring it back.
Hiding is per person: it changes only your own view, and it never affects anyone else in your organization. It also leaves every category and every product's classification untouched, so nothing is reclassified and nothing is lost. You can hide the built-in Cernel Taxonomy this way too, but you can't hide your last remaining visible taxonomy, since there would be nothing left to browse. Show another one first.
This is different from deactivating a category, which is an organization-wide change to a single category inside one taxonomy. Hiding a taxonomy is a personal view preference that covers the whole taxonomy.
You can keep multiple taxonomies side by side, each with its own defining attribute and classification prompt. Classify the same products into each one by running each taxonomy's classification. This is useful when different teams or channels need the same catalog organized in different ways.
## Frequently asked questions
There is no single switch that makes one taxonomy the only active one. Every taxonomy you create is Active and available at once. To work in a custom taxonomy, run its classification on your products and use the taxonomy selector on the Products page to view your catalog organized by that taxonomy. Each product keeps its category in every taxonomy independently.
The **Description** tells the AI what a category contains, so it can decide which products belong there. **Additional Instructions** tell the AI how to sort products from that category into its subcategories. The **Classification Prompt** is a single set of global rules for the whole taxonomy. Category descriptions and instructions should drive most decisions; keep the classification prompt for organization-wide rules.
No. A new taxonomy starts empty. Products are classified only when you run the taxonomy's classification from the Products page or through an Automation. Existing classifications in other taxonomies are left untouched.
The Cernel Taxonomy is a **System taxonomy**: its category names and descriptions are fixed. You can still adjust each category's Additional Instructions to steer how products are sorted into its subcategories. Full editing of names, descriptions, and structure is available on taxonomies you create.
Go as deep as your products need distinct handling. Deeper trees give more precise categories but take more thought to describe well. The Automatic Activation Depth setting lets you keep deeper levels turned off until you are ready to use them.
Yes, if the taxonomy is set up for it. Turn on **Allow multiple categories per product** when you create the taxonomy, then the AI can place each product in several categories at once, up to the **Max Categories per Product** limit in Classification Settings. Single-category taxonomies, including the built-in Cernel Taxonomy, keep one category per product. See [Placing products in more than one category](#placing-products-in-more-than-one-category).
No. Whether a taxonomy allows multiple categories per product is chosen when the taxonomy is created and cannot be changed afterward. If you need multiple categories for an existing single-category taxonomy, create a new taxonomy with the option turned on and classify your products into it.
Yes. On **Tools > Taxonomies**, open the taxonomy's actions menu (the **...** button) and choose **Hide**. It disappears from the taxonomy selector when you browse products by category and gets a **Hidden** badge in the list. Choose **Show** to bring it back. Hiding changes only your own view, not your teammates', and it leaves every category and classification exactly as it was. You can't hide your last visible taxonomy: show another one first. See [Hiding a taxonomy from your view](#advanced-configuration).
Deleting a taxonomy is permanent. It removes the taxonomy's whole category structure and every product's classification in it, and it cannot be undone. To guard against an accidental click, the confirmation dialog keeps its **Delete** button disabled until you type the taxonomy's name back exactly. Deleting one taxonomy leaves every other taxonomy untouched, so each product keeps its classification in the taxonomies you keep. The built-in Cernel Taxonomy cannot be deleted; you can hide it from your view instead.
You can clear a product's category by hand from the product table, which is useful when a classification landed in the wrong place and you want to start over. Turn on the **Classification** column from the table's Column settings, switch on **Bulk select**, and select the Classification cells for the products you want to reset. Then press **Delete** (or open **Bulk edit values** and choose **Clear**) to empty the category. The products keep all their other values and are simply no longer classified, so you can re-run classification, or set a category by hand, whenever you're ready. See [Moving products to a different category in bulk](/features/jobs-and-enrichment#moving-products-to-a-different-category-in-bulk).
## Related features
Learn how the built-in taxonomy classifies products and how attributes apply across categories.
Configure the agents that generate and classify content for your taxonomies.
Run classification on a schedule so new products are sorted automatically.
Track classification runs and review results on the Jobs page.
# Data Sources
Source: https://docs.cernel.com/features/data-sources
Build a context library of brand guidelines, product rules, and reference material that your AI agents use to generate on-brand content.
Data Sources are your organization's context library. Store brand voice guidelines, product specifications, target audience descriptions, and other reference material in one place, then reference it in your AI agent prompts. This means your agents always have the context they need to generate content that matches your brand - without pasting the same information into every prompt.
## How it works
Data Sources is a file-and-folder system inside Cernel where you organize reusable context. You create folders to group related information (like "Brand Guidelines" or "Product Rules"), then add entries inside them - either text content or images.
When writing an agent prompt, you type `/` to insert a Data Source reference. Cernel injects the referenced content directly into the prompt at generation time. Update a Data Source entry once, and every agent referencing it automatically uses the latest version.
### Why you would use this
Instead of pasting your full brand guide into every agent prompt, store it once and reference it. Your prompts stay focused on instructions, not context.
Change your brand voice? Update the Data Source entry and every agent that references it picks up the change. No need to edit dozens of prompts individually.
**Key concept:** Data Sources are NOT integrations. They are organizational context that enriches AI output quality. They don't import or export product data - they provide the background knowledge your agents need to write well.
## Setting up Data Sources
Go to **Tools > Data Sources** in the sidebar. You'll see an explorer view with a folder tree on the left and a content panel on the right.
Click **New Folder** to organize your data sources. Give the folder a descriptive name like "Brand Guidelines" or "Product Rules". Folders help you group related entries and keep your context library organized.
Folder and entry names determine the display name shown on the pill in the prompt editor. Choose clear, descriptive names.
Select your folder, then click **New Entry**. You can add two types of entries:
* **Text entries** - Paste or type your brand guidelines, product rules, audience descriptions, or any text content. You can also upload plain-text files (`.txt`, `.md`) instead of pasting.
* **Image entries** - Upload reference images like brand logos, style guides, or product photography standards
You can also drag and drop files directly into the upload area. The drop zone lists the formats it accepts: **PNG, JPG, JPEG, GIF, WEBP, SVG, TXT, and MD**. If you drop a file in an unsupported format, Cernel skips it and tells you which formats are accepted, so nothing is silently discarded.
When writing an agent prompt, type `/` to open the reference menu. Select your Data Source entry and it appears as a styled **pill** in the prompt editor: a labeled badge showing the entry's display name.
Your Data Source is ready. Reference it in any agent prompt by typing `/` and selecting it from the autocomplete menu. The pill makes it easy to see which references are included at a glance.
## Organizing your library
A clean folder structure makes Data Sources easy to find and reference. A recommended structure:
```
data-sources/
├── brand/
│ ├── voice → Brand tone and style rules
│ ├── audience → Target customer description
│ └── values → Brand values and mission
├── product-rules/
│ ├── footwear → Footwear-specific content rules
│ ├── apparel → Apparel-specific content rules
│ └── accessories → Accessories-specific content rules
├── compliance/
│ ├── claims → Claims to avoid
│ └── certifications → Required certification language
└── seo/
├── meta-rules → Meta title/description rules
└── keywords → Priority keywords
```
Keep entries focused. One entry per topic is better than one massive entry covering everything. Focused entries let you reference exactly the context each agent needs, no more, no less.
## Writing effective entries
Instead of "write in our brand voice," give concrete instructions:
**Less effective:**
> "Use our brand voice when writing product descriptions."
**More effective:**
> "Tone: Warm and knowledgeable, like a trusted friend who happens to be an expert. Use contractions (we're, you'll). Address the customer directly (you, your). Avoid: superlatives (best, finest), corporate language (leverage, synergy), and exclamation marks."
Examples are more effective than abstract rules:
> "Product description example for running shoes: 'Built for the long run. The CloudStride features responsive foam cushioning that returns energy with every stride, while the breathable mesh upper keeps your feet cool from first mile to last. A reinforced heel counter provides stability without adding weight.'"
## Using Data Sources in prompts
Navigate to any agent or attribute configuration and open the prompt editor.
In the prompt text field, type `/`. An autocomplete menu appears showing your available Data Sources organized by folder. Select the entry you want to insert.
The reference appears as a labeled **pill** inline with your prompt text. When the AI runs, the pill's content is replaced with the actual Data Source entry.
A well-structured prompt with Data Source references might look like:
> Write a 120-150 word product description for this product.
> Follow the tone and style in `Brand Voice`. Write for the audience described in `Brand Audience`.
> Apply the content rules in `Footwear Rules`. Check against `Compliance Claims` before including any claims.
Each of the references above would appear as a pill in the prompt editor, clearly distinguishable from the surrounding instructions.
## Advanced configuration
You can create folders within folders to build a structured hierarchy. For example:
* `brand/` - Brand-level context
* `brand/voice` - Tone of voice guidelines
* `brand/audience` - Target audience description
* `legal/` - Compliance rules
* `legal/claims` - Claims to avoid
Each entry appears as its own labeled pill in the prompt editor, making it easy to see which context is being used.
The `/` autocomplete menu offers several reference categories beyond your custom Data Sources:
* **Product Data** - Reference all product attributes, or drill into specific ones like Product Title, Product Images, GTIN, or ID
* **Product Defining Attributes** - Reference the values that make this product a distinct variant, such as its Size or Color. Cernel resolves these from wherever the variant axis was introduced in the product hierarchy, so a product nested under both a Size and a Color split surfaces both
* **Organization** - Reference organization-level properties like name, language, and site domain
* **Existing Attributes** - Reference other attribute values already generated on the same product
* **Custom Data Sources** - Your own folder/entry references from the Data Sources library
Each reference type inserts a labeled pill in the prompt editor, visually distinct from your instruction text.
Image entries are useful for providing visual references to AI agents - brand logos, style examples, or product photography standards. Upload images in PNG, JPG, GIF, WebP, or SVG format. You can add alt text to describe the image for accessibility and context.
Deleting a Data Source entry or folder will break any agent prompts that reference it. The reference will remain in the prompt text but won't inject any content. Check which prompts use a reference before deleting.
## Frequently asked questions
Common entries include:
* **Brand voice guide** - Tone, vocabulary, and style rules
* **Target audience** - Who you're writing for and what they care about
* **Product guidelines** - Category-specific content rules (materials to highlight, claims to avoid)
* **Compliance rules** - Legal requirements, prohibited claims
* **Competitor information** - Brands or terms to never mention
Click on any entry card in the explorer to open the edit modal. Change the display name, content, or image, then save. All agent prompts referencing this entry will automatically use the updated content the next time enrichment runs.
Yes. Insert as many references as you need. Each `/` insert adds another reference. For example, you might reference both your brand voice and product guidelines in the same agent prompt.
**Data Sources** are context - they provide information for the AI to use (brand guidelines, product rules). **Global Prompts** are instructions - they tell the AI how to behave across all agents (e.g., "never use superlatives"). Use Data Sources for what to know, and Global Prompts for what to do.
The upload area accepts image files (PNG, JPG, JPEG, GIF, WEBP, SVG) and plain-text files (TXT, MD). The accepted list is shown directly in the drop zone. Other formats - such as PDF, Word, or spreadsheet files - aren't supported; if you drop one, Cernel skips it and shows you which formats are accepted. For content in an unsupported format, copy the text into a **Text entry** instead.
## What's next
Create agents that reference your Data Sources to generate on-brand product content.
Run enrichment to generate content using your Data Sources and agents.
# Developer Tools
Source: https://docs.cernel.com/features/developer-tools
Manage API keys and service accounts to integrate Cernel into your own systems.
Developer Tools give you programmatic access to Cernel. Use the API to push products from your own systems and pull enriched content back once it's generated.
## How it works
Under **Settings > Developer > API**, you authenticate requests to the [Public API](/integrations/public-api) with keys, organized into service accounts, one per integration. Push products in, let automations enrich them, then poll the [changes endpoint](/integrations/public-api#getting-enriched-data-back) to pull the results back.
### Why you would use this
Push products from your ERP, PIM, or custom backend into Cernel without manual imports.
Poll the changes endpoint to pull AI-generated content and product updates back into your own systems on your schedule.
## Step-by-step guide
### Managing API keys with service accounts
An API key authenticates requests to the [Public API](/integrations/public-api). Keys are organized into **service accounts**: one account per integration, each holding its own keys. Grouping keys this way lets you see which integration has been calling and switch one off without disturbing the others.
Go to **Settings > Developer > API**. Each service account is listed with the number of keys it holds, when it was created, and when it was last used. Expand an account to see its individual keys.
Click **New service account** and name it after the integration that will use it, for example `Shopify` or `ERP sync`. That name is what shows up on the work its keys do. Creating an account immediately mints its first key.
When a key is created, Cernel shows it once in a **Your new API key** dialog. Copy it and store it somewhere safe. For your security you won't be able to see the full key again, only a masked version.
Store your API key like a password. Anyone with the key can access your organization's data through the API. If a key is ever exposed, revoke it and mint a new one.
Click **New key** on an account to mint another key for it. To roll over to a fresh key without downtime, add the new key, update your integration to use it, then revoke the old one. Revoking a key stops it working immediately while the account and its other keys keep going. A revoked key stays in the list, marked **Revoked**, so a past call still has an explanation.
Renaming and deleting a service account are **admin-only**; minting a key stays open to any member. You can delete an account only once none of its keys are still live, so revoke its keys first.
Click **Visit Documentation** to open the full API reference in a new tab, with every endpoint, request format, and response schema.
Keys created before service accounts existed appear under a **Keys without an account** list at the bottom of the page. There's nothing to do there: the next time such a key is used, it gets an account of its own and moves up to the main list. Revoke any you no longer need.
### Getting enriched content back
Cernel does not push results to your systems. Once automations have enriched your products, poll the [changes endpoint](/integrations/public-api#getting-enriched-data-back) to pull the updates back in chronological order, using the offset it returns to pick up where you left off on the next poll. See [Building a custom product pipeline](/integrations/public-api#building-a-custom-product-pipeline) for the full walkthrough.
## Frequently asked questions
Go to **Settings > Developer > API**, where keys are grouped under service accounts. Cernel shows a key's full value only once, in a dialog right after it's created, so copy it then. Afterwards only a masked version is shown. If you've lost a key, mint a new one on its account and revoke the old one.
Yes. Create a **service account** per integration, and give each account as many keys as you need. Keys are revoked individually, so you can rotate one key or switch off a single integration without affecting the others. This is a change from the earlier model of one key per organization.
Mint a new key on the same service account with **New key**, update your integration to use it, then revoke the old key. Because both keys are live during the switch, nothing stops working in between. Revoking takes effect immediately, so revoke only after the new key is in place.
Poll the [changes endpoint](/integrations/public-api#getting-enriched-data-back) on the Public API. It returns enrichment updates in chronological order, and you use the offset it returns to fetch only what changed since your last poll. There is no push-style webhook delivery, so retrieving results is always a poll from your side.
## What's next
Set up a full API integration for pushing products programmatically.
Auto-enrich products pushed via API with automations.
# Jobs & Review
Source: https://docs.cernel.com/features/jobs-and-enrichment
Track enrichment progress on the Jobs page, then approve, edit, or reject the values your agents propose from the Review surface.
Enrichment in Cernel happens in two steps. First, a **job** runs your AI agents across the products you selected and proposes new attribute values. Then, on the **Review** surface, you approve, edit, or reject those proposed values before they're saved to your products and synced to your integrations. The **Jobs** page tracks the runs; **Review** is where you make the decisions.
## How it works
When you select products and click **Enrich Products**, Cernel creates a job that processes each product with the AI agents linked to your selected attributes. Jobs run in the background, so you can keep working while content generates.
What happens to the generated values depends on the **Review** toggle in the enrichment modal:
* **Review on**: proposed values are held as *pending* and collected on the **Review** surface, where you approve, edit, or reject them before they go live.
* **Review off**: proposed values are applied to your products automatically as soon as they're generated, with no approval step.
The **Jobs** page (sidebar → **Jobs**) tracks every run with progress indicators, plus a search box and filters to find a past run. The Dashboard also surfaces a compact **Recent jobs** widget. The **Review** surface, reached from the **Review** tab on the Products area, or by opening a job from the Jobs page, is where proposed values wait for your decision.
### Why you would use this
Nothing is saved to your products until you approve it. Review proposed values one product at a time, or approve in bulk when you trust the output.
For each value, see the prompt that produced it, the agent's reasoning, the inputs it used, and where any translation came from, so you can decide with confidence.
See at a glance how many jobs are running, how far along they are, and who started them.
Failed and skipped values are surfaced for you to dismiss, so your review queue reflects only what still needs a decision.
## Running enrichment
In the sidebar under **Catalog**, click on a category to view its products. Use the checkboxes to choose which products to enrich, or use the header checkbox to select all visible products.
Click **Enrich Products**. The **Configure Enrichment** modal opens:
1. Optionally give the run a **Title** so it's easy to find later on the Jobs page. Leave it blank and Cernel names the job for you from the attributes and category you picked (for example, *Color from Electronics*)
2. Set the **Product Scope**. It opens on **Include child products**, so a master product and its variants are enriched together, which is what variant-heavy catalogs usually want. Switch it to enrich the selected products only, or to **Only child products**, if you'd rather narrow the run
3. Toggle **Review** on to hold generated values for approval on the [Review surface](#reviewing-proposed-values) before they're saved, or off to apply them automatically. Its starting position follows your organization's approve-before-push setting, and you can override it per run
4. Toggle **Only enrich missing fields** on if you only want to fill in attributes that are currently empty (existing values won't be overwritten). Leave it off to re-enrich all selected attributes
5. Check the **Attributes** you want to generate (only attributes with a linked agent appear here, so use the search box to find specific ones)
6. Under **Language Configuration**, choose what happens for each enabled language: **Generate** the content from scratch, **Translate** it from another language, or **Skip** it. Use **Apply to all** to set every language at once
7. Click **Preview** to see a summary of the run, then **Start Enrichment** to dispatch it
The attribute count shown (e.g., "Available Attributes (5)") only includes attributes that have an AI agent linked. If you're missing an expected attribute, check the category's attribute configuration.
To pick several attributes at once, click the first one, then hold **Shift** and click another: every attribute between the two is selected together. The range follows the list as shown, so if you've typed in the search box it covers just the matching attributes.
Use **Only enrich missing fields** when you've added a new attribute to a large catalog and want to backfill values for products that lack one, without touching anything you've already reviewed or hand-edited.
**Each enrichment run processes up to 50,000 products in a single job.** If you select more than that, only the first 50,000 are enriched in that run, and the rest are left untouched, with no error. To enrich a catalog larger than 50,000 products, split it into runs of 50,000 or fewer (see below).
### Filtering the product list
A category can hold thousands of products, so the toolbar above the product table lets you narrow the list to exactly the set you want before you enrich. Filtering is how you build a batch, focus on products that are still missing a value, or find everything a particular integration populated.
Open **Filter** in the toolbar above the table, then click **Add filter** to build a condition. Each condition reads like a sentence, for example *Where Color has no data*. You can filter on:
* **Product attributes** and **Category attributes**: filter by an attribute's value, using the operators below.
* **Product properties**: built-in fields such as the created date, an identifier (SKU or GTIN), whether the product **Has images**, and which **integration** or CSV import populated its values.
For an attribute condition, pick an operator:
| Operator | Matches products where the attribute |
| - | - |
| Equals / Does not equal | exactly matches, or doesn't match, a value |
| Contains / Does not contain | includes, or doesn't include, the text you enter |
| Has data / Has no data | already has a value, or has none yet |
| Is enriched / Is not enriched | has, or doesn't have, a value that AI enrichment produced |
| Is manually edited | has a value that someone entered or edited by hand |
| Is empty | has an empty value |
| Updated before / Updated after | was last changed before or after a date |
**Is enriched**, **Is not enriched**, and **Is manually edited** filter by where a value came from, not only whether one exists. This matters when a connected integration or CSV import already fills a field you also enrich, such as Description or Product type: **Has data** matches every product because the field is populated either way, while **Is not enriched** isolates the products that still need AI enrichment, and **Is manually edited** finds values a person set by hand.
**Updated before / Updated after** matches any change to the attribute's value, not only ones from AI enrichment. An update pulled in from a connected integration (for example, a product edited in Shopify and synced to Cernel) counts too.
**Has no data** and **Does not contain** are the two you'll reach for most when building enrichment batches. **Has no data** isolates the products that still need a value, and **Does not contain** lets you exclude products whose value already includes a term. When the field is already populated by an integration or import, reach for **Is not enriched** instead of **Has no data** to find the products AI hasn't touched yet.
Add as many conditions as you need and join them with **and** or **or**. Switch between **Simple** and **Advanced** to keep a flat list of conditions or to group them into logic. Use **Clear all filters** to reset the table. When you have a setup you return to often, save it as a view from the **Views** button, covered in [Saving and sharing a view](#saving-and-sharing-a-view).
### Quick filter from a column header
When you only want to narrow one attribute, you don't have to open the filter builder. Open a column's menu from its header in the product table and use the **Quick filter** section to set a condition on just that attribute. It offers the same operators and value editors as the toolbar filter, so you can type a term to search within the column, or pick an operator such as **Has no data** or **Is not enriched**. Press **Enter** or click **Apply** to filter, and **Clear** in the same menu to remove it.
A quick filter and the toolbar filter share one filter state, so anything you set here also appears as a row in the filter builder, and the table URL updates so the narrowed view survives a refresh or a shared link. A filtered column shows a funnel beside its name, giving you an at-a-glance read of which columns are narrowing the list.
A column's quick filter reads and writes that attribute's first condition in the filter list. If you have also filtered the same attribute inside an **Advanced** group, the quick filter narrows the list alongside that group's condition, and clearing the quick filter leaves the group's condition in place. A condition that lives only inside an Advanced group shows no funnel on its column.
### Saving and sharing a view
A view saves the whole product-list setup, its filters, search, sort, and column layout, so you can return to it in one click instead of rebuilding it each time. Views live in your Cernel account rather than in the browser, so a view you save is there when you sign in from another browser or another device, and you can share one with your whole team.
Apply the filters, search, sort, and columns you want the view to remember.
Click **Views** in the toolbar above the table, then **Save view**, and give the view a name.
Pick **Only me** to keep the view in your own list, or **Everyone at \[your organization]** to share it with the whole team. Anyone on the team can apply a shared view, and anyone there can edit it.
Saved views appear under the **Views** button, grouped into **My views** and **Views for organization**. Click a view to apply it, and click it again to turn it off and return the table to its default state. If you change the filters, search, sort, or columns while a view is applied, use **Save changes** to write the update back into the view, or **Save view** to keep the new setup as a separate one. The **Review** surface has its own saved views that work the same way.
### Enriching a large catalog in batches
A single run now covers up to 50,000 products, so most catalogs enrich in one go. When you have more than 50,000 products to enrich, work through them in batches and let each batch finish before starting the next:
In the enrichment modal, enable **Only enrich missing fields**. Each run then targets only products that still lack a value for the selected attributes, so finished products drop out of the next batch automatically.
Use the [product filters](#filtering-the-product-list) to narrow the selection to 50,000 products or fewer. For example, add a **Has no data** condition on the target attribute to show only products that still need a value.
Start the enrichment and wait for the job to complete on the **Jobs** page before starting the next batch. Running back-to-back filtered batches in parallel can overlap on the same products.
Re-apply the **Has no data** filter for products that still lack a value and run again. Repeat until no products remain. Track progress on the Jobs page and by filtering the attribute for products with no data.
## Editing values in bulk
Sometimes you need to change many values by hand rather than enrich them: fixing the same wrong value across a batch of products, clearing a field before a re-run, or setting a shared value that no agent produces. **Bulk select** turns the product table into a grid you can select across, so you can set, clear, delete, or enrich a whole block of values at once.
### Selecting the values to change
Click **Bulk select** in the toolbar above the table to turn on selection mode. You can then pick values in a few ways:
* **A single value**: click its cell.
* **A whole product**: tick the product's row to take all of its values.
* **A block**: drag across cells, or click one cell and hold **Shift** while clicking another to extend the range. Hold the add/remove key (**Cmd** on Mac, **Ctrl** on Windows) to add or remove cells without clearing the rest.
A bar at the bottom of the table keeps a running count of what you've picked, for example *3 values, 1 attribute, 3 products*, and lists the keyboard shortcut for each action. Press **V** to turn selection mode on and off, and **Esc** when you're done.
### Setting or clearing values by hand
With a selection in place, click **Bulk edit values** to open the editor. The attributes you selected are listed on the left; pick one to edit. For that attribute, and for each enabled language, choose what to do:
* **Set value**: type the value that every selected product should get. The field opens on the value the selection already shares, so you can see what you're about to replace before you change it. When the selected products hold different values, or the selection reaches past the rows currently loaded, the field stays blank and tells you why, rather than showing one product's value as if the whole selection held it. The starting value is shown, not staged: **Apply** still counts only the fields you actually change.
* **Clear**: remove the existing value from the selected products. An attribute that must always have a value can't be cleared.
* **Leave as is**: skip the field, so nothing is written for it.
Click **Apply to \[n] values** to write your changes. Because this overwrites the selected products and can't be undone from the dialog, Cernel first asks you to confirm, showing exactly how many values and products it will change. Turn on **Send for review** to propose the edits on the [Review surface](#reviewing-proposed-values) instead, so they wait for approval before they're saved.
A single bulk edit covers up to a set number of values. If your selection is larger, Cernel updates the first batch and tells you how many values were left unchanged, so you can narrow the selection, or run the edit again, to finish the rest.
Variant-defining attributes (such as the size or colour that distinguishes a variant) are owned by the parent product and locked on its variants, so they aren't yours to set on a variant here. Edit those on the parent instead. See [Why can't I edit a value? It says the attribute defines the variant](/features/product-detail#why-cant-i-edit-a-value-it-says-the-attribute-defines-the-variant).
### Deleting values
To empty the selected values without opening the editor, click **Delete** on the selection bar, or press **Del** (**Backspace** also works). This clears the value on every selected product, across every enabled language, the same as choosing **Clear** for each language in the bulk editor. Because it can't be undone, Cernel asks you to confirm, showing how many values it will delete. A value deleted by hand shows as a genuinely blank cell, not the muted **No value** marker that an agent leaves when it looked and found nothing.
### Enriching a selection
To generate the selected values with AI instead of typing them, press **E**, or click **Enrich Products** in the toolbar while a selection is active. This uses the same agents as a full enrichment run. Enrich needs a rectangular selection, meaning the same products picked in every selected attribute, so if your selection is ragged, drag a block rather than picking single cells.
Bulk select is also available on the [Review surface](#reviewing-proposed-values), where you can edit or decide many proposed values together before they're saved. See [Deciding in bulk](#advanced-configuration).
### Moving products to a different category in bulk
A product's category is stored as its **Classification** value, the same value the AI sets when it sorts products into your taxonomy. You can change it for many products at once from the product table, instead of writing a per-product prompt or re-running classification.
Open **Column settings** in the toolbar above the table and turn on **Taxonomy Classification**. This column is hidden by default, because the category tree in the sidebar already shows where products sit, so you switch it on only when you want to edit categories directly in the table.
Turn on **Bulk select**, then pick the Classification cells you want to change. Tick a product's row to take its Classification along with its other values, or select the Classification cells across a block of rows.
Click **Bulk edit values**, choose the Classification attribute, and pick the target category from the taxonomy tree. Every selected product moves to that category when you apply the change.
The same confirmation and limits as any other bulk edit apply: Cernel shows how many products it will move before writing, and you can turn on **Send for review** to have the change wait as a proposed value on the [Review surface](#reviewing-proposed-values) instead of applying it straight away.
## The Jobs page
Open the **Jobs** page from the sidebar to see a table of your jobs, newest first.
Each row in the table shows:
* **Name**: the job's title (the one you set, or the one Cernel generated from the attributes and category), or its ID if untitled
* **Status**: a colored badge: **Pending**, **Running**, **Success**, **Failed**, or **Cancelled**
* **Progress**: how many elements are done out of the total (for example, `42 / 100`)
* **Trigger**: how it was started, by an **Automation** or run **manually**
* **Created by**: the teammate who started the job
* **Created**: when the job started
* **Actions**: [rename the job](#renaming-a-job) at any time, and [cancel the job](#cancelling-a-job) while it's still running
Click any row to open that job's proposed values on the [Review surface](#reviewing-proposed-values), already scoped to the job. The Jobs page itself is for tracking. All approve, edit, and reject actions happen on Review.
A job-status indicator sits in the app header and stays visible while you're signed in, so you can keep an eye on active work from anywhere in the app. It spins while jobs are running and shows a count of active jobs. Click it to open the **Running jobs** list, jump straight to a job, or choose **View all jobs** to go to the Jobs page.
### Finding a job
A search box and a row of filters sit above the table so you can narrow a long history to the run you're after:
* **Search jobs by name** to match on the job title
* **Status**: show only **Pending**, **Running**, **Success**, **Failed**, or **Cancelled** jobs
* **Trigger**: show only jobs started by an **Automation** or run **manually**
* **Created by**: show only jobs a particular teammate started
* **Product**: show only jobs that ran on a specific product
* **From** and **To**: limit to jobs created within a date range
Use **Clear filters** to reset them all at once.
### Renaming a job
Every job can be renamed, whatever its status. Enrichment setup has several steps and the job title is easy to skip past, so you can give a run a clearer name after it has started, or even once it has finished. In the **Actions** column, click the **Rename job** action, type a new **Job name**, and click **Save**. The new name appears everywhere the job is shown, including the header job-status list. A blank name, or a name you haven't changed, can't be saved.
### Cancelling a job
While a job is **Pending** or **Running**, a **Cancel job** action appears in its **Actions** column. Cancelling stops the run: anything already finished is kept, but the remaining items aren't processed, and this can't be undone. Cernel asks you to confirm (**Cancel job** to go ahead, or **Keep running** to leave it) before stopping the job. Finished jobs (**Success**, **Failed**, or already **Cancelled**) have nothing left to stop, so they show no cancel action.
### Older jobs
Jobs run before the Jobs & Review update are kept available under **Show older jobs** at the bottom of the page. Expand it to browse your earlier history; collapse it again with **Hide older jobs**.
### Recent jobs on the Dashboard
The Dashboard's **Recent jobs** widget shows the most recent runs at a glance, with the same status and progress information. Use it to jump to the full Jobs page when you need the complete history.
## Job statuses
| Status | Meaning |
| - | - |
| **Pending** | The job has been created and is waiting to start |
| **Running** | Agents are actively generating values for the products |
| **Success** | Every product in the job finished processing |
| **Failed** | The job could not complete |
| **Cancelled** | The job was cancelled before it finished |
A finished job (**Success**) doesn't mean its values are live. If the run had **Review** turned on, the proposed values wait for your approval on the Review surface (see below).
## Reviewing proposed values
When a run has **Review** turned on, the values your agents generate aren't saved straight away. They wait on the **Review** surface as *proposed values* until you approve, edit, or reject them. This is where you decide what actually goes live on your products.
### Where Review lives
There are two ways into Review:
* **From the Products area**: at the top of the Products screen, switch between **Catalog** (browse your products) and **Review** (work through proposed values). The switch keeps whichever category you have selected, so you can jump straight from a category's products to that category's review queue. Pick categories from the taxonomy tree in the sidebar to narrow what you're reviewing.
* **From a job**: click any job on the **Jobs** page to open the review queue scoped to just that job's products. A **Back to jobs** link returns you to the Jobs page.
### The review queue
The review queue lists one row per product, with a card for each proposed value. Every card shows the attribute, the proposed value, the language, and a status badge:
| Badge | Meaning |
| - | - |
| **In review** | Waiting for your decision |
| **Approved** | You approved this value; it's saved to the product |
| **Rejected** | You rejected this value; it's discarded |
| **Failed** | The agent couldn't generate a value |
| **Skipped** | The agent skipped this value (for example, nothing to generate) |
| **Outdated** | A newer value has replaced this one, so it can no longer be reviewed |
Use the toolbar to focus the queue:
* **Search** by product name
* **Languages**: show only the languages you want to review
* **Filter by job**: narrow to a single job's products
* **Attribute filter**: hide or show value cards by attribute
* **Show failed & skipped**: on by default; turn it off to see only values that are waiting for a decision
* **View options**: let each card grow on a sideways-scrolling row, or lay values out in a column per language
### Approving, rejecting, and dismissing
You have three actions, depending on a value's state:
* **Approve**: accept the proposed value; it replaces the product's current value for that attribute.
* **Reject**: discard the proposed value; the product's current value is left unchanged.
* **Dismiss**: acknowledge a **Failed** or **Skipped** value. There's nothing to approve or reject, so dismissing simply clears it from your queue once you've seen it.
Both Approve and Reject let you add an optional comment to record why you made the call, useful for teammates reviewing the same catalog later.
To work quickly, select multiple cards (or whole product rows) and use the bulk **Approve**, **Reject**, or **Dismiss** buttons. To decide the whole queue in one go, use the header **select all**: this reaches every in-review value that matches your current filters, including products beyond the ones loaded on screen, so you don't have to scroll to the bottom first. When you're reviewing a single job, select all covers that job's entire pending set the same way. You can still deselect individual products to leave them out. When a bulk decision spans many products at once, Cernel asks you to confirm before applying it.
Keep **Show failed & skipped** on while you work through a new job so you can dismiss the values that didn't generate, then your queue reflects only the decisions you still owe.
### Reviewing one product in detail
Click a product (or open a single value) to go to its detail view, which lays everything out in three columns:
* **Current value**: what's saved on the product right now. Approving a proposed value replaces it.
* **Pending · In review**: the proposed values awaiting your decision. Select one to inspect it.
* **Inspector**: everything behind the selected value, so you can decide with full context.
The Inspector shows the value's status, attribute, language, source (for example, **AI enrichment**), and date. If the value was translated, it notes which language it was **translated from**. Three tabs explain how the value was produced:
* **Used attributes**: the product data the agent fed into its prompt as inputs
* **Reasoning**: the agent's own explanation of why it generated this value
* **Prompt**: the exact compiled prompt, including any images, that produced the value
From here you can **Approve** or **Reject** the selected value (with an optional comment), edit it inline before approving, or use **Approve all** to accept every still-pending value on the product. **Previous** and **Next** move you through the products in your current queue or job without returning to the list.
When you're reviewing a single job, decided values stay visible in place, marked with their decision, instead of disappearing. In the general queue, a product drops out once you've resolved its values.
## Understanding value sources
Every attribute value carries a source so you can tell where the data came from. In the product table, hover over an attribute value to open its details popover. The source appears there alongside the value, with a label and icon:
| Source | Icon | Meaning |
| - | - | - |
| **AI Enriched** | Sparkle | Generated by an AI agent during enrichment |
| **Integration** | Plug | Imported from a connected integration like Shopify |
| **Manual Input** | User | Entered or edited manually by a user. When a teammate edited the value, their email is shown below. |
## Advanced configuration
Click a job on the **Jobs** page to open the review queue scoped to just that job's products. In this job-focused view, values you've already decided stay visible in place, marked **Approved** or **Rejected**, so you can see the full picture of what the job produced. A **Back to jobs** link takes you back to the Jobs page when you're done.
If your organization has multiple languages enabled, agents generate values for each configured language, and each value shows its language. Use the **Languages** filter in the review toolbar to focus on one or more languages, or switch on **Language columns** in **View options** to lay each product's proposed values out in a column per language. Manage languages in **Tools > Languages**.
Select multiple value cards, or tick a whole product row to select all of its values, then use the bulk **Approve**, **Reject**, or **Dismiss** buttons. You can attach an optional comment to a bulk Approve or Reject. When a decision spans a large number of products at once, Cernel asks you to confirm before applying it.
Use the header **select all** to decide the entire queue at once. Cernel resolves this against your current filters (languages, attributes, and, in a job review, the job in focus), so it approves or rejects every matching in-review value, including products beyond the ones currently loaded on screen. Deselect individual products first if you want to leave them out, and the confirmation dialog will note how many you excluded.
Not every value generates successfully. **Failed** values are ones the agent couldn't produce; **Skipped** values are ones it had nothing to generate for. These can't be approved or rejected; instead, **Dismiss** them to acknowledge you've seen them and clear them from your queue. Keep **Show failed & skipped** turned on to handle them; turn it off to see only values awaiting a decision.
## Frequently asked questions
Open the job from the **Jobs** page to see its status, and check the review queue for any values marked **Failed**. Common causes:
1. **Agent configuration issue**: the linked agent's prompt may be empty or invalid
2. **Missing dependencies**: a required attribute dependency isn't enriched yet
3. **API error**: a temporary issue with the AI provider
Not directly. Instead, go back to the product table, select the products that failed, and start a new enrichment. Check the agent configuration first to fix whatever caused the failure.
Cernel stops and asks first, so an unsaved edit is never lost silently. If you change a value inline and then approve (on its own or with **Approve all**) without saving, a **You have unsaved changes** dialog appears, and the edited card is marked **Not saved yet** so you can spot it. You then choose:
* **Save and approve**: keeps your edit, saves it, and approves that value.
* **Approve without saving**: approves the value as the agent enriched it and discards your edit.
Nothing is approved until you pick one, so you can also cancel and go back to your edits.
Enrichment no longer fails just because a single image is unusable. If an image can't be fetched, isn't a valid image, or is unusually large, Cernel skips that one image and generates the value from the product's remaining inputs (its other images, text, and attributes). A run only fails when nothing usable is left to work from.
When an image is skipped, the agent records a short note in its **Reasoning**, for example *"A product image was not processed (the image exceeds the size limit)"* followed by the image's address. Open the value in the [review detail view](#reviewing-one-product-in-detail) and check the **Reasoning** tab to see it. If a generated value seems to be missing detail you expected from a photo, this note is the first place to look.
Yes, while it's still **Pending** or **Running**. Open the **Jobs** page and use the **Cancel job** action in that job's **Actions** column, then confirm. Cancelling stops the run: anything already finished is kept, but the remaining items aren't processed, and it can't be undone. Once a job reaches **Success**, **Failed**, or **Cancelled**, there's nothing left to stop, so no cancel action is shown. See [Cancelling a job](#cancelling-a-job).
Yes. The **Configure Enrichment** modal has an optional **Title** field. Whatever you type there becomes the job's **Name** on the Jobs page, so a run is easy to find later. Leave it blank and Cernel names the job for you from the attributes and category you selected (for example, *Color from Electronics*). You can also rename a job later, in any status: use the **Rename job** action in its **Actions** column on the Jobs page. See [Renaming a job](#renaming-a-job).
**Reject** is a decision about a value the agent *did* generate: you're declining to save it, and the product keeps its current value. **Dismiss** applies to **Failed** or **Skipped** values, where there's nothing to save in the first place; dismissing just acknowledges you've seen them and removes them from your queue.
They wait on the **Review** surface as proposed values until you act on them. Nothing is saved to your products or synced to your integrations until you approve it. Reach Review from the **Review** tab on the Products area, or by opening a job from the **Jobs** page. The starting position of the **Review** toggle in the enrichment modal follows your organization's approve-before-push setting (in **Settings > Platform**), and you can override it for any individual run.
Changing the organization's approve-before-push setting only affects *future* runs: it sets the default position of the **Review** toggle when you start an enrichment. It does **not** retroactively approve or push values that are already waiting in Review. Those still need a decision: approve them from the Review surface, or reject them if you don't want them.
Each enrichment run processes up to **50,000 products** in a single job, so most catalogs enrich in one go. If you select more, only the first 50,000 are enriched in that run and the rest are silently skipped. For catalogs larger than that, enrich in runs of 50,000 or fewer, turning on **Only enrich missing fields** and waiting for each job to finish before starting the next. See [Enriching a large catalog in batches](#enriching-a-large-catalog-in-batches).
The product table tells two kinds of blank apart, so you can see whether an agent has looked at an attribute yet:
* **An empty cell** means nothing has ever been written for that attribute on that product. Enrichment hasn't produced a value here.
* **A muted "No value"** means an agent did run and deliberately produced nothing, because it found nothing to write for that attribute. It carries the same enrichment tint as any other AI-written value, so you can tell it apart from an untouched cell.
Hover over the value to open its details popover and confirm the [source](#understanding-value-sources). If you expected a value where you see **No value**, check the agent's prompt and the product's inputs: the agent ran but had nothing to go on.
Yes. Click **Bulk select** in the product table toolbar, pick the cells, rows, or columns you want (drag or **Shift**-click to take a block), then click **Bulk edit values** to **Set value**, **Clear**, or **Leave as is** for each attribute and language. This writes the values directly, so use **Send for review** in the editor if you'd rather have them approved first. To empty the selected values outright, click **Delete** (or press **Del**) instead of opening the editor. See [Editing values in bulk](#editing-values-in-bulk).
No. Writing values in the bulk editor overwrites the selected products and can't be undone from the dialog, which is why Cernel asks you to confirm the count first. If you want a safety step, turn on **Send for review** so the edits wait as proposed values on the [Review surface](#reviewing-proposed-values) until you approve them.
Yes. Saved views are stored in your Cernel account, not in the browser, so a view you save is there when you sign in from another browser or another device. When you save a view you choose who can see it: **Only me** keeps it in your own list, while **Everyone at \[your organization]** shares it with the whole team, and anyone there can apply or edit it. You save and manage views from the **Views** button on the product list; see [Saving and sharing a view](#saving-and-sharing-a-view). (This replaces the earlier saved filters, which were kept only in the browser you saved them in.)
Yes. By default the product table's search and filters match **parent products** only. Turn on the **Search within children** toggle in the product table toolbar to widen the match to child products as well, so you can land on an individual variant. The toggle stays disabled until you enter a search term or apply a filter, since it needs something to match against.
With it on, each matching variant appears under its parent product, with extra columns for the properties that set that variant apart and the matched text highlighted, so you can see exactly which children matched and why.
Once you've found the variants you want, select the parent product and set the **Product Scope** in the enrichment modal: choose to include child products, or to run only on the children. See [Running enrichment](#running-enrichment) for the scope options.
Yes. When you enrich variants (with a **Product Scope** of **Include child products** or **Only child products**), their proposed values wait for a decision on the **Review** surface just like a parent product's. Selecting a category in the sidebar, or applying a search or filter, keeps the variants in view: each variant lists as its own row alongside its parent, and you approve, edit, or reject its values the same way.
Bulk actions cover variants too. When you use the header **select all** to decide a whole category or a whole job, every matching variant value is included, not only the parent products. For variant-heavy catalogs this means the queue can show many more rows than you have parent products, since each enriched variant contributes its own.
Yes. Cernel supports multi-language enrichment. The enrichment modal shows your enabled languages, and AI generates content in each configured language. You can manage languages in **Tools > Languages**.
Turn on **Only enrich missing fields** in the enrichment modal. When this toggle is on, the AI only generates values for attributes that have no value yet; existing values you've reviewed or hand-edited are left alone. Turn it off to re-enrich every selected attribute, overwriting current values.
Cernel decides a field is missing by whether a value has ever been **saved** for it, not by what that value looks like. A field with any saved value counts as filled and is skipped, even when that value is blank, for example one you cleared by hand or a blank that came in from an import. A field like that can look empty in the table and still be left untouched by the run.
The check runs **per language**, so on a multi-language attribute one language can be filled and skipped while another is still missing and gets enriched in the same run.
To re-generate a field that already holds a saved but empty value, turn **Only enrich missing fields** off for that run. You can narrow the run to those fields first by adding an **Is empty** filter (see [Filtering the product list](#filtering-the-product-list)).
Most products finish in under a minute. Text attributes are the quickest, while attributes that generate images or pull in external data can take a few minutes per product.
Adding more attributes does not make enrichment slower. Cernel works on all selected attributes for a product at the same time, so the total wait is only as long as the slowest one.
Small batches typically complete in seconds. Larger runs across hundreds of products may take several minutes. If you have multiple jobs running at once, they may take a little longer as Cernel shares capacity fairly across your workspace.
Jobs remain visible on the Jobs page. Recent runs appear at the top; earlier history, including jobs from before the Jobs & Review update, is available under **Show older jobs**. The Dashboard's **Recent jobs** widget gives you a quick view of the latest runs with a link through to the full page.
## What's next
Create and refine agents to improve the quality of your enrichment output.
Set up automatic enrichment for new products so you don't have to start jobs by hand.
# Languages
Source: https://docs.cernel.com/features/languages
Generate AI-powered product content in multiple languages and configure language-specific prompts.
Cernel supports multi-language content generation. Enable the languages your store needs, give each one a translation prompt to guide AI output, and generate enriched content across all your active languages in a single enrichment run.
## How it works
Your organization has a **primary language** and can enable additional languages. When you run enrichment, Cernel generates content in each enabled language. Each language can carry its own **translation prompt** - additional context for that language, like grammar rules, cultural preferences, or terminology that should be used.
Languages are managed under **Tools > Languages**:
* The **languages list** is where you enable or disable languages and add new ones.
* Each language has its own **detail page** - open it to write that language's translation prompt and control how it's used during enrichment.
Beyond these organization-wide settings, you can refine how content reads in a given language for a single agent, and decide which languages a single attribute is written in. See [Fine-tuning language output](#fine-tuning-language-output).
### Why you would use this
Generate product descriptions, meta titles, and structured data in every language your store supports - without hiring translators.
A per-language translation prompt ensures AI output follows the grammar, tone, and conventions of each target language, not just a direct translation.
## Setting up languages
Go to **Tools > Languages**. You'll see a table of available languages with their language code and status. Toggle languages on or off using the switch in each row.
Your primary language is marked with a badge and cannot be disabled.
Click **Add Language** to enable a language that isn't in your list yet. Type the language code you want, for example `en` for English, `da` for Danish, or a region-specific code like `sv_FI` for Swedish (Finland), and click **Add Language**. Once added, the language appears in your table.
Language codes follow the IETF / ISO 639 conventions Cernel uses across the platform. Use a two-letter code (`en`, `da`, `de`) for a generic language, or combine a language and region with an underscore (`sv_FI`, `pt_BR`, `en_GB`) when you need region-specific content. The platform validates the code on submit, so if a code isn't recognised you'll see an error and can try again.
From **Tools > Languages**, click a language in the table to open its detail page. Here you can write a **translation prompt** for that language - instructions that guide how the AI produces content in it. Use it for:
* Grammar and style rules specific to the language
* Cultural conventions and preferences
* Terminology that should (or shouldn't) be used
Type `/` in the prompt editor to pull in a Data Source for reference, then click **Save**.
The **Use translation prompt for all language enrichments** toggle, at the top right of the Translation Prompt section, is on by default. While it's on, Cernel automatically instructs your agents to write this language's enriched content *in* that language, so your output always comes back correctly localised. Turn it off only if you'd rather control the output language entirely through your own prompts.
Your languages are configured. When you run enrichment, Cernel generates content in each enabled language, applying that language's translation prompt.
## Fine-tuning language output
A language's translation prompt sets the rule for that language across your whole organization. Two further controls let you refine language behavior more precisely: per agent, and per attribute.
### Give an agent its own language instructions
Each agent can carry its own instructions for each language, on top of the organization-wide settings. Open an agent, go to the **Languages** tab, and you'll find one box per enabled language. Whatever you write in a box is applied when the agent writes a value in that language, and, for Text and HTML agents, when a value is translated into it. Leave a box empty to add nothing for that language. Type `/` in a box to reference a [Data Source](/features/data-sources).
Use this when a single agent needs a language rule the others don't, for example a size-guide agent that must use metric phrasing in German, without changing how any other agent writes German.
The **Use the organization's language instructions** toggle above the boxes is on by default. While it's on, the agent also gets the standard output-language directive when it writes, and the language's translation prompt when it translates, in addition to anything you type in the boxes. Turn it off to make the agent's own boxes the only language instructions it gets, replacing the organization's wording instead of adding to it.
The Languages tab appears on every agent that writes from a prompt. Taxonomy classification agents, which don't use a prompt, don't have it.
### Choose which languages an attribute is written in
By default, each enrichment run decides which languages an attribute is written in, one plan for the whole run. You can instead fix that choice for a single attribute. Open the attribute's agent settings, expand **Enrichment Settings**, and turn on **Override language settings**. A per-language plan appears where each enabled language is set to **Generate**, **Translate**, or **Skip**, the same editor you use when starting a manual enrichment. Once it's on, that plan replaces whatever a run asks for, but only for this attribute.
A new plan starts the way a run does: the attribute is written in your primary language and translated into the rest. Because the plan is a fixed list rather than a rule, a language you enable later sits outside it and is skipped for this attribute until you add it. Cernel notes under the editor which languages are currently left out, so the gap is easy to spot.
You edit these settings at the category where the attribute's agent is set. Viewed from a subcategory that receives the attribute from a parent category, they show as read-only with a link to the category that owns them. They are also read-only until an agent is attached.
## Advanced configuration
Besides per-language translation prompts, you can set Global Prompts per attribute type (Text, HTML, Single Select, Multi Select). These are configured in **Settings > Global Prompts**. They provide foundational instructions that apply to all agents generating that type of content.
For example, a system prompt for HTML might say "Always use semantic HTML headings" while one for Single Select might say "When uncertain, choose the closest match rather than leaving empty."
For Single Select and Multi Select attributes, the predefined values can be translated into each enabled language. When configuring an attribute, the Values section shows translation status for each value. You can auto-translate or enter translations manually.
Disabling a language hides it from language selections but preserves all existing translations. You can re-enable it later without losing any data.
## Frequently asked questions
No. The same agents work across all languages. Cernel handles the language context through each language's translation prompt and your language settings. Your agents focus on what to generate, not which language to use.
The enrichment modal shows your enabled languages. Content is generated for all enabled languages by default. If you need content in just one language, you can manage this through your language settings.
A **translation prompt** is set per language and applies automatically to all content generated in that language - it handles language-wide rules. **Agent prompts** define what content to generate and how. They work together: the agent prompt says "write a 150-word product description" and the language's translation prompt adds "use formal Danish grammar."
They stack. A language's **translation prompt**, set under **Tools > Languages**, applies to every agent writing in that language. An agent's **Languages** tab adds instructions for that one agent only. With the agent's **Use the organization's language instructions** toggle on, the agent gets both. Turn it off and the agent's own boxes replace the organization's wording for that agent. See [Give an agent its own language instructions](#give-an-agent-its-own-language-instructions).
Use the agent's per-language instruction boxes and point each one at a different [Data Source](/features/data-sources). A Data Source entry is a single block of text you insert whole, so there's no way to filter one shared entry down to a market's slice. Instead, create one entry per market (for example `seo/keywords-es`, `seo/keywords-fr`), then open the agent, go to its **Languages** tab, and in each language's box type `/` to reference only that market's entry: the Spanish entry in the Spanish box, the French entry in the French box, and so on. A run in a given language then only pulls in the content from that language's box, so each market sees only its own keywords. You don't need separate agents to do this. See [Give an agent its own language instructions](#give-an-agent-its-own-language-instructions).
Yes. When a language is set to **Translate** (rather than **Generate**), Cernel translates the value produced in the source language instead of writing it again from scratch. The translation reuses the prompt that generated the original value as read-only guidance, so the translated value honors the same length, tone, and format rules as its source. For example, a value written to a 150-word limit stays within that limit after translation. Each translated value also passes the same quality check Cernel applies to generated content, so corrupted output is caught and retried automatically.
## What's next
Create agents that generate content across all your enabled languages.
Run multi-language enrichment across your product catalog.
# Product detail
Source: https://docs.cernel.com/features/product-detail
Inspect and edit everything Cernel knows about a single product: its attribute values, how complete it is, its variants, and the data each connected integration sends.
The product detail page is where you see and manage everything Cernel holds for a single product. It brings the product's attribute values, their languages, its variants, and the raw data from each connected integration into one view, and shows at a glance how complete the product is. Open it from the Products page whenever you want to check a specific product, edit a value by hand, or understand where a value came from.
## How it works
Open a product from the Products page to land on its detail page. The header shows the product's image, its categories in the Cernel Taxonomy, its identifiers (such as SKU and GTIN), and a **Completeness** ring. Below the header, a set of tabs organizes the rest:
* **Attributes**: every attribute value on the product, with the language it's filled in, where it came from, and the category it belongs to. This is where you edit values.
* **One tab per connected integration**: the properties that integration sends for this product, shown exactly as they arrive, and how each one connects to your attributes.
* **Variants**: the product's variants (for example the same product in different sizes or colours), shown only when the product has them.
* **Events**: a log of the system activity Cernel has recorded for this product, such as when it was enriched, classified, or synced.
**Key concept: completeness.** Completeness compares how many attributes have a value against everything the product's category could hold (its filled values plus the category attributes still empty). It's a guide to what's left to fill in, not a target: reaching 100% isn't always the goal, so fill in what's relevant for each product.
### Why you would use this
Check what's filled in, what's still missing, and how complete a product is before you enrich it or push it live.
Adjust an individual attribute value, fill in a missing one, or edit every language for a value in one place, without running a job.
Every value shows its origin (enriched, manual, or imported) and its history, so you can trace how it got there and restore an earlier version.
See the exact properties each integration sends for the product and how they map to your attributes.
## Working with a product
On the Products page, click a product to open its detail page. Use **Back to products** in the top left to return to the list; your filters, search, and sort are preserved.
The header summarizes the product:
* **Image gallery**: the product's images, including any image-typed attribute values. Use the arrows to step through them.
* **Categories**: the paths the product is classified into, led by the Cernel Taxonomy and followed by any external standards (for example Google Product Category).
* **Identifiers**: the product's identifier values, each tagged with its type (SKU, GTIN, and so on).
* **Completeness**: a ring showing the share of the category's attributes that have a value. Hover it for the exact percentage, and hover the info icon for how it's measured.
The **Attributes** tab lists every attribute on the product, one row each. For each attribute you see:
* **Attribute**: the attribute name.
* **Value**: the current value, editable inline.
* **Category**: the category the attribute is defined on in the Cernel Taxonomy.
* **Languages**: which languages hold a value. With a few languages, the codes read as text (green where filled, red where missing); with more, a compact bar shows the ratio and opens a full language report when clicked.
* **Origin**: how the value was produced. **Enriched** by an AI agent, **Manual** if someone typed it, or **Imported** from an integration.
Click a column header (Attribute, Category, or Origin) to sort by it, and click again to reverse the order. Attributes the category defines but the product hasn't filled in yet appear as empty rows so you can add a value directly.
Click a value to edit it in place, then save. The editor matches the attribute type (text, HTML, a select, and so on). To fill in an attribute that has no value yet, edit its empty row the same way.
For a Single Select attribute that allows an empty value, the option list includes a **No value** choice at the top. Pick it to clear the field back to no value, the same as leaving the attribute unset.
To work across languages, open the attribute's actions and choose **Edit translations**. A panel opens with every enabled language side by side, the primary language marked, and any AI reasoning shown beside the value that has it. Edit any languages you need and save them all in one go; languages you don't touch are left untouched.
Open a value to see its details footer. Alongside its type and origin, the footer shows **Updated** with the date and time the value was last written, whether that was an enrichment, an import, or a manual edit. When someone edited the value by hand, it also shows **Edited by** with that person's email, so you can tell at a glance who last changed it. The timestamp is for the value as a whole, so every language of the same value shares it.
From an attribute's actions, choose **Show history** to open its version history. Each past version is timestamped; restoring one overwrites the current value with that version. Cernel asks you to confirm first, since the restore replaces what's there now.
If the product has variants, open the **Variants** tab. Each variant lists the attributes that make it distinct (for example its size or colour) and how many sub-variants it has. Click a variant to open its own detail page.
Each connected integration has its own tab showing the properties it sends for this product, exactly as they arrive. The **Connected attributes** column shows which Cernel attributes and identifiers each property maps to, with arrows for the direction (a top arrow for values going out to the integration, a bottom arrow for values coming in). Search to find a property by name.
Open the **Events** tab to see the system activity Cernel has recorded for this product. Entries appear here as the product is enriched, classified, or synced with an integration. Each row shows the event's level (**Info** or **Error**), its domain, a short description, and when it was last seen. Use **Min severity** to focus on errors, and click a row to expand it for the full details: how many times it occurred, when it was first and last seen, and the integration or product it relates to. The feed is scoped to this product, so it never shows another product's activity.
## Advanced configuration
On the **Attributes** tab you can narrow the list several ways at once:
* **Search** by attribute name.
* **Filter by language** to show only attributes that hold a value in the languages you pick.
* **Filter by origin** to show only values that were **Enriched**, **Manual**, **Imported**, or that have no recorded origin.
* **Filter by integration** to show only attributes supplied by a given integration, or choose **Not from an integration** for values added in Cernel by enrichment or by hand.
When a product is a variant, the attributes that define its variant axis (for example the size or colour that distinguishes it) are owned by its parent and shown as **locked** on the variant. You'll see the note *"This attribute defines the variant, so it can't be edited here."* This keeps a variant's defining values consistent with the parent. Edit these values on the parent product instead.
On an integration tab, properties split into two sections. **Mapped** properties connect to a Cernel attribute or identifier, listed in the **Connected attributes** column. **Unmapped** properties arrive from the integration but aren't connected to anything, so their values aren't applied to your products. To start using them, open the integration's settings with **Configure mappings** and map them there.
Editing a mapped property's value on this tab writes to the Cernel attribute it maps to, not to the integration's raw incoming value (which is refreshed on the next sync).
The ring divides the number of attributes that have a value by everything the product's category could hold: its filled values plus the category attributes that are still empty. Cernel measures against the category the product is actually classified into, not wherever you browsed in from. A product with no category attributes shows no ring.
## Frequently asked questions
No. Completeness shows how much of a category's attribute set a product has filled in, as a guide to what's left. Not every attribute is relevant to every product, so fill in what matters for the product rather than chasing 100%.
That attribute defines the product's variant axis (such as its size or colour) and is owned by the parent product, so it's locked on the variant to keep the two consistent. Edit the value on the parent product instead.
Only for attributes the variant doesn't already have a value for. Enrichment checks the variant's own data first, for every attribute referenced in the prompt. If the variant already holds a value there (for example its own images), that value is used and the parent product's value for that attribute is not pulled in as well. If the variant has no value of its own for that attribute, Cernel looks for it on the parent product, then the parent's own parent, and so on up the chain, stopping as soon as it finds a value or running out of ancestors to check.
You can switch this inheritance off for a specific agent. In the agent's settings for a category, turn off **Use parent product data**, and that agent enriches each variant from the variant's own values only. This helps when parent products hold placeholder or copied data. See [Enrich variants from their own data only](/features/ai-agents#enrich-variants-from-their-own-data-only).
The **Origin** column shows how a value was produced: **Enriched** means an AI agent generated it, **Manual** means someone entered or edited it by hand, and **Imported** means it came in from a connected integration. A value with no recorded source shows no origin.
Restoring replaces the current value with the version you picked, for that language. Cernel confirms before it does this, because the current value is overwritten. Other languages and other attributes are unaffected.
Open the value to see its details footer. **Updated** shows the date and time it was last written, for any origin (enrichment, import, or manual edit). If the last change was a manual edit, **Edited by** also shows the email of the person who made it. The timestamp covers the value as a whole, so it reads the same across every language.
If the Single Select attribute allows an empty value, open its editor and pick **No value** from the top of the option list. That returns the field to having no value. To clear values across many products at once, use bulk select and the **Clear value** action on the [Products page](/features/jobs-and-enrichment#deleting-values) instead.
Editing a property value on an integration tab writes to the Cernel attribute that property maps to. It does not change the integration's raw incoming value, which Cernel refreshes on the next sync. Properties that aren't mapped to an attribute can't be edited here.
The **Events** tab lists the system activity Cernel has recorded for this specific product, such as enrichment, classification, and integration syncs. It's scoped to the product you're viewing, so it only ever shows that product's own activity, not the whole account's. Each entry is graded **Info** or **Error**. Filter by **Min severity** to focus on problems, and expand a row to see the full details, including how often it occurred and when it was first and last seen.
## What's next
Set up the attributes and agents that fill in the values you see here.
Run enrichment across many products, then approve the proposed values.
Configure the languages a product can carry values in.
Import product variants so they appear on the Variants tab.
# Agent Sandbox
Source: https://docs.cernel.com/features/sandbox
Test and refine an AI agent on real products before running enrichment across your catalog.
The **Agent Sandbox** is where you iterate on an AI agent against your own products, see exactly what it generates, and refine its behavior through a chat, all before you run enrichment on your catalog. It's the fast, low-stakes workspace for tuning an agent's voice, structure, and accuracy, so the agent is already performing the way you want before it touches any real job.
## How it works
The sandbox lives inside the agent wizard's final step, both when you create a new agent and when you edit an existing one. You pick a handful of real products from the current category, click **Run**, and the agent generates values for each one in front of you. Results stream in live as each product finishes, and you can watch the agent's reasoning as it works. For every result you can see the generated value, the AI's reasoning, and the source data it used.
The sandbox only runs when you click **Run** (or **Re-run**): opening the step or switching attribute types doesn't trigger a run on its own. That way you stay in control of when the LLM is called. While a run is in progress, the **Run** button becomes **Cancel**: click it to abort the in-flight request immediately, keep any results that already came back, and return to a startable state.
If the output isn't quite right, you don't rewrite the prompt by hand. You tell the sandbox's **agent chat** what to change (for example, *"make descriptions shorter"* or *"don't mention competitor brands"*) and the chat rewrites the prompt as a new version in history. Each refinement creates a new version of the prompt that you can step through with **undo** and **redo**, so you can compare wordings and roll back any change that made things worse. Once the prompt is rewritten, click **Re-run** to generate fresh output for the new version.
When the sandbox is showing output you're happy with, save the agent. The current prompt is committed, and the agent is ready to be linked to attributes and run through enrichment at scale.
### Why you would use this
See the agent's output on real products first. Fix tone, structure, and accuracy on a handful of samples instead of discovering issues across thousands of enriched products.
Tell the chat what to change in plain language. It rewrites the prompt and re-runs the agent for you, faster than hand-editing a long prompt and guessing at phrasing.
Step back through prompt versions to compare outputs. If a change made things worse, one click takes you back.
The sandbox runs against your own product data, so what you see is what enrichment will actually produce.
**Key concept: Agent chat.** The chat panel on the left of the sandbox doesn't just comment on the output. It rewrites the agent's prompt based on what you ask and saves the new version in history. Click **Re-run** when you're ready to generate output for the rewritten prompt; the chat itself doesn't auto-trigger a new sandbox run.
## Step-by-step guide
Create a new agent or edit an existing one. In the wizard, step through to the final step: **Review & Test**. The sandbox opens with a small random sample of products pre-selected for you.
For a brand new agent, the sandbox pre-selects up to 5 random products (preferring products with images), but it doesn't run until you click **Run**. You can replace the selection any time before running.
Use the product picker to set which products the agent should run against. You can:
* **Search and pick manually**: type part of a product name, click results to add them
* **Click 5 Random**: let Cernel pick 5 random products from the current category, preferring ones with images
You can select up to **10 products** per run.
Pick a mix that represents what enrichment will actually face: different product types, price points, and levels of input data. Catching edge cases here saves you from discovering issues across thousands of enriched products later.
Click **Run**. Results stream in live, one product at a time. Each card updates with a rotating status as the agent works (for example, *Initializing agent*), then settles into the generated value as soon as that product finishes, so products that complete early show their output while the rest are still running, instead of everything appearing at the end. Each result shows the product's name and image alongside the generated value for the agent's attribute.
To watch the agent reason as it goes, click **View live agent thinking** on a card to expand the **Live agent thinking** panel: a running stream of the agent's reasoning for that product. Collapse it again at any time, or copy the text to keep it. If a product fails, its card shows an error state, and you can still open its thinking to see what the agent did before the error.
On the next run, the button becomes **Re-run**, so you can generate fresh output on the same selection as you iterate. While a run is in progress, the same button shows **Cancel**: click it to stop the run immediately. Results that already came back are kept; you'll see a *Run cancelled* toast and the button returns to **Run** / **Re-run** so you can adjust and try again.
Cancel is especially useful for External Data agents: a single agentic web research pass can take a couple of minutes, and Cancel lets you abort if you spot a misconfiguration without waiting it out.
Scan the generated values. For any result you can:
* **Hover the value** to see the **AI Reasoning**, a breakdown of how the agent arrived at the output
* **Click View details** (the info icon at the top-right of each product card) to open the detail drawer, which shows the compiled **Prompt** the model received, the **Source Data** (product attributes used as context), and the **Result** in full
If a product failed, the card shows an error state so you know something went wrong for that specific input.
If the output needs work, use the **agent chat** on the left. Type what you want to change. For example:
* *"Make the descriptions shorter, aim for 80 to 100 words."*
* *"Start every description with the material, then move to fit."*
* *"Don't mention competitor brands."*
The chat rewrites the prompt and saves the change as a new version in history. To see the rewritten prompt in action, click **Re-run**: the chat doesn't trigger a new sandbox run on its own, so you stay in control of when the LLM is called.
Type `@` in the chat to reference a specific product from your current results. The chat picks up that product's generated output and reasoning, so feedback like *"@Blue Running Shoe, too wordy, make it match the tone of the others"* is tied to exactly what you're pointing at.
Every refinement creates a new version of the prompt. Use the **Undo** and **Redo** buttons at the top of the chat panel to move between versions. Each step takes you one change back or forward, so you can compare output side by side and roll back any change that didn't land.
If the current direction isn't working, undo back to a version you liked before adding new instructions on top. It's often faster than undoing one refinement at a time.
When the output is where you want it, save the agent. The current prompt (the latest version in history) is committed and linked to the agent. Your sandbox selection and chat history are cleared; the agent is now ready to be linked to attributes and run through enrichment.
The agent is saved with the prompt you tested. Running enrichment with this agent will produce output similar to what you just saw in the sandbox.
The sandbox doesn't run an agent's dependencies before testing. If your agent depends on other attribute values (for example, a Meta Description agent that reads Product Description), pick products that already have those upstream values filled in. Otherwise the sandbox will show weaker output than enrichment would produce once dependencies are in place.
## Advanced configuration
The agent chat supports `@` mentions. Typing `@` opens a list of the products in your current sandbox run. Click one to insert it as a pill into your message. When the chat rewrites the prompt, it uses that product's generated output, reasoning, and images as grounded feedback, not just the text you typed.
Use this when one product is off but the rest look fine. Instead of rewording the entire prompt, point the chat at the outlier and describe what's wrong with it specifically.
The detail drawer ( **View details** on any result) shows three tabs:
* **Prompt**: the compiled prompt that was sent to the model for that product, with Data Source references and product fields already filled in. If the output is surprising, check the compiled prompt first to see whether the right context made it in.
* **Source Data**: the product attributes the agent used as context, including the product name, images, and any referenced fields
* **Result**: the generated value on its own, rendered the way the product table will render it
If you're debugging an unexpected output, comparing the Prompt and Source Data between a good product and a bad product usually pinpoints the problem quickly.
As a product runs, click **View live agent thinking** on its card to open the **Live agent thinking** panel. This is the agent's reasoning, streamed as it happens, useful for understanding *why* an output is taking shape the way it is, especially for longer-running External Data and Media agents. Use **Hide live agent thinking** to collapse it again, or copy the full stream to paste into a chat refinement or a note.
The thinking is preserved after the run finishes, including for products that errored, so you can open the detail drawer and review what the agent did before it failed. Pair this with the **Prompt** and **Source Data** tabs to see the full picture: what the model received, how it reasoned, and what it produced.
If you change the agent's attribute type during the wizard (for example, from Text to HTML, or from Single Select to Multi Select), the sandbox automatically asks the chat to adapt the prompt for the new type. This keeps the instructions aligned with what the new type expects, so you don't have to rewrite them from scratch.
After the prompt is adapted, re-run the sandbox to see output in the new format.
* **Saved with the agent:** the prompt as it stands at the moment you save (the current version in history), plus any configuration changes made in earlier wizard steps
* **Not saved:** the list of sandbox products you tested on, individual sandbox results, and the agent chat transcript
When you reopen the wizard later, the sandbox starts fresh. The agent carries forward the prompt you saved, but the conversation that produced it is not stored.
## Frequently asked questions
Two common causes:
1. **The agent has dependencies that haven't been filled in on the test products.** The sandbox doesn't run upstream agents first. If your agent reads other attribute values, pick test products that already have those values.
2. **The selected products don't represent your catalog well.** Try clicking **5 Random** again, or hand-pick a mix of product types and price points. Outputs can vary a lot between, say, a simple t-shirt and a technical running shoe.
No. The sandbox runs on up to 10 products per run by design, so refinement stays fast. Ten is typically enough to spot patterns in the output. Once you're happy with the agent, run enrichment to generate content across the rest of the catalog.
Not directly. Undo and redo move one step at a time through the prompt's history, so you can compare consecutive versions. If the current direction isn't working, undo back to the version you liked and start a new refinement from there.
The chat calls the LLM once to rewrite your prompt for the new instruction. That's a small, fast call. The sandbox itself only re-runs when you click **Re-run**, so you decide when the (potentially slow) enrichment pass actually fires. Keep chat messages focused: one clear change per message is easier to verify than a long instruction that rewrites several things at once.
Yes. Results stream in live: each product's card updates as the agent works and shows its output the moment that product finishes, rather than waiting for the whole batch. To see the agent's reasoning as it happens, click **View live agent thinking** on a card to open the **Live agent thinking** panel. It stays available after the run, including for products that failed, so you can inspect what the agent did before an error.
Yes. The **Run** button becomes **Cancel** while a run is in progress. Click it to abort immediately: Cernel stops the in-flight LLM call, keeps any results that already came back, and returns the button to **Run** / **Re-run** so you can adjust and try again. This is especially useful for External Data agents in Agentic mode, which can take a couple of minutes per pass.
The agent chat transcript isn't stored. The prompt version you saved with the agent is kept, but the conversation that produced it is discarded. If you reopen the agent, the sandbox starts fresh.
Technically yes. You can send chat messages before the sandbox has run, and the chat will still refine the prompt. But the refinements aren't grounded in any output, so the results are less predictable. The recommended flow is: run the sandbox, read the output, then refine.
## What's next
Learn the full agent setup: prompts, Data Sources, dependencies, and linking agents to categories.
Take a sandbox-tested agent and run it across a full category.
Understand the attribute types the sandbox tests against, and how they're configured on categories.
Plug brand guidelines and context libraries into prompts so sandbox output lines up with your brand.
# Settings & Configuration
Source: https://docs.cernel.com/features/settings
Configure your Cernel platform: organization settings, Global Prompts, usage tracking, event monitoring, and platform preferences.
Cernel's configuration lives in two places in the sidebar. Day-to-day work items (Automations, Data Sources, Integrations, Languages) are grouped under **Tools** at the top of the sidebar. Platform-wide configuration (Global Prompts, Usage, team management, API access) lives under **Settings** at the bottom of the sidebar.
## Tools overview
The **Tools** section in the main sidebar holds the workspaces you return to as part of daily enrichment work:
| Tool | Path | What it controls |
| - | - | - |
| **Automations** | Tools > Automations | Auto-enrichment rules for new products |
| **Data Sources** | Tools > Data Sources | Organization context library for agent prompts |
| **Integrations** | Tools > Integrations | Shopify, CSV, Feed, API connections |
| **Languages** | Tools > Languages | Enabled languages and language configuration |
## Settings overview
Click **Settings** at the bottom of the sidebar to access platform and team configuration.
### Global settings
| Setting | Path | What it controls |
| - | - | - |
| **Platform** | Settings > Platform | Approve Before Push, sidebar tree depth |
| **Global Prompts** | Settings > Global Prompts | System-level AI instructions per attribute type |
| **Usage** | Settings > Usage | Enrichment metrics, usage tracking |
| **Events** | Settings > Events | System activity log with filtering and diagnostics |
### Organization settings
| Setting | Path | What it controls |
| - | - | - |
| **Users** | Settings > Users | Team member management, roles, invitations |
### Developer settings
| Setting | Path | What it controls |
| - | - | - |
| **API** | Settings > Developer > API | API key and service account management, and documentation |
See [Developer Tools](/features/developer-tools) for a full guide on API keys and service accounts.
## Key platform settings
### Approve Before Push
When enabled, AI-generated content must be explicitly approved before it syncs to your connected integrations. This gives you full control over what gets published to your store.
Find this at **Settings > Platform** under "Enable 'Approve Before Push'."
### Global Prompts
System-level instructions that apply to all AI agents. The page lists a system prompt per attribute type (Text, HTML, Single Select, Multi Select); click **Edit Prompt** on any type to customise it. These instructions are automatically included when an agent generates that type of content.
Per-language instructions live elsewhere: open a language under **Tools > Languages** to set its translation prompt. See [Languages](/features/languages#setting-up-languages).
Global Prompts combine with individual agent prompts. You don't need to repeat organization-wide rules in every agent. Put universal rules in Global Prompts, and content-specific instructions in agent prompts.
### Usage tracking
The Usage page (**Settings > Usage**) shows your enrichment activity:
* **Elements Run Total** - Total number of attribute values generated
* **Total Jobs** - Number of enrichment jobs run
* **Avg Elements Per Job** - Average attribute values generated per job
* **Elements Run Today** - Today's generation count
* **Enrichments over time** as a trend chart
* **Breakdown by type** (Text, HTML, Single Select, etc.)
* **Breakdown by language** for localization tracking
Filter by time period to track your enrichment usage across different ranges.
### Event Log
The Event Log (**Settings > Events**) gives you a real-time view of system activity across your Cernel platform. Use it to monitor what's happening with your integrations, enrichment runs, and product processing, and to quickly diagnose issues when something goes wrong.
The event table shows four columns:
| Column | What it shows |
| - | - |
| **Level** | Severity of the event: **Info** (normal activity) or **Error** (something needs attention) |
| **Domain** | Which part of the platform generated the event (e.g., Integration, Platform) |
| **Event** | A description of what happened |
| **Last seen** | How recently the event occurred |
Click any event row to expand it and see additional details: how many times it occurred, when it was first and last seen, the associated integration (if applicable), and any diagnostic information.
#### Filtering events
Use the filter toolbar at the top of the page to narrow down what you see:
* **Min severity**: Show only events at a certain severity level or above
* **Domain**: Filter to events from a specific platform area
* **Event kind**: Filter to a specific type of event
* **Resource type**: Filter by the type of resource involved (e.g., product, integration)
Click **Clear filters** to reset all filters and see the full event stream again.
If you're troubleshooting a sync issue with an integration, filter by the **Integration** domain and **Error** severity to quickly find relevant events.
### Category depth
Control how many levels of your taxonomy appear in the sidebar navigation. Set this at **Settings > Platform**. Choose between 3 and 7 levels. This is display-only and doesn't affect how attributes flow or how enrichment works.
## Frequently asked questions
**Tools** are the workspaces you use day-to-day to configure how enrichment runs: Automations, Data Sources, Integrations, and Languages. They live at the top of the sidebar because you visit them regularly. **Settings** (at the bottom of the sidebar) holds platform-level and team configuration you change infrequently: Global Prompts, Usage tracking, Users, and API keys.
**Global settings** affect how the platform behaves for everyone in your workspace (Global Prompts, Usage tracking). **Organization settings** manage team access (Users).
Admin users can access all settings. Regular users have limited access depending on their role. User management (inviting, removing, changing roles) is admin-only.
**Settings > Usage**. This shows total enrichments, trends over time, and breakdowns by type and language.
Go to **Settings > Events** and filter by **Domain: Integration** and **Min severity: Error**. The event log shows all recent errors along with details about what went wrong. Expand any event row for diagnostic information including occurrence count and timestamps.
Global Prompts are prepended to agent prompts automatically. The AI receives both: the Global Prompt first (for universal rules), then the agent's specific prompt (for content instructions). This means rules like "never use superlatives" only need to be set once in Global Prompts, not in every agent.
## What's next
Manage team members, roles, and invitations.
Enable languages and configure language-specific Global Prompts.
# Users & Team
Source: https://docs.cernel.com/features/users-and-team
Manage your team members, invite new users, assign roles, and control access to your Cernel organization.
Cernel lets you invite team members to your organization and assign them roles that control what they can do. Admins manage the team, while regular users work with products, agents, and enrichment.
## How it works
Each Cernel organization has a list of users. Users are invited via email and can be assigned one of two roles: **Admin** or **User**. Admins have full access to all settings including user management, while regular users can work with the platform's core features.
If you have access to multiple organizations, you can switch between them without logging out.
### Why you would use this
Invite team members so multiple people can configure agents, run enrichment, and review results.
Admin-only access for sensitive settings like integrations, user management, and API keys. Regular users focus on content work.
## Managing users
### Viewing your team
Go to **Settings > Users** to see all members of your organization. Each user card shows:
* **Name** with a "You" badge for your own account
* **Email address**
* **Role** (Admin or User)
* **Status** (Active or Inactive)
* **Last login** timestamp
### Inviting a new user
On the Users page, click **Invite User** to open the invitation modal.
Fill in:
* **Email Address** - The email where the invitation will be sent
* **Role** - Choose **User** (standard access) or **Admin** (full access including settings management)
New users receive an invitation email to set up their account. They'll need to create a password before they can log in.
Click **Send Invitation**. The user appears in your team list with an "Inactive" status until they complete their account setup.
The invitation has been sent. The user will appear as "Active" once they set up their account and log in.
### Changing a user's role
Admins can change any user's role by clicking the role badge on their user card. Select the new role from the dropdown. Changes take effect immediately.
### Removing a user
Admins can remove users by clicking the delete icon on their user card. A confirmation dialog asks you to verify. Removing a user revokes their access to the organization but doesn't delete any content they created.
## Your profile
Click your name in the sidebar to access your profile, or navigate to **Profile** directly. Here you can:
* **Edit your name** (first and last name)
* **View your email** (read-only)
* **Change your password** via the change password drawer
* **See your account details** (role, status, member since, last login)
## Roles and permissions
| Capability | Admin | User |
| - | - | - |
| View and enrich products | Yes | Yes |
| Create and edit agents | Yes | Yes |
| Configure attributes | Yes | Yes |
| Run enrichment | Yes | Yes |
| Review and approve content | Yes | Yes |
| Manage integrations | Yes | No |
| Manage users (invite, remove, change roles) | Yes | No |
| Configure platform settings | Yes | No |
| Access API keys and service accounts | Yes | No |
| View usage metrics | Yes | Yes |
## Switching organizations
If you have access to multiple Cernel organizations, you can switch between them from the organization switcher in the sidebar. Your current organization is shown, and a dropdown lets you select a different one. Switching is instant and doesn't require logging out.
## Frequently asked questions
No. Only other admins can change your role. This prevents accidental loss of admin access. Every organization must have at least one admin.
The user immediately loses access to the organization. They can no longer log in or view any data. Content they created (agents, enrichment results, configurations) is not deleted.
Email addresses are set during account creation and cannot be changed through the profile page. Contact support if you need to update your email.
There is no limit on the number of users you can invite to your organization. Invite as many team members as you need.
## What's next
Explore all platform settings available to admins.
Share this page with new team members to help them get started.
# Connecting Shopify
Source: https://docs.cernel.com/get-started/connecting-shopify
Connect your Shopify store to Cernel for two-way product sync in minutes.
Cernel integrates directly with Shopify to pull your product catalog in and push enriched content back, including metafields. Once connected, your products sync automatically so your AI-generated content flows straight to your store.
## How it works
The Shopify integration creates a two-way connection between your store and Cernel. When you connect, Cernel imports your full product catalog (names, images, variants, and existing descriptions). After you enrich products with AI-generated content, you can sync the results back to Shopify as product fields or custom metafields.
### Why you would use this
Your products flow directly from Shopify into Cernel. No CSV exports, no copy-paste, no data gaps.
AI-generated descriptions, meta titles, and attribute values sync back to Shopify, including custom metafields for structured data your theme can display.
**Before you start:** You'll need admin access to your Shopify store and a Cernel account. The connection uses Shopify's official OAuth flow, so there are no API keys to manage manually.
The integration adopts your store's languages when it connects, and its default language is the store's default language (see **Settings > Languages** in your Shopify admin). Create your Cernel organization with the same primary language as the store's default; Cernel warns you when the two differ.
## Step-by-step guide
In Cernel, go to **Settings** in the sidebar, then select **Organization > Integrations**.
Click **Add Integration**. In the integration selection modal, choose **Shopify**.
Enter your Shopify store domain (e.g., `your-store.myshopify.com`). Click **Connect** to begin the OAuth authorization flow.
Your domain is the `.myshopify.com` address, not your custom domain. You can find it in Shopify under **Settings > Domains**.
You'll be redirected to Shopify to authorize Cernel. Review the requested permissions and click **Install app**.
After authorizing, Cernel begins importing your products. You'll see a progress indicator showing the sync status. This may take a few minutes depending on your catalog size.
You've successfully connected your Shopify store. Once the sync completes, your products will appear in the Cernel **Catalog** and you can start enriching them with AI.
## Advanced configuration
After connecting, you can map Cernel attributes to Shopify product fields. Navigate to **Tools > Integrations**, click on your Shopify connection, and open **Property Mapping**.
The mapping interface shows your Cernel attributes on the left and available Shopify fields on the right. Draw connections between them to define how enriched content flows back to your store.
For structured data that doesn't map to standard Shopify fields (like materials or size guides), you can sync attributes as Shopify metafields. When configuring an attribute, enable **Sync to Shopify Metafields** and select the metafield namespace and key.
You don't need to pre-create the metafield definition in Shopify. If the namespace and key don't exist yet, Cernel creates the metafield definition in your Shopify store automatically when you set up the mapping. If a definition with that namespace and key already exists, Cernel uses it.
Metafields are useful for data your Shopify theme can render dynamically, like displaying material lists or care instructions on product pages.
You can configure how Cernel handles sync conflicts and update behavior under **Sync behavior configuration** in the integration settings. Options include choosing a sync mode that controls whether Cernel overwrites existing Shopify data or only fills in empty fields.
Changes synced to Shopify are live. Always use the **Review & Approve** workflow in Cernel before pushing enriched content to your store.
## Frequently asked questions
It depends on your catalog size. A store with a few hundred products typically imports in under a minute. Larger catalogs with thousands of products may take several minutes. You can close the modal and products will continue importing in the background.
First, check the integration status under **Tools > Integrations**. If the status shows the sync is still running, wait for it to complete. If the sync failed, try disconnecting and reconnecting the integration. Make sure you authorized all requested permissions in Shopify.
Yes. Go to **Tools > Integrations** and click **Add Integration** again to connect additional stores. Each store connection is managed independently.
Cernel requests read and write access to your product catalog, including product data, images, and metafields. These permissions are required for the two-way sync to work. Cernel does not access customer data, orders, or payment information.
Yes. Go to **Tools > Integrations**, find your Shopify connection, and remove it. Syncing stops, and no data is ever deleted from your Shopify store.
The removal dialog includes a **Delete imported products** option that is **on by default**: leaving it on permanently deletes the products imported through that integration from your Cernel catalog. Turn it off if you want to keep them, or simply disable the integration instead of removing it to stop syncing without touching your catalog. See [Removing an integration](/integrations/shopify) for details.
## What's next
See how Cernel automatically classifies your imported products into categories, and where to configure the attributes and agents that run on each branch of the tree.
Set up AI agents to generate descriptions, meta content, and structured attributes for your products.
# Core Concepts
Source: https://docs.cernel.com/get-started/core-concepts
Understand the key ideas behind Cernel before you start enriching products.
Cernel uses a few core concepts that work together: your products are organized into a **taxonomy** of categories, **attributes** define what data each product needs, and **AI agents** generate that data. Understanding how these pieces connect will help you get the most from the platform.
## The big picture
Here's how product data flows through Cernel:
1. **Products come in** from your connected integration (Shopify, CSV, Feed, or API)
2. **Cernel automatically classifies** each product into the right category in the Cernel Taxonomy
3. **Attributes are configured** on categories to define what data products need
4. **AI agents generate** attribute values, using your prompts, your brand context from Data Sources, and, where you've set it up, the output of upstream agents
5. **You review and approve** the generated content, or let it push automatically if you've turned approval off
6. **Enriched data syncs back** to your store or export channel
Each step builds on the previous one. The taxonomy drives what attributes exist, attributes drive what agents produce, and agents drive what content your customers see.
## Key concepts
### Cernel Taxonomy
The Cernel Taxonomy is a hierarchical category structure maintained by Cernel, like *Apparel & Accessories > Shoes > Running Shoes*. When you import products, Cernel automatically classifies each one into the right category, so you don't build or manage the taxonomy yourself. Every product ends up in a category.
Categories are the organizing principle for everything else in Cernel. When you add an attribute to a category, it automatically applies to all subcategories beneath it. This means you configure once at the right level and it flows down the tree.
Full guide to setting up and managing your Cernel Taxonomy.
### Attributes
Attributes are the data fields that AI fills in for your products: descriptions, meta titles, materials, colors, sizing, and more. You configure attributes on categories in your taxonomy, and they automatically apply to all subcategories.
Cernel supports seven attribute types:
| Type | What it produces | Example |
| - | - | - |
| **Text** | Plain text content | Product descriptions, meta titles |
| **HTML** | Rich formatted content | Long descriptions with headings and lists |
| **Single Select** | One value from a list | Gender: Male / Female / Unisex |
| **Multi Select** | Multiple values from a list | Materials: Cotton, Polyester, Elastane |
| **External Data** | Data from an external source | GTIN matching |
| **Media** | Image content | AI-generated product images |
| **Picker** (Preview) | The best value or values selected from a set of candidates | The cleanest packshot out of all product images |
Deep dive into attribute types, configuration, and how they work across categories.
### AI Agents
An AI agent is a configured AI with a specific job: write a product description, extract materials, classify by gender, source product imagery, or anything else your catalog needs. You define what it should generate, the tone and style, any constraints, and the brand context it should draw on from your [Data Sources](/features/data-sources). You can describe your intent in plain language and let Cernel write the prompt for you, or write it yourself.
Before an agent goes live, you test it in a sandbox on real products with an agent chat that rewrites the prompt based on your feedback, plus version history so you can roll back. Agents can also depend on each other, letting one agent's output feed into the next so you can chain work (for example, a meta description agent that reads the product description agent's output). Cernel resolves dependencies and runs agents in the right order when you enrich.
Agents are independent from categories. Create one "Product Description" agent and link it to the description attribute across your entire taxonomy. Update the agent's prompt and every category picks up the change.
Create agents, configure prompts, and run your first enrichment.
### Data Sources
Data Sources are your organization's context library. Store brand guidelines, product specifications, target audience descriptions, and other reference material that you want AI agents to use when generating content.
You create entries in **Tools > Data Sources** and reference them in agent prompts by typing `/`. The reference appears as a labeled **pill** in the prompt editor, making it easy to see which context is included. Update a Data Source once and every agent using it picks up the change.
### Enrichment and jobs
Enrichment is the process of running AI agents on your products to generate attribute values. You select products (individually or by category), choose which attributes to generate, and start a job. Cernel processes everything in the background and tracks progress on your Dashboard.
After a job completes, you review the results. Each generated value can be approved, edited, or rejected before it syncs to your connected integrations.
Review is optional. If you'd rather have enriched content push straight to your store without a manual approval step, turn off **Approve Before Push** in **Settings > Global > Platform**. Leave it on when you want a human check before anything goes live.
### Automations
Automations let you automatically enrich products as they arrive or change. Set up a rule by selecting a category, defining optional product filters, and choosing which attributes to generate. When a product matches the rule, enrichment runs automatically.
Automations run on both newly created products and existing products that are updated: when a matching product's data changes, the automation re-evaluates it and enriches it. To enrich a batch of unchanged products on demand, use manual enrichment from the products table instead.
## What's next
Import your product catalog so you have products to work with.
Walk through generating AI content for your first products.
# What is Cernel?
Source: https://docs.cernel.com/get-started/what-is-cernel
AI-powered product content enrichment for e-commerce teams who need better product data, faster.
Cernel is an AI-powered platform that automatically generates high-quality product content for your e-commerce catalog. Connect your product data, configure AI agents with your brand voice and guidelines, and generate descriptions, attributes, and media at scale, saving hours of manual content work while keeping every product on-brand.
## How it works
Cernel sits between your product data source (like Shopify) and the enriched content your customers see. You import your product catalog and Cernel automatically classifies every product into its Cernel Taxonomy, so your catalog is organized without any manual setup. From there, you use AI agents to generate content for each product: descriptions, materials, colors, sizing, meta titles, and more.
Instead of writing each product description by hand, you set up agents once with your brand voice, product guidelines, and the specific content rules for each category. Then Cernel generates content across your entire catalog in minutes. You review, approve, and push the results back to your store.
### Why teams use Cernel
Hundreds or thousands of products need descriptions, meta data, and structured attributes. Cernel generates all of it from your existing product data and the context you provide, with no copywriting team required.
AI agents follow the same rules for every product. Your brand voice, terminology, and formatting stay consistent whether you have 50 products or 50,000.
Set up automations to enrich new products the moment they arrive. No bottleneck waiting for someone to write descriptions before a product goes live.
Every piece of generated content goes through a review and approval step. You stay in control of what gets published to your store.
## Core concepts
Understanding a few key ideas will help you get the most from Cernel.
The Cernel Taxonomy is a hierarchical category structure maintained by Cernel, for example, *Apparel & Accessories > Shoes > Running Shoes*. When you import products, Cernel automatically classifies each one into the right category, so you don't set up or maintain the taxonomy yourself. Each product's category determines which attributes and agents apply to it, making the taxonomy the backbone that drives every enrichment.
Attributes are the data fields that AI fills in for your products, like descriptions, meta titles, materials, and colors. Cernel supports seven attribute types: **Text**, **HTML**, **Single Select**, **Multi Select**, **External Data**, **Media**, and **Picker** (Preview). You configure attributes at the category level, and they automatically apply to all subcategories beneath it.
An AI agent is a configured AI that generates a specific piece of content for your products. You set up its prompt, tone, and references to your brand context once, test it live in a sandbox on real products, and link it to attributes across your taxonomy. Agents can also depend on each other, so one agent's output can feed into another, letting you chain work like "use the product description to write a meta description, then pick the best product image." Cernel runs every agent in the right order when you enrich.
Data Sources are your organization's context library: brand guidelines, product specifications, target audience descriptions, and other reference material. You create entries in **Tools > Data Sources** and reference them in agent prompts so the AI produces content that matches your specific needs.
Enrichment is the process of AI agents generating attribute values for your products. You select products, choose which attributes to generate, and start a job. Cernel tracks the progress and lets you review the results before publishing.
## What you can connect
Cernel works with your existing product data through four integration channels:
Two-way sync: pull your catalog in and push enriched content back to Shopify, including metafields.
Upload product data via spreadsheet and export enriched results for use anywhere.
Connect to product feeds for automated data ingestion from external sources.
Programmatic access for custom integrations and automated workflows.
# Your First Enrichment
Source: https://docs.cernel.com/get-started/your-first-enrichment
Generate AI-powered content for your products in minutes, from selecting products to reviewing results.
This guide walks you through running your first enrichment: selecting products, choosing attributes, generating content with AI, and reviewing the results. By the end, you'll have AI-generated product content ready to approve and push to your store.
If you're still iterating on the wording, tone, or behavior of an agent, do that work in the [Agent Sandbox](/features/sandbox) first, not in a full enrichment job. The sandbox runs your agent on real products, shows the AI's reasoning, and lets you refine the prompt through chat with undo/redo and version history. Enrichment is for applying a tested agent across your catalog, not for testing.
## Before you begin
To run an enrichment, you need:
1. **Products imported**: Connect an integration like [Shopify](/get-started/connecting-shopify) or import via CSV
2. **A taxonomy with attributes**: Products organized into categories with [attributes configured](/features/attributes)
3. **Agents linked to attributes**: At least one [AI agent](/features/ai-agents) linked to an attribute on your categories
If you're just getting started and Cernel has suggested attributes for your categories, you can apply those recommendations directly from the Dashboard.
## Step-by-step guide
In the sidebar under **Catalog**, expand the taxonomy tree and click on a category to view its products. You'll see a product table with columns for each configured attribute.
Use the checkboxes to select the products you want to enrich. You can select individual products or use the header checkbox to select all products in the current view.
Refine your agent in the [Agent Sandbox](/features/sandbox) before running enrichment. The sandbox is the right place to test prompt wording and iterate on output quality. Enrichment is for applying an agent you're already happy with. Once the sandbox results look good, you can comfortably enrich any number of products, from a single category to your whole catalog.
Click **Enrich Products** in the toolbar. The enrichment modal opens, showing the available attributes and enabled languages for your workspace.
Check the attributes you want AI to generate. You can search for specific attributes using the search box. Once you've selected your attributes, click **Start Enrichment**.
A confirmation notification appears: "Enrichment job started for X products with Y attributes."
Go to the **Dashboard** (click the Cernel logo or the Dashboard link in the sidebar). Your enrichment job appears as a card showing:
* The job name and type (e.g., "Product Enrichment | 8 products")
* A progress indicator showing how many products have been processed
* The status: **Pending**, **Running**, or **Completed**
* Product thumbnails and attribute badges
Once the job completes, click on the job card to open the review view. You'll see each product with its AI-generated values displayed alongside the original data.
For each attribute value, you can:
* **Approve**: accept the generated content as-is
* **Edit**: make changes before approving
* **Reject**: discard the generated content
You can also view the **Agent Reasoning** to understand why the AI generated specific content.
If the generated content doesn't match your expectations, open the agent and iterate in the [Agent Sandbox](/features/sandbox); that's where refinement belongs. Use the agent chat to rewrite the prompt, compare versions with undo/redo, and re-test on real products until the output is right. Only once the sandbox looks good should you re-run enrichment on your catalog.
You've completed your first enrichment. Approved content is ready to sync to your connected integrations. If you have **Approve Before Push** enabled in **Settings > Platform**, you'll need to approve each item before it pushes to your store.
## Frequently asked questions
Enrichment runs in the background, so you can keep working while it processes. Most products finish in under a minute. Text attributes are the quickest, while attributes that generate images or pull in external data can take a few minutes per product.
Adding more attributes to an enrichment does not make it slower. Cernel works on all selected attributes for a product at the same time, so the total wait is only as long as the slowest one.
Small batches typically complete in seconds. Larger runs across hundreds of products may take several minutes. If you have multiple enrichment jobs running at once, they may take a little longer as Cernel shares capacity fairly across your workspace. You can track progress from the Dashboard at any time.
Once an enrichment job has started, it runs to completion. If you realize the results aren't what you expected, you can reject the generated values and re-run enrichment after adjusting your agent prompts.
When enabled in **Settings > Platform**, this setting requires you to explicitly approve every generated value before it syncs to your connected integrations. This gives you full control over what gets published. Without it, approved values sync automatically.
Only attributes with a linked AI agent appear in the enrichment modal. If an attribute is missing, go to the category's attribute configuration and link an agent to it. See [AI Agents](/features/ai-agents) for how to create and link agents.
## What's next
Refine your agent prompts and create new agents for different content types.
Configure more attribute types and understand how they work across your taxonomy.
# CSV Import & Export
Source: https://docs.cernel.com/integrations/csv-import-export
Import product data from CSV files and export your enriched catalog using reusable templates.
CSV import and export let you bring product data into Cernel from a spreadsheet and send your enriched catalog back out as a CSV file. Map your columns once, see exactly what an import will change before it runs, and save reusable export layouts you can run on demand. It's the fastest way to work with product data that lives in a spreadsheet, a vendor file, or any system that reads and writes CSV.
## How it works
CSV import and export have their own home in the platform. In the sidebar, open **CSV** under **Tools**. The page has two tabs:
* **CSV Import**: bring product data into Cernel from a file. Cernel reads your file, suggests how each column maps to your attributes and product identifiers, and shows you a preview of what will be created or updated before anything happens.
* **CSV Export Templates**: reusable column layouts for exporting product data. You define a template once, then run exports from the Products page whenever you need a file.
When you start an import, Cernel first asks where your file is coming from. This sets the right expectations for how the file is matched to your catalog:
**Key concept: catalog vs. vendor imports.**
* **From catalog**: you manage products in one system and send a CSV to Cernel. Cernel enriches it and you get updates back in the same format. The file keeps the same column layout each time, so you map it once.
* **From vendor**: different suppliers send you files in different shapes. Cernel maps each vendor's columns to your attributes and brings them together into one catalog.
### Why you would use this
If your product data lives in a spreadsheet (from a supplier, an ERP system, or a manual catalog), you can import it directly without building a custom integration.
Define the columns and headers your downstream system expects once as a template, then run the same export again in two clicks whenever your data changes.
## Importing products from a CSV
Prefer to watch first? These short walkthroughs cover each import type, then the written steps follow below.
In the sidebar, open **CSV** under **Tools**. On the **CSV Import** tab, click **Import CSV**.
Cernel asks **Where is your CSV file coming from?** Pick the option that matches your workflow and click **Continue**:
* **From catalog**: you manage products in one place and round-trip a CSV through Cernel.
* **From vendor**: you receive differently-shaped files from multiple suppliers and want them combined into one catalog.
Drop your `.csv` file onto the upload area (or click to browse). Cernel fills the **Name** field with the file's name as soon as you select it, so you can go straight to **Import CSV File** to analyze it. Type your own name first if you want something more recognizable, and you can always rename the import later.
If Cernel can't detect how your file separates columns, it asks you to pick the delimiter: comma, semicolon, tab, or pipe. This is common with European exports that use semicolons.
Cernel analyzes your file and proposes a mapping for each column. Review the suggestions and adjust as needed:
* Map each column to an existing **attribute** or a **product identifier** (such as SKU or GTIN), or create a new one inline.
* Columns Cernel couldn't place are listed as **skipped**: add the ones you want with **Add to imported columns**.
* Where Cernel recommends a new attribute, accept it with one click.
Map at least one **product identifier** and a column to use as the **product title**: these are required to run the import. The identifier is how Cernel matches rows to existing products on every future import, so values must be stable and unique.
Pick a sync mode before you run:
* **Full Sync**: existing products are updated and new rows are created.
* **Update Only**: only existing products are updated; rows without a matching identifier are skipped, so nothing new is created.
When you're happy with the mapping, click **Save and review import**.
Cernel scans your file and shows a preview of exactly what will happen: how many products will be **created**, how many **updated**, and any new attributes or identifiers that will be created. When it looks right, click **Run import**.
If some rows in your file won't be imported, the preview shows a heads-up step first: **Some products won't be imported**, with the count of rows that will be dropped. A row is dropped when it has no identifier value, or when its identifier matches another row's. Tick **I understand, and want to continue anyway** and click **Continue** to move on to the create and update summary, or cancel and fix the file first.
Your import is running. Products appear in your catalog and are ready for enrichment as the import completes.
## Exporting your catalog as a CSV
Exporting works in two parts: you create a reusable **export template** that defines the columns and layout, then you run an export from the **Products** page using that template. You can also pick columns ad hoc at export time without a template.
### Create an export template
Open **CSV** under **Tools**, switch to the **CSV Export Templates** tab, and click **Create CSV Export Template**.
Set up the layout your downstream system expects:
* **Export Name**: a descriptive name for the template.
* **Quick setup (optional)**: upload a sample CSV and Cernel auto-maps columns whose names match your attributes or identifiers, so you don't have to build the layout by hand.
* **Column mapping**: choose which attributes and product identifiers to include, rename the output column headers, and drag to reorder.
Turn on **Export only values Cernel produced** to leave imported values out of the file, so it contains only what Cernel generated or you edited. This is useful for pushing updates back to a source system without overwriting it with its own data.
Click **Create Export Template**. The template now appears on the **CSV Export Templates** tab and is available whenever you export from the Products page.
Your export template is saved and reusable. Edit it any time, or duplicate it as a starting point for a similar layout.
### Run an export from the Products page
Open a category in the **Products** sidebar. The export honors your current filters and selection: tick specific rows, or leave the selection to export everything that matches your filters.
From the products toolbar, choose **Export to CSV**. On the **Templates** tab, select one of your saved export templates to load its columns. You can still adjust the columns before exporting.
Set the file basics and download:
* **File name**: defaults to the current category; the `.csv` suffix is added automatically.
* **Export language**: pick one enabled language. The primary language is marked **(Primary)**.
* **Delimiter** and **Include header row**: control the file format.
Click **Export CSV**. A live counter shows **Exported N products** as the file streams, then it downloads to your browser.
Your CSV is downloaded with the columns and order you configured. The modal stays open so you can run another export with different settings.
## Advanced configuration
You don't have to use a template. In the **Export to CSV** modal, use the other tabs to assemble columns directly:
* **Attributes**: all attribute values, split into category and product attributes. Search to filter, drag to reorder, and edit the output header per column.
* **Identifiers**: SKU, GTIN, MPN, and any custom identifier types.
* **Product fields** are the built-in properties: **Title**, **Product ID**, **Parent ID**, and **Parent Identifier**.
* **Product children**: set **Min** and **Max** child levels to expand matched products into their variants. Leaving **Max** empty includes all descendants.
* **Integrations**: per-integration properties (for example Shopify metafields), shown when at least one integration is connected.
To refresh products, open the import from the **CSV Import** tab and upload a new file. The sync mode decides whether Cernel creates new products and updates existing ones (**Full Sync**) or only updates existing ones (**Update Only**). Keep the same columns in the same order as the original file so the saved mapping still applies.
Reuse a configuration you've already proven instead of rebuilding it:
* **Use an existing import as a template** with the row's **Use as template for new import** action. Cernel starts a new import and matches your uploaded file's columns to the original by name: columns that match keep their original mapping, and columns with no match start unmapped in **Skipped columns**, ready for you to map. The new file no longer has to carry the exact same columns in the same order, so you can reuse a proven setup even when a vendor sends a slightly different file. Nothing is saved until you run the import. (Imports created before April 1, 2026 can't be used as a template; start a new import instead.)
* **Duplicate an export template** to create a new template with the same columns, mappings, and settings. The copy opens ready to edit, with the name pre-filled as " copy".
On the Products page you can filter by **CSV import source** to see only the products that came from a specific file. Use it to audit a vendor's upload or to confirm a fresh import landed as expected.
An import matches rows to existing products using the columns you mapped as **product identifiers**. If identifier values change between imports, Cernel can't recognize the same product and may create duplicates instead of updating. Keep identifier columns stable across imports.
## Frequently asked questions
Cernel imports `.csv` files, up to **200 MB per file**. The delimiter (comma, semicolon, tab, or pipe) is detected automatically; if it can't be detected, you pick it during upload. If your file is larger than 200 MB, split it into multiple smaller files and import them into the same integration.
Auto-detection works best on clean, standard CSVs. If columns come in misaligned or the import looks off, set the delimiter manually and make sure the file is saved as UTF-8.
This is a text-encoding issue, not a mapping mistake. Cernel reads **UTF-8** files (with or without a byte-order mark), and **UTF-16** or **UTF-32** files that begin with a byte-order mark. An Excel **CSV UTF-8** export imports as-is: its leading byte-order mark used to attach to the first header name so that column matched nothing and quietly dropped, and it now maps correctly.
If Cernel can't determine a file's encoding, it stops the import and asks you to re-save rather than importing scrambled text. In your spreadsheet application, choose **Save As**, then **CSV UTF-8**, and upload again. A plain **Unicode Text** export (UTF-16 without a byte-order mark) is one common case that gets refused this way.
You can run Cernel on CSV alone, with no Shopify, PIM, or API connection required. Import your catalog as a CSV, enrich it, and export the enriched data back out as a CSV. Many customers operate this way long-term. A live integration (Shopify, Struct, API) adds two-way sync and removes the manual upload/download step, but it's optional.
Choose **From catalog** when you manage products in one system and want a clean round trip: you send a file, Cernel enriches it, and you get updates back in the same layout. Choose **From vendor** when different suppliers send you files in different shapes and you want Cernel to map each one into a single, consistent catalog.
The import needs at least one column mapped as a **product identifier** and one column set as the **product title**. The review step also blocks if two columns map to the same attribute, or if an identifier row still needs a type. Resolve the highlighted rows and the **Run import** button enables.
If your file has more rows than the number of products created plus updated, the extra rows were dropped, and the preview flags this before you run: **Some products won't be imported**, with the count. A row is dropped for one of two reasons: it has no value in the column mapped as the **product identifier**, or its identifier value matches another row's, so Cernel can't tell the two rows apart.
Give every row a unique, non-empty identifier value and re-upload. Because a colliding identifier would otherwise let one row silently overwrite another, Cernel treats a column as an identifier only when its values are almost entirely unique; a column with too many repeated values won't be offered as an identifier during mapping.
Unrecognized columns are listed as **skipped** and aren't imported by default. Add the ones you want with **Add to imported columns**, mapping each to an existing attribute or creating a new one. Leave the rest skipped to ignore them.
Product images come in as **URLs**, not file uploads. Add a column that holds a public image URL for each product, then map it under the **Images** section during column mapping. Each value is imported as a product image in Cernel, and Cernel only treats a column as image URLs when its values are real links (they contain `http://` or `https://`).
If you have image files but no URLs yet, host them somewhere that gives a stable, direct link first (your Shopify store or another connected commerce platform, or a public storage bucket or CDN), then put those links in the column. A Google Drive "share" link won't work, because it opens a viewer page rather than pointing straight at the image file.
Save the column layout as a **CSV export template**, then select it on the **Templates** tab of the Export to CSV modal each time. Templates keep your headers and column order consistent for whatever system reads the file.
In the Export to CSV modal, open **Product children**. **Min** and **Max** control how many variant levels are included relative to the matched products. Setting **Min** to `0` and leaving **Max** empty includes the matched products plus every descendant; setting **Min** to `1` exports only children.
Not as variants. CSV import brings every row in as a standalone product. It matches rows to existing products by the columns you mapped as **product identifiers** and updates them, but it has no parent/child column, so it cannot create the variant relationships that link a variant to its master product. Variant structure comes from a connected integration instead: Shopify, Struct, and the [Public API](/integrations/public-api) build variants, and CSV import does not.
If a Shopify integration with variants is already set up, a CSV can still update those products and variants. As long as a CSV row shares a product identifier (SKU, GTIN, and so on) with an existing record, Cernel matches the row to that record and applies your mapped values, updating what is already there rather than creating a second, unlinked copy. To add or restructure variants, use Shopify or the Public API rather than a CSV.
Two or more columns share the same output header. A CSV can't carry duplicate headers meaningfully: the last value written wins, so earlier columns are lost. Rename one of the conflicting columns so each output header is unique.
When a Single Select or Multi Select agent produces no matching option, the value is empty, and it exports as an empty cell. It used to come out as the literal text `None`, which downstream systems could mistake for real content. If an older export shows `None` in Single Select or Multi Select columns, run the export again to get truly empty cells.
## What's next
See how Cernel classifies your imported products into categories, ready for enrichment.
Start generating AI content for your imported products.
# Product Feed
Source: https://docs.cernel.com/integrations/feed-configuration
Connect a product feed for automated data ingestion and export enriched data in Google Shopping format.
Cernel can ingest product data from product feeds (like Google Shopping feeds) and export enriched content back in feed format. Provide a feed URL or upload a feed file, and Cernel imports your products automatically.
## How it works
The Product Feed integration reads product data from an XML or CSV feed. You provide the feed source, Cernel ingests the products, and they appear in your Catalog ready for enrichment. You can also configure a feed export to push enriched data to Google Merchant Center or other feed consumers.
### Why you would use this
Point Cernel at your feed URL and products flow in automatically. Great for large catalogs managed through feed systems.
Generate a Google Shopping Feed with your AI-enriched product data - optimized descriptions, structured attributes, and complete metadata.
## Importing from a product feed
Go to **Tools > Integrations**, click **Add Integration**, and select **Product Feed**.
Set up the basic configuration:
* **Integration Name** - A descriptive name for this feed
* **Integration Language** - The language of the feed content
Choose the feed source:
* **URL** - Enter the URL of your product feed
* **Upload File** - Upload an XML, CSV, or text feed file
In **Advanced Settings**, choose how updates are handled:
* **Full Sync** - Replace all products each time the feed is processed
* **Update Only** - Only update existing products with changed data
Click **Create Integration**. Cernel begins ingesting your feed. You'll see a live progress view as products arrive.
Your feed is connected. Products appear in your Catalog as they're ingested and are ready for enrichment.
## Exporting as a Google Shopping Feed
In **Tools > Integrations**, click **Add Integration** and select **Export Data**. Choose **Google Shopping Feed**.
Set up the export:
* **Export Name** - A descriptive name
* **Export Language** - The language for the exported feed
* **Feed Title** - The title that appears in your Google Feed
* **Store Link** - Your store's base URL for product links
Once configured, trigger an export from the integration details. When complete, download the XML feed file.
You can also enable **Auto Push Export** to automatically regenerate the feed when product data changes.
Your enriched product data is available as a Google Shopping Feed for submission to Google Merchant Center or other feed consumers.
## Frequently asked questions
XML (Google Shopping format), CSV, and text feeds. The most common format is the Google Shopping Feed XML specification.
Yes. For an XML feed, Cernel reads Google's Product Data Specification: it looks for Google's own field names (`title`, `link`, `id`, `gtin`, `price`, the image fields, and so on) under Google's `g:` XML namespace. There is no column-mapping step for XML feeds the way there is for CSV, so Cernel does not read arbitrary or custom tag names. Any tag that isn't a recognized Google field is ignored rather than imported.
If your feed uses your own field names, or isn't a complete Google Shopping feed, you have two options that let you keep your own naming:
* **CSV import**, where you map each column to a Cernel attribute or identifier by hand. See [CSV Import & Export](/integrations/csv-import-export).
* **The [Public API](/integrations/public-api)**, for pushing fully arbitrary fields from an ERP or PIM.
A partial Google feed works for a first import, but it only brings in the products and fields that match the specification.
If you provide a feed URL, Cernel can re-fetch the feed to pick up product updates. The sync mode controls whether it replaces all products or only updates changed ones.
When enabled, changes to product data automatically trigger a new feed export. This keeps your Google Shopping Feed in sync with your enriched content without manual intervention.
The Google Shopping Feed only emits fields that are part of Google's Product Data Specification (such as `title`, `description`, `brand`, `gtin`, `price`, and the image fields). If you map a Cernel attribute that isn't a recognized Google field (for example a custom "Sneaker Style" attribute), it is silently dropped from the feed rather than added as a new column.
To carry your own values into the feed, map them to one of Google's five **custom label** fields, `custom_label_0` through `custom_label_4`, which accept arbitrary text (commonly used for campaign segmentation in Google Ads). If you need to send fully arbitrary fields to another system, use the [Public API](/integrations/public-api) instead of the Google feed.
## What's next
See how Cernel automatically classifies your feed products into categories, ready for targeted enrichment.
Set up agents to enrich your feed products with AI-generated content.
# Public API
Source: https://docs.cernel.com/integrations/public-api
Push product data to Cernel over REST and pull enriched content back by polling the changes endpoint.
The Public API lets you programmatically push product data to Cernel and pull enriched content back as it's generated. Use it for custom integrations, automated pipelines, or any workflow that needs to interact with Cernel beyond the standard integrations.
## How it works
After creating an API integration, you authenticate requests with an API key, managed under **Settings > Developer > API**. Push product data to Cernel's REST endpoints, and your products appear in the Catalog ready for enrichment. Once Cernel has enriched them, poll the changes endpoint to pull the results back into your own systems.
### Why you would use this
Connect Cernel to any system that can make HTTP requests - your ERP, PIM, custom tools, or internal workflows.
Poll the changes endpoint to pull AI-generated content and product updates back into your ERP, PIM, or storefront on your own schedule.
## Setting up the API integration
Go to **Tools > Integrations**, click **Add Integration**, and select **API Integration**.
Configure the basics:
* **Integration Name** - A descriptive name
* **Integration Languages** - The languages this integration pushes and pulls product data in. You can pick one language or several: the first one you add is marked **Primary** and is used as the fallback when a property is pushed without a language. Open **Edit Languages** later from the integration detail panel to change the list.
* **Product Identifier Field** - The field name used as the unique identifier (e.g., `id`, `sku`)
* **Product Title Field** - The field name used as the product title (e.g., `title`, `name`)
Properties you push can carry a `locale` field: Cernel stores each localized value separately and surfaces it for the matching language. Properties pushed without a `locale` are stored against the integration's primary language.
Go to **Settings > Developer > API**. Keys are organized into **service accounts**, one per integration. Click **New service account**, name it after this integration, and it mints a first key. Cernel shows the full key once, right after it's created, so copy it then and store it somewhere safe.
Keep your API key secure. Anyone with the key can push data to your Cernel organization. To rotate a key without downtime, add a **New key** on the same service account, switch your integration to it, then revoke the old key. Revoking takes effect immediately.
For the full walkthrough of service accounts, keys, and rotation, see [Managing API keys with service accounts](/features/developer-tools#managing-api-keys-with-service-accounts).
Click **Visit Documentation** or go directly to the [API Reference](https://api.platform.cernel.com/api/v1/docs) to open the full API documentation. This covers all available endpoints, request formats, authentication, and response schemas.
Your API integration is ready. Use your token to authenticate requests and start pushing product data to Cernel.
## Building a custom product pipeline
If your products come from an ERP, PIM, custom database, or supplier feed, you can build a fully automated pipeline: push products in via the API, enrich them with AI using [Automations](/features/automations), and get the results back programmatically.
```
Your System → API (create products) → Cernel → Automation → AI Enrichment
↓
Your System ← Changes endpoint (polling) ← Enriched Content ← Review & Approve
```
### Pushing products
Use the create products endpoint to push product data from your system:
```
POST /api/v1/integrations:api/{integration_id}/products
```
You can send up to 100 products per request. Products are matched by their identifier field; if a product with the same ID already exists, it's updated instead of duplicated.
### Creating variant structure
Cernel models variants as a parent product with child products beneath it, for example a master style that splits into colours, and a colour that splits further into sizes. This is the one relationship a [CSV import](/integrations/csv-import-export) can't build, since a CSV row has no parent column, so push variant structure through the API (or a Shopify or Struct integration) instead.
To build the structure through the API:
* **Link each variant to its parent** with `parent_identifier`, set to the parent's own identifier. A variant can itself be a parent, so a colour that splits into sizes is a variant of the master and a parent to its own size variants.
* **Declare the variant axis on the parent** with `child_bound_attributes`: the attributes whose values make each child distinct, such as Size or Colour.
* **Carry the axis values on each variant** with `defining_properties`: the values for the attributes the parent declared, for example `colorCode: 3007` and `color: NAVY` for one colour variant.
Setting `parent_identifier` alone is enough to nest a product under its parent. Without any axis values, though, the child has no variant axis to sit on, so nothing distinguishes it from its siblings the way a Size or Colour would. The FAQ below covers what you get with, and without, those values.
### Patching products (partial updates)
Use the patch endpoint when you only need to change a few properties on a product, without re-pushing the full payload:
```
PATCH /api/v1/integrations:api/{integration_id}/products
```
The patch endpoint accepts an array of operations. Each operation locates a product either by `product_id` (Cernel's ID) **or** by `identifier` (your system's identifier, exactly one of the two), then sets, removes, or appends localized property values. Each item in the batch is applied as its own transaction, so a bad operation only fails that one item, not the whole batch.
Use this when you want to update a single field (e.g., a price change) on thousands of products without re-sending every property you've already pushed.
### Listing products
Use the list products endpoint to fetch products that already exist on the integration, with filters:
```
GET /api/v1/integrations:api/{integration_id}/products
```
You can filter by identifier (useful for looking up whether a product is already in Cernel before deciding whether to create or patch) and optionally include child products in the response.
### Getting enriched data back
Poll the changes endpoint to get a chronological list of enrichment updates:
```
GET /api/v1/integrations:api/{integration_id}/changes
```
Use the cursor-based pagination to track where you left off. Each response includes an offset you pass to the next request.
Polling on a schedule (for example, a nightly sync) is the pattern for batch pipelines. To keep downstream systems closer to real time, poll more frequently and use the offset so each poll only returns what changed since the last one.
### Reading a category (taxonomy classification) value
A category attribute, the result of taxonomy classification, comes back as a `struct` value. Because a product can belong to several categories at once, its `data` carries a `nodes` array with one entry per category:
```json theme={null}
{
"nodes": [
{
"path": ["Apparel & Accessories", "Clothing", "Shirts & Tops"],
"node_id": "0193af1c-8b2e-7c1f-9d3a-1f5e7b9c2d4e"
},
{
"path": ["Apparel & Accessories", "Clothing", "Activewear"],
"node_id": "6b1f0e42-2d77-4a19-9d21-8a3c5e0f7b64"
}
],
"taxonomy_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"taxonomy_name": "Cernel Taxonomy"
}
```
* `path` is the category's display path, and `node_id` is the category it resolved to.
* `taxonomy_id` and `taxonomy_name` describe the whole value. One value covers one taxonomy, so a product classified in two taxonomies returns one value per taxonomy.
* The entries carry equal weight. If you can store only one category, take the first.
Only a taxonomy set up to [place products in more than one category](/features/custom-taxonomies#placing-products-in-more-than-one-category) returns more than one entry. Every other taxonomy still uses this shape, with a single entry in the `nodes` array.
A category value that arrived as a path from your side, and that no classification has produced a value for yet, carries `node_id`, `taxonomy_id`, and `taxonomy_name` all `null`. The three fill in together when a classification replaces the value, so treat a null `node_id` as unclassified rather than as a state that resolves on its own.
**If you integrated before multi-category taxonomies:** classifications made back then carried their single category directly on the object, with no `nodes` array:
```json theme={null}
{
"path": ["Apparel & Accessories", "Clothing", "Shirts & Tops"],
"node_id": "0193af1c-8b2e-7c1f-9d3a-1f5e7b9c2d4e",
"taxonomy_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"taxonomy_name": "Cernel Taxonomy"
}
```
Those older values are never rewritten, so you keep receiving both shapes: the older one from products last classified before the change, and the newer one from every classification since. Check for `nodes`, read it when it is present, and otherwise read `path` and `node_id` from the object itself. The `value_type` descriptor always matches the shape of the `data` beside it.
### Tracking product completeness
When you poll the changes endpoint, add `include_summary=true` to attach a per-product **completeness summary** to each change. It answers "how far along is this product?" without a separate lookup:
```
GET /api/v1/integrations:api/{integration_id}/changes?include_summary=true
```
Each change then carries a `summary` object with:
* `num_attributes`: every attribute attached to the category the product is classified in, including ones this integration has no mapping for. When the product sits in one of your own taxonomies, the count is measured against that category; otherwise it falls back to the product's Cernel category.
* `num_attributes_with_agents`: how many of those attributes an AI agent can fill. The rest are only ever set by an upsert or a manual edit.
* `locale_summaries`: a `num_attributes_populated` count per locale, covering every language enabled on your organization. A language with nothing filled in yet reports zero rather than being absent. The attribute totals are the same for every locale, so the per-locale counts share one denominator and are directly comparable.
The summary describes the product as Cernel holds it, matching what you see in the dashboard. It measures against your own taxonomy when the product is classified in one, and falls back to the product's Cernel category otherwise. It is `null` only when the product is classified in neither, since there is then no attribute set to measure against.
`include_summary` reads each product's values across every locale, so it is heavier than a plain change poll and is off by default. Unlike `include_all_properties`, it does not lower the maximum `limit`, so you can keep polling at full page size.
### Listing the attributes a product requires
For a single product, you can list its required attributes directly instead of deriving them from a change summary:
```
GET /api/v1/products/{product_id}/attributes
```
This returns every attribute the product's categories require, and whether the product holds a value for each. A product can belong to several categories, in one taxonomy or across several, and it requires the combined set of attributes those categories ask for. The response is a flat `attributes` list, where each entry describes one required attribute:
* `attribute_id`, `attribute_name`: the attribute itself.
* `taxonomy_id`: the taxonomy the requirement was resolved in. When the same attribute is required in two taxonomies the product is classified in, it appears once per taxonomy.
* `resolved_anchor_id`: the category that set the attribute for this product. Attributes set at a parent category automatically apply to all its subcategories, so where several of the product's categories require it, this names the one that governs.
* `contributing_node_ids`: every category the product belongs to that requires the attribute. Read this for a per-category view.
* `is_completed`: whether the product holds a value for the attribute in any language.
**Turning the list into a completeness figure.** The endpoint returns the raw list rather than a percentage, so you choose the scope. Count the entries, count the ones where `is_completed` is true, and divide the second by the first:
* Whole product: use every entry.
* One taxonomy: keep only entries with that `taxonomy_id`.
* One category: keep only entries whose `contributing_node_ids` include that category.
An attribute required by two taxonomies counts once per taxonomy, so narrow to a single `taxonomy_id` first if you don't want it counted twice. If the product has no required attributes there is nothing to divide by, which means nothing is required, not that the product is 0% complete.
**Scoping the resolution.** Two optional query parameters narrow what gets resolved. `taxonomy_id` resolves within a single taxonomy only. `taxonomy_node_id` resolves within one category's subtree and excludes any category outside it; it requires `taxonomy_id`, since a subtree lives inside one taxonomy.
The changes summary (`include_summary=true`) gives aggregate counts across a whole poll, while this endpoint returns the per-attribute detail for one product: which attributes it requires and which are still empty. Use the summary to track progress in bulk, and this endpoint to see exactly what is missing on a given product.
### Example: ERP to Cernel to e-commerce platform
1. **Nightly export** from your ERP pushes new/updated products to Cernel via API
2. **Automation** enriches each product with descriptions, meta content, and materials
3. **Morning review:** your content team reviews results on the Dashboard and approves
4. **Changes endpoint:** your e-commerce platform polls for approved changes and publishes them
### Managing the product lifecycle
You have two options:
* **Full update**: push the complete product payload to `POST /products`. The identifier field matches against existing products; Cernel replaces the property values you send.
* **Partial update**: send a `PATCH /products` operation that only includes the properties you want to change. Locate the product by `product_id` or `identifier` (exactly one of the two), then set, remove, or append localized values. Each operation runs in its own transaction, so a single failure doesn't roll back the batch.
Updated product data can re-trigger automations if the product matches automation criteria.
When you change how a property is mapped, adjust an agent, or update an attribute, the products already in your integration keep their current values until they're processed again. To re-run your current property mappings across every product in the integration, without re-sending them through the API:
1. Open the integration from **Integrations** and click the **Settings** menu near the top of the detail page.
2. Choose **Reset Integration**.
3. Select **Reapply mappings** and confirm.
Reapplying mappings re-runs the current property mappings on your existing products. It's faster than a full restart because no source data is re-ingested: Cernel simply re-processes the products it already holds.
The other reset option, **Restart from scratch**, re-imports all products from an integration's source. API integrations receive products directly rather than importing from a source, so that option doesn't apply to them. Reapplying mappings is the equivalent operation for an API-driven catalog.
An API integration can be configured for any number of languages; see [Setting up the API integration](#setting-up-the-api-integration) for the **Integration Languages** picker.
When you push or patch product properties, each property can carry a `locale` field. Cernel stores each localized variant separately and exposes the matching language to enrichment, the product UI, and the `/changes` endpoint. Properties pushed without a `locale` are stored against the integration's **Primary** language.
This lets one API integration cover, for example, a Danish reference catalog with English and German translations alongside it, without setting up separate integrations per language.
Use the delete endpoint to remove products:
```
DELETE /api/v1/integrations:api/{integration_id}/products/{product_id}/delete
```
You can choose to fully delete the product or just unlink it from the integration while keeping it in Cernel.
The changes endpoint returns enrichment updates in chronological order. Use it to build an audit trail or sync enriched content to downstream systems.
Pass `include_all_properties=true` to get the full product snapshot with each change (useful for full syncs, but limited to 10 results per request). Pass `include_summary=true` to attach a completeness summary (attributes defined, AI-fillable, and populated per locale) to each change without lowering the page size. See [Tracking product completeness](#tracking-product-completeness).
## Frequently asked questions
The full API reference is available at [api.platform.cernel.com/api/v1/docs](https://api.platform.cernel.com/api/v1/docs), also accessible from the **API Docs** tab at the top of this site or from **Settings > Developer > API** in the app. It covers all endpoints, authentication, request/response formats, and error codes.
Go to **Settings > API** and click **New key**. A new token is generated immediately and the old one stops working. Update any systems using the old token.
Poll the changes endpoint: `GET /api/v1/integrations:api/{integration_id}/changes`. It returns enrichment updates in chronological order, and you use the offset it returns to pick up where you left off on the next poll. There is no push-style webhook delivery on the Public API, so retrieving results is always a poll from your side. See [Getting enriched data back](#getting-enriched-data-back).
Yes. Setting a product's `parent_identifier` is enough to make it a child of that parent: a variant-defining attribute isn't required for the link itself. Cernel accepts the product and nests it under the parent, so it appears among the parent's children rather than in the flat product list.
Without any variant-defining values, though, the child has no variant axis, so nothing distinguishes it from its siblings the way a Size or Colour would. Add `defining_properties` for the attributes the parent declared as `child_bound_attributes` when you want each variant identified by its own axis values. See [Creating variant structure](#creating-variant-structure).
Yes, through the Public API. Cernel has native integrations for [Shopify](/integrations/shopify) and [Struct](/integrations/struct), plus [CSV import and export](/integrations/csv-import-export). For any other platform, including Magento, you connect over the Public API: your side pushes products in, pulls the enriched results back by polling the [changes endpoint](#getting-enriched-data-back), and writes them into your platform's own API. That write into your platform is custom code on your side, since Cernel does not host it.
Unlike a CSV round trip, the API can model **variant (parent and child) structure**, so a catalog where the same product exists in several variants, for example one ring in three metals, is fully supported. Set each child's `parent_identifier` to nest it under its parent. See [Creating variant structure](#creating-variant-structure) and the [ERP to Cernel to e-commerce platform](#example-erp-to-cernel-to-e-commerce-platform) walkthrough, which is the same pattern any custom platform integration follows.
No. The API is for **product data and the enrichment pipeline**: pushing and updating products, polling for changes, and triggering enrichment through your automations. Configuration of **AI Agents, Data Sources, attributes, automations, and your taxonomy is done in the Cernel app**, not through the API. Set those up once in the platform, then let the API drive products through them.
## What's next
Browse the full API documentation: endpoints, schemas, authentication, and examples.
Once products are pushed via API, enrich them with AI-generated content.
Set up automations to automatically enrich products pushed via API.
# Shopify
Source: https://docs.cernel.com/integrations/shopify
Complete reference for the Cernel-Shopify integration: setup, property mapping, sync behavior, and metafields.
Cernel connects directly to your Shopify store for two-way product sync. Pull your full product catalog into Cernel, enrich it with AI, and push the results back to Shopify, including standard product fields and custom metafields.
For first-time setup instructions, see [Connecting Shopify](/get-started/connecting-shopify).
## How it works
The Shopify integration creates a live connection between your store and Cernel through Shopify's OAuth flow. Once authorized, Cernel imports your products (names, descriptions, images, variants, and metadata) and keeps the connection open for pushing enriched content back.
Unlike one-way integrations like CSV or Product Feed, Shopify supports **bidirectional sync**: data flows from Shopify into Cernel and from Cernel back to Shopify.
### Why you would use this
Pull products from Shopify and push enriched content back, including descriptions, meta titles, structured attributes, and metafields, without leaving Cernel.
No CSV exports, no feed URLs. Products sync through a direct API connection that stays active after setup.
## Integration overview
After connecting your store, the integration appears in **Tools > Integrations** with these properties:
| Field | Description |
| - | - |
| **Name** | The name you gave the integration during setup |
| **Type** | Shopify |
| **Direction** | Ingress & Egress (two-way) |
| **Languages** | The language(s) configured for this connection |
| **Active** | Whether the integration is currently enabled |
| **Status** | Current sync state (Idle, Syncing, or Error) |
Click **Settings** on your Shopify integration to access quick actions:
* **View Integration Details:** Open the full configuration panel
* **Integration Enabled:** Toggle the integration on or off without removing it
* **Reset Integration:** Reapply mappings, restart the import, or restart the export (see [Resetting the integration](#resetting-the-integration))
* **Remove Integration:** Disconnect the store entirely
## Integration details
The integration detail view shows the full state and configuration of your Shopify connection.
### Overview panel
The top section displays:
* **Integration ID:** Unique identifier (useful for API access)
* **Status:** Enabled or Disabled
* **Languages:** Which language(s) this integration covers
* **Created / Last Updated:** Timestamps for when the integration was set up and last modified
* **Auto Sync:** Whether Cernel automatically re-syncs products from Shopify on a schedule
* **Sync Mode:** How updates are applied (see [Sync behavior](#sync-behavior))
### Data import
The Data Import section shows the current state of the inbound sync:
* **Sync Status:** Idle (no sync running), Syncing (import in progress), or Error
* **Last Sync:** When the most recent import ran
* **Last Completion:** Status of the most recent completed sync
## Property mapping
Property mapping controls how data flows between Shopify fields and Cernel attributes. Open the mapping view from the integration detail panel.
The mapping interface displays three columns:
| Column | Description |
| - | - |
| **From Shopify** | Source fields from your Shopify store (e.g. `title`, `body_html`, `product_type`) |
| **Cernel Attributes** | The attributes in your Cernel catalog |
| **To Shopify** | Target fields for pushing enriched content back to Shopify |
Each row shows a connection between a source field, a Cernel attribute, and an optional output target. You can view mappings in **Graph** mode (visual connections) or **List** mode.
### Adding a mapping
Click **+ New Mapping** to create a new connection. You can:
* Map a Shopify source field to a Cernel attribute (inbound)
* Map a Cernel attribute to a Shopify target field (outbound)
* Map both directions for the same attribute (bidirectional)
Each Cernel attribute takes its value from a **single** source field: you can't map two or more Shopify fields into the same Cernel attribute (the mapping is rejected if you try). If you need to combine several Shopify fields into one value, map them to separate attributes and use an AI agent to compose the combined value, or merge them on the Shopify side before syncing.
### Removing a mapping
Click the **x** next to any source or target field to remove that side of the mapping. Removing a mapping does not delete any data already imported or synced.
Use the **Search mappings** field to quickly find a specific attribute when you have many mappings configured.
### Mapping from the Properties tab
The integration detail view has a **Properties** tab next to **Property Mapping**. It lists every property your Shopify store exposes, alongside the Cernel attributes and identifiers each one is already connected to.
To map a property without switching to the Property Mapping tab, click the **+** button on its row. This opens the mapping picker with that property preselected, so you can connect it to a Cernel attribute in one step. Use **Search properties** to find a specific field.
## Sync behavior
After setup, Cernel keeps your catalog up to date automatically. It continuously checks Shopify for changed products in the background, and updated products typically appear in Cernel within a minute. Only products that changed since the last sync are re-imported, so day-to-day syncs stay fast regardless of catalog size.
Archived Shopify products are not imported. Products and variants in every other status (active and draft) are.
Change detection works at the **product** level. A change made only to a variant, with no change to its parent product, is not picked up on its own. The variant's changes come through the next time the parent product itself changes in Shopify.
The Sync Mode setting controls how Cernel handles product updates from Shopify:
| Mode | Behavior |
| - | - |
| **Full Sync** | Replaces all product data each time a sync runs. Products removed from Shopify are removed from Cernel. |
| **Update Only** | Only updates existing products with changed data. Does not add or remove products. |
Full Sync overwrites product data in Cernel with the latest from Shopify. If you've made manual edits to imported fields in Cernel, those changes will be replaced on the next sync.
### Auto Sync
When Auto Sync is enabled, Cernel periodically re-imports products from Shopify to keep your catalog up to date. When disabled, syncs only happen when you trigger them manually from the integration detail panel.
## What data syncs
### From Shopify into Cernel
| Shopify data | How it imports |
| - | - |
| Product fields | Title, description, vendor, product type, tags, status, SEO title and SEO description, product category, product options, the product's online store URL, and its URL handle (the storefront slug) |
| Product images | As image values, including alt text |
| Variant fields | Title, SKU, barcode, price, inventory quantity, country of origin, the variant's option values, the variant image, the variant's Shopify ID, and the variant's online store URL (the storefront link with that variant preselected) |
| Metafields | Every value type: text, numbers, true/false, dates, URLs, money, measurements (weight, dimensions, volume, and similar, as a value together with its unit), ratings, rich text, and their list variants. Value types Cernel doesn't model natively import as plain text, so nothing is dropped |
| Reference metafields | Image file references import as images; references to other products (for example shop-the-look setups) import as IDs |
| Per-language values | Product fields and product and variant metafields import in every language configured on the integration, using the same translations that power Shopify Markets |
### From Cernel back to Shopify
| Cernel data | How it exports |
| - | - |
| Product fields | Title, description, meta title, and meta description push out of the box. Vendor, product type, and tags can also push once you enable the export side of their mapping |
| Generated images | Push as new product images, including their alt text |
| Metafields | Product and variant metafields, with the matching metafield definition created in Shopify automatically when it doesn't exist yet |
| Select values | Single Select and Multi Select attributes push to text metafields with predefined choices. When a Cernel value isn't in the choice list yet, Cernel adds it to the metafield definition for you |
| Per-language values | Each language pushes as the matching Shopify translation, so content lands in the languages (and Markets) configured on your store |
| Variant values | Variant metafields push with the same options as product metafields, including per-language values |
### Not yet supported
* **Videos and non-image files** are not synced in either direction; media support covers images.
* **Complex metafield types are import-only.** Money, measurements, ratings, and references to other products can be imported, but Cernel does not push values back as these Shopify types.
* **Updating only the alt text of an existing Shopify image.** Cernel sets alt text on the images it creates, but cannot edit the alt text of an image that already exists in Shopify.
* **Collections, bundles, and sibling products** are not managed by Cernel.
## Languages
The integration's languages are taken from your Shopify store when it connects, and its default language is the store's default language (see **Settings > Languages** in your Shopify admin). Enriched content flows to the languages configured on the integration: each language pushes as the matching Shopify translation.
Each connected store is its own integration with its own languages, so you can run several stores side by side and target an attribute at more than one store.
Create your Cernel organization with the same primary language as your store's default language. If the two differ, Cernel shows a warning on the integration's languages, and some behavior (for example media content, and creating new products from the integration alone) won't work as expected.
## Working with product variants
By default, Cernel syncs a Shopify product as a single record using the product's top-level data. If your catalog uses **product variants** in Shopify (for example, the same product in multiple sizes or colours), turn on **Variants** for the integration so Cernel imports each variant as its own variant record under the parent product.
You'll find the **Variants** control on the Shopify integration detail panel, alongside the other connection-level flags.
Go to **Tools > Integrations** and open the Shopify integration you want to update.
In the overview section, find the **Variants** label. If variants are not yet enabled, you'll see an **Enable** button. Click it.
Cernel asks you to confirm with **Enable variants?** and the message: *"This turns on variant processing for this Shopify integration. Once enabled, it cannot be turned off."* Click **Enable variants** to confirm.
The **Variants** label switches to an **Enabled** badge. Future Shopify syncs bring in variant data, and existing products gain variant records on the next sync.
Enabling variants is a one-way action: once on, it stays on for that integration. If you need to stop processing variants for a store, remove the integration and reconnect it without enabling variants. Plan the change at a moment when a fresh sync won't interrupt active enrichment work.
Variants only flow through if your Shopify products actually use variants. Products with a single, default variant continue to sync as a single record.
## Syncing to Shopify metafields
For structured data that doesn't map to standard Shopify product fields (like materials, care instructions, or size guides), you can sync Cernel attributes as **Shopify metafields**.
Metafields are custom key-value fields in Shopify. When you map a Cernel attribute to a metafield target, the enriched value is pushed to Shopify under the namespace and key you configure. Your Shopify theme can then render these metafields on product pages.
### Cernel creates the metafield definitions for you
You don't need to pre-create metafield definitions in Shopify before mapping them. When you map a Cernel attribute to a new metafield (using a `namespace.key` that doesn't yet exist in Shopify), Cernel creates the metafield definition in your Shopify store automatically, including the correct value type based on your Cernel attribute configuration.
If a metafield definition with the same namespace and key already exists in Shopify, Cernel uses the existing definition instead of creating a new one. If the existing definition has a different value type than the Cernel attribute, the mapping is rejected so you can resolve the mismatch (either by renaming the Cernel attribute, choosing a different namespace and key, or updating the existing Shopify metafield to match).
Metafield sync happens as part of the regular push to Shopify. There is no separate sync process for metafields.
## Pushing enriched content to Shopify
There is no manual export step. When a value is approved in [Review](/features/jobs-and-enrichment#reviewing-proposed-values) (or applies directly, because the job ran without review), Cernel pushes it to Shopify automatically in the background, typically within a minute. Values that were imported from Shopify are never echoed back; only content that was enriched or edited in Cernel is pushed.
The push updates the mapped output fields, both standard product fields and metafields. Changes are live in Shopify immediately after the sync completes.
If you clear a value in Cernel so the attribute becomes empty, the push **removes the matching metafield from the Shopify product** rather than writing a blank value. Shopify does not accept empty metafields. Clearing a value in just one language removes only that language's value in Shopify; the other languages are left untouched, and mapped values that still have content are unaffected.
Changes pushed to Shopify are live. Always review enriched content before approving a sync to avoid publishing unfinished or incorrect product data.
## Resetting the integration
Day-to-day syncing is automatic, so you rarely need to reset. When you do, open the **Settings** dropdown on the integration and choose **Reset Integration**. The dialog offers three actions:
* **Reapply mappings:** Re-run the current property mappings on the products already in Cernel. This is faster than a full restart because it does not re-fetch anything from Shopify, it just reapplies your latest mapping to the data you already have.
* **Restart import:** Re-import every product from Shopify. Processing time scales with catalog size and can take a while for large stores. Use this after a change that a normal sync would not pick up, such as bringing in a variant edit that never touched its parent product.
* **Restart export:** Send your enriched Cernel values to Shopify again. Use the **Send changes since** field to control the scope: leave it on **Everything** to re-push all mapped values, or pick a date to re-push only the values changed since the start of that day (in your timezone). This is useful if a push was interrupted or you want to force Shopify back into step with Cernel.
Resetting only affects the sync. It never deletes products from Shopify, and **Restart export** never sends values that were imported from Shopify back to the store, only content enriched or edited in Cernel.
## Frequently asked questions
Yes. Add a separate integration for each store under **Tools > Integrations**. Each connection is managed independently with its own property mappings and sync settings.
Yes. Cernel matches imported products by identifier across your whole organization, not just within one integration. When a second store brings in a product whose SKU or barcode matches a product already in Cernel, even with a different Shopify product ID, the two resolve to the same Cernel product instead of creating a duplicate. Each store keeps its own connection to that shared product, so both stay in sync with it. A product with no matching SKU or barcode comes in as a new product.
No. Enabling variants on a Shopify integration is a one-way action: the dialog warns you up front. If you need to stop processing variants for that store, remove the integration and reconnect it without enabling variants.
Cernel requests read and write access to your product catalog, including product data, images, and metafields. Cernel does not access customer data, orders, or payment information.
Cernel imports the online store URL only for products that are published to your **Online Store** sales channel in Shopify. A product that isn't published there has no storefront link yet, so it imports without a URL and picks one up on the next sync after you publish it. The same applies to the variant online store URL, which is the storefront link with that variant preselected.
Products already imported into Cernel remain in your catalog, but no new syncs run in either direction. Re-enable the integration to resume syncing.
No. Resetting only re-runs the sync in Cernel: **Restart import** re-fetches products from Shopify, **Reapply mappings** reuses the data already in Cernel, and **Restart export** re-pushes your enriched values. Your Shopify store is never modified by a reset. See [Resetting the integration](#resetting-the-integration).
Open the Settings dropdown for the integration and click **Remove Integration**. The connection to Shopify is removed and no further syncs run. Your Shopify store is never modified: no data is deleted from Shopify.
The removal dialog includes a **Delete imported products** option that is **turned on by default**. While it is on, removing the integration also permanently deletes the products that were imported through it from your Cernel catalog.
**Turn off "Delete imported products" if you want to keep your catalog in Cernel.** Because the option is enabled by default, removing an integration without changing it will permanently delete every product that was imported through that integration. This cannot be undone. If you only want to stop syncing, disable the integration instead of removing it.
On the next push, Cernel removes the corresponding metafield from the Shopify product instead of sending a blank value. Shopify rejects empty metafields with a "Value can't be blank" error. This keeps your store clean: emptying an attribute in Cernel takes the field off the product in Shopify. Clearing the value in a single language removes only that language's value in Shopify; the values in your other languages stay in place.
No. When you map a Cernel attribute to a metafield namespace and key that doesn't yet exist in Shopify, Cernel creates the metafield definition in Shopify for you with the correct value type. You only need to pick the namespace and key; Cernel handles the rest.
If a metafield definition with the same namespace and key already exists in your Shopify store, Cernel reuses it. If the existing definition has a different value type, the mapping is rejected so you can resolve the mismatch.
Cernel reads every metafield you map, across all of Shopify's value types:
* **Common types** (text, whole and decimal numbers, true/false, dates, URLs, and money) import directly into the mapped attribute.
* **Measurement types** (weight, dimensions, volume, temperature, and the like) import as a numeric value together with its unit, so both are preserved.
* **Multi-value ("list") metafields** import as a list of values, including lists of measurements.
* **Image file references** import as images; **references to other products** import as IDs. Video and other file references are not imported.
* Any value type Cernel doesn't model natively imports as plain text, so the data is never dropped.
See [What data syncs](#what-data-syncs) for the full picture, including what Cernel can push back.
Cernel detects changes at the product level. If you change only a variant in Shopify, without any change to its parent product, the update is not picked up on its own. It comes through the next time the parent product changes. To bring it in sooner, make any edit to the parent product in Shopify, or use **Restart import** on the integration to re-import everything.
No. Cernel imports products and variants in every status except archived. If you archive a product that was previously synced, it stops receiving updates and is cleaned up from Cernel by a daily reconciliation, so allow up to 24 hours for it to disappear.
Yes. The integration's default language is your store's default language, so create your Cernel organization with the same primary language. If they differ, Cernel shows a warning on the integration's languages, media content can behave unexpectedly, and new products cannot be created from the integration alone.
Connecting a store never changes your organization's languages. Each Shopify integration adopts its own languages from its store, but the languages your organization actually works in are set in **Settings > Languages** and only change there. So a second store can bring in a language your organization hasn't enabled.
Cernel enriches and translates only into languages that are enabled on your organization. Until you enable that language in **Settings > Languages**, Cernel skips it: no content is generated or pushed to the store in that language. To have Cernel produce and sync content in the new store's language, enable it there first, then run enrichment. If the unenabled language is also the store's default, you'll see the primary-language warning covered above.
## What's next
See how Cernel automatically classifies imported Shopify products into categories, ready for targeted enrichment.
Configure agents to generate descriptions, meta content, and structured attributes for your products.
# Struct PIM
Source: https://docs.cernel.com/integrations/struct
Connect Cernel to your Struct PIM workspace for two-way product sync: pull your catalog, enrich it with AI, and push enriched content back.
Cernel connects directly to your Struct PIM workspace for two-way product sync. Pull your full product catalog into Cernel, enrich it with AI, and push the results back to Struct PIM, without leaving the platform.
## How it works
The Struct PIM integration creates a live connection between your PIM and Cernel using your Struct PIM Base URL and API Key. Once connected, Cernel imports your products and keeps the connection open for pushing enriched content back.
Like Shopify, Struct PIM is a **bidirectional** integration: data flows from Struct PIM into Cernel and from Cernel back to Struct PIM.
### Why you would use this
Pull products from Struct PIM and push enriched content (descriptions, structured attributes, media) back to the same PIM.
If you organise your catalog into dimensions, point Cernel at the exact dimension you want to enrich and ignore the rest.
**Key concept: Dimension.** Struct PIM uses dimensions to slice the same catalog by market, channel, or audience. Cernel can target one specific dimension when exporting data so enriched content lands exactly where you need it. You choose dimensions during setup and can change them later from the integration detail panel.
## Step-by-step guide
Go to **Tools > Integrations** and click **Add integration**. Cernel opens the **Connect your catalog** picker with every supported integration as a card.
Click **Configure** on the **Struct PIM** card. Cernel opens the configuration form.
Enter the details for your Struct PIM workspace:
* **Integration Name**: A descriptive name (for example, `My Struct PIM`).
* **Version**: Pick **Struct PIM v3** or **Struct PIM v4** depending on which version your workspace runs.
* **Base URL**: The base URL of your Struct PIM instance (for example, `https://your-struct-pim-instance.com`).
* **API Key**: A Struct PIM API key with read and write access to the products and dimensions you want Cernel to manage.
Cernel stores the API key only long enough to verify the connection and fetch dimensions. You'll need to re-enter the key later if you want to refresh the dimension list.
Toggle **Use dimensions** on if you want Cernel to target a specific dimension in Struct PIM when exporting data. With the toggle on, click **Fetch dimensions**: Cernel calls Struct PIM with the Base URL and API Key you entered and lists the available dimensions. Select one or more dimensions from the multi-select.
Leave **Use dimensions** off if you want Cernel to work against your workspace without scoping exports to a dimension.
Click **Create Integration**. Cernel connects to Struct PIM and starts importing your products.
Your Struct PIM integration appears under **Tools > Integrations**. Products begin arriving in your Catalog and are ready for enrichment.
## Installing Cernel from Struct PIM's App store
The steps above start from Cernel. You can also start from **Struct PIM's own App store** and install Cernel as an app there. This suits a Struct admin who wants to connect Cernel without first entering a Base URL and API key by hand.
**The app and the integration are the same connection, reached two ways.** Installing and connecting the Cernel app inside Struct PIM creates (or adopts) the same Struct PIM integration described on this page. The difference is that Struct hands Cernel the Base URL and API key automatically as part of the install, so there's nothing to copy across.
In Struct PIM, go to **Settings > Integration > Apps**, then open the **App store**.
Find **Cernel AI enrichment** and click **View app**. Struct lists what the app installs and the API permissions it grants Cernel (reading your catalog and creating assets), which is what lets Cernel import your products and push enriched images back as new assets.
Click **Install app**. Struct PIM installs it and opens the app's **Setup** tab.
A confirmation appears and the app shows under Struct's installed apps.
The **Setup** tab shows a **Client credentials** panel (a client ID and secret) that Struct generated for this app instance. These secure the connection between Struct and Cernel automatically. There's nothing here to copy into Cernel and nothing to configure.
Switch to the **Connect** tab and click **Connect Struct PIM**. This opens a Cernel window that already knows which Struct PIM instance is asking to connect.
If you're not signed in to Cernel, you'll see a short contact form instead (company name, website, your name, work email), because Cernel isn't self-serve sign-up. Leave your details and the Cernel team will reach out to set things up. If you already have a Cernel account, click **Sign in** on that same screen and log in.
Once you're signed in, Cernel shows which Struct PIM tenant is about to be connected to which Cernel organization. Check it, then click **Connect Struct PIM**.
**Only one Cernel organization can connect to a given Struct PIM instance.** Confirming here links that Struct tenant to whichever Cernel organization you're signed into, so make sure it's the right one before you continue.
The window shows **Struct PIM is connected**, and back in Struct PIM a new **Cernel** tab appears in the top navigation. Opening it loads the full Cernel app (Dashboard, Products, Agents, Automations, Integrations, and the rest) embedded inside Struct PIM.
If you'd already set up the Struct PIM integration from Cernel's side (the guide above) before installing the app, connecting adopts that existing integration rather than creating a second one against the same PIM, so you won't end up with duplicate products.
Removing the app from Struct PIM's App store does **not** disconnect or delete anything on the Cernel side. The integration keeps syncing until you disable or remove it from **Tools > Integrations** in Cernel.
## Integration overview
After connecting, the integration appears in **Tools > Integrations** with these properties:
| Field | Description |
| - | - |
| **Name** | The name you gave the integration during setup |
| **Type** | Struct PIM |
| **Direction** | Ingress & Egress (two-way) |
| **Languages** | The language(s) configured for this connection |
| **Active** | Whether the integration is currently enabled |
| **Status** | Current sync state (Idle, Syncing, or Error) |
Click **Settings** on your Struct PIM integration to access quick actions:
* **View Integration Details**: Open the full configuration panel
* **Integration Enabled**: Toggle the integration on or off without removing it
* **Reset Integration**: Reapply mappings, restart the import, or restart the export (see [Resetting the integration](#resetting-the-integration))
* **Remove Integration**: Disconnect the workspace entirely
## Changing the targeted dimensions later
You can change the dimensions Cernel targets at any time without recreating the integration. Open the integration detail panel and find the **Struct PIM Dimensions** section.
The Base URL is already filled in. Re-enter your Struct PIM API key: Cernel doesn't store the key after the initial fetch, so you'll need it again to refresh the dimension list.
Click **Fetch dimensions**. Cernel lists every dimension available in your workspace.
Select the dimensions you want to target, then click **Save dimensions**. Cernel confirms the change and resyncs so the new mappings apply.
Saving new dimensions triggers a resync of the integration. Plan the change for a moment when a fresh import won't interrupt active enrichment work.
## Property mapping
Like every Cernel integration, the Struct PIM connection has a **Property Mapping** view that controls how data flows between Struct PIM fields and Cernel attributes. Open the mapping view from the integration detail panel.
The mapping interface shows three columns: **From Struct PIM** (source fields), **Cernel Attributes** (your catalog), and **To Struct PIM** (output fields). Map a source field to a Cernel attribute to import data, and map a Cernel attribute to a target field to push enriched content back.
For more on mapping, see the field mapping section of the [Shopify integration guide](/integrations/shopify#property-mapping). The workflow is the same.
## Sync behavior
### Importing changes from Struct PIM
After setup, Cernel keeps your catalog up to date automatically. It continuously checks Struct PIM for changed products in the background, and updated products typically appear in Cernel within a minute. Only products that changed since the last check are re-imported, so day-to-day syncs stay fast regardless of catalog size.
Archived products are not imported. Products and variants in every other state are.
Change detection works at the **product** level. A change made only to a variant, with no change to its parent product, is not picked up on its own. The variant's changes come through the next time the parent product itself changes in Struct PIM.
### Pushing enriched content to Struct PIM
There is no manual export step. When a value is approved in [Review](/features/jobs-and-enrichment#reviewing-proposed-values) (or applies directly, because the job ran without review), Cernel pushes it to Struct PIM automatically in the background, typically within a minute. Both product-level and variant-level values are pushed. Values that were imported from Struct PIM are never echoed back; only content that was enriched or edited in Cernel is pushed.
Push-back works on both **Struct PIM v3** and **Struct PIM v4**. Struct PIM v3 reaches end of life at the end of 2026, so we recommend v4 for new connections.
## Resetting the integration
Day-to-day syncing is automatic, so you rarely need to reset. When you do, open the **Settings** dropdown on the integration and choose **Reset Integration**. The dialog offers three actions:
* **Reapply mappings**: Re-run the current property mappings on the products already in Cernel. This is faster than a full restart because it does not re-fetch anything from Struct PIM, it just reapplies your latest mapping to the data you already have.
* **Restart import**: Re-import every product from Struct PIM. Processing time scales with catalog size and can take a while for large workspaces. Use this after a change that a normal sync would not pick up, such as bringing in a variant edit that never touched its parent product.
* **Restart export**: Send your enriched Cernel values to Struct PIM again. Use the **Send changes since** field to control the scope: leave it on **Everything** to re-push all mapped values, or pick a date to re-push only the values changed since the start of that day (in your timezone). This is useful if a push was interrupted or you want to force Struct PIM back into step with Cernel.
Resetting only affects the sync. It never deletes products from Struct PIM, and **Restart export** never sends values that were imported from Struct PIM back to the workspace, only content enriched or edited in Cernel.
## What data syncs
### From Struct PIM into Cernel
| Struct PIM data | How it imports |
| - | - |
| Text and HTML attributes | As text, keeping plain and rich formatting apart |
| Number attributes | As numbers |
| Boolean attributes | As true/false values |
| List attributes | As lists of values |
| Global List values | As the display value of the referenced Global List entry |
| Images | As image URLs resolved from your Struct PIM assets, including alt text |
| Dimension-segmented data | Each segment's value imports as its own value |
| Language layers | Every language on the attribute imports, matched to the integration's languages |
| Product references | As IDs only; the referenced product's data is not pulled in |
| Complex attributes | As their structured (JSON) representation in a text value |
| Categorizations | The product's category placements import as a text attribute carrying the category names |
| Variants | Each Struct PIM variant imports as a variant record under its parent product |
### From Cernel back to Struct PIM
| Cernel data | How it exports |
| - | - |
| Text and HTML values | Written to the mapped Struct PIM attribute |
| Number and Boolean values | Written to the mapped Struct PIM number or boolean attribute |
| Lists | Written as list values |
| Global List values | Matched against the values already defined in your Global List |
| Images | Uploaded to Struct PIM as new assets and added alongside the images already on the product |
| Dimension-segmented values | Pushed into the dimensions selected on the integration |
| Per-language values | Each language pushes to the matching Struct PIM language |
| Variant values | Pushed to the variant, with the same coverage as product values |
Cernel cannot create new Global List values. A pushed value must match a value that already exists in the Global List; values that don't match are skipped for that product (the rest of the product's data still syncs), and the skip is recorded as an integration event.
### Not yet supported
* **Files and videos** are not synced in either direction; media support covers images.
* **Business Rules and Workflows**: Cernel writes attribute values only. It does not trigger, manage, or update Business Rules, Workflows, or workflow states in Struct PIM.
* **References other than variants are not resolved.** Product references import as IDs, and Publications, Catalogues, and external assets are not natively worked with.
## Languages
The integration's languages come from Struct PIM, and its **primary language** is the first language in your Struct PIM language list (see **Settings > Languages** in Struct PIM). Cernel adopts the primary language when the integration is created, and it cannot be changed afterwards.
Because the integration's primary language cannot be changed, your Cernel organization must be created with the same primary language as your Struct PIM workspace. Check your Struct PIM language list before setting up the organization.
## Frequently asked questions
Both Struct PIM v3 and Struct PIM v4. Pick the matching version during setup using the **Version** segmented control. Cernel uses the right API for the version you select, and both versions support importing your catalog and pushing enriched content back.
Struct PIM v3 reaches end of life at the end of 2026, so we recommend Struct PIM v4 for new connections.
Cernel detects changes at the product level. If you change only a variant in Struct PIM, without any change to its parent product, the update is not picked up on its own. It comes through the next time the parent product changes. To bring it in sooner, make any edit to the parent product in Struct PIM, or use **Restart import** on the integration to re-import everything.
No. Cernel's Struct PIM sync only pulls products that are new or changed since its last check, so a product you delete or archive in Struct PIM simply stops syncing. The copy already imported into Cernel stays in your catalog until you remove it there yourself. To take it out of Cernel, delete the product in Cernel directly, or remove the integration if you want to clear everything it imported.
No. Cernel only uses the values already defined in your Global List. When pushing a Global List attribute, the Cernel value must match an existing entry; values that don't match are skipped for that product and recorded as an integration event, while the rest of the product's data still syncs. Add the missing value in Struct PIM first, then re-approve the value in Cernel.
Generate the API key in your Struct PIM admin under the user or system-user permissions that have read and write access to the products and dimensions you want Cernel to manage. Cernel only uses this key to read your catalog and push enriched content back; it isn't stored after the initial fetch.
No. Dimensions are optional. Leave the **Use dimensions** toggle off to let Cernel work against your workspace without scoping exports to a dimension. Turn it on only if you want to target a specific dimension when pushing enriched data back to Struct PIM.
Yes. Open the integration detail panel and use the **Struct PIM Dimensions** section to re-enter your API key, fetch the current list of dimensions, reselect them, and save. Cernel resyncs the integration with the new dimension mappings.
Products already imported into Cernel remain in your catalog, but no new syncs run in either direction. Re-enable the integration to resume syncing.
No. Resetting only re-runs the sync in Cernel: **Restart import** re-fetches products from Struct PIM, **Reapply mappings** reuses the data already in Cernel, and **Restart export** re-pushes your enriched values. Your Struct PIM workspace is never modified by a reset. See [Resetting the integration](#resetting-the-integration).
Open the Settings dropdown for the integration and click **Remove Integration**. The connection to Struct PIM is removed and no further syncs run. Your Struct PIM workspace is never modified: no data is deleted from Struct.
The removal dialog includes a **Delete imported products** option that is **turned on by default**. While it is on, removing the integration also permanently deletes the products that were imported through it from your Cernel catalog.
**Turn off "Delete imported products" if you want to keep your catalog in Cernel.** Because the option is enabled by default, removing an integration without changing it will permanently delete every product that was imported through that integration. This cannot be undone. If you only want to stop syncing, disable the integration instead of removing it.
No. When you connect the app from inside Struct PIM, Struct hands Cernel the Base URL and API key automatically as part of the install, so there's nothing to copy in by hand. Use the manual **Add integration > Struct PIM** flow above if you'd rather enter those yourself.
Cernel recognizes the integration already pointed at that Struct PIM tenant and attaches the app connection to it instead of creating a new one. Your existing setup, mappings, and sync history are unaffected, and you won't get duplicate products.
No. Uninstalling the app removes only Struct's side of the connection. The Struct PIM integration in Cernel keeps running until you disable or remove it yourself from **Tools > Integrations**.
Installing the app always sets up the integration against **Struct PIM v4**. If your workspace runs Struct PIM v3, use the manual **Add integration > Struct PIM** flow above instead, where you select the **Struct PIM v3** version yourself.
## What's next
See how Cernel automatically classifies imported Struct PIM products into categories, ready for targeted enrichment.
Configure agents to generate descriptions, structured attributes, and media for your products.
# Changelog
Source: https://docs.cernel.com/release-notes/changelog
The latest updates, improvements, and fixes to the Cernel platform.
Stay up to date with what's new in Cernel. This page lists recent platform changes, new features, and improvements. For longer write-ups on major releases, see the [Blog](/blog/overview).
## More flexible value counts for Picker agents
A multi-value Picker agent now lets you choose how its value count is enforced with a **How many?** setting. **At most** and **All that fit** keep however many candidates fit, down to saving no value, so a thin candidate set no longer fails the whole enrichment. **At least**, **Exactly**, and **Between** still enforce a floor and report an error when the agent cannot reach it.
Picker is an early-access Preview feature whose behavior may change.
See [Output](/features/ai-agents#output).
## Skip parent product data during variant enrichment
An agent's settings now include a **Use parent product data** switch. Leave it on and variants keep drawing on values inherited from their parent products during enrichment. Turn it off and the agent enriches each variant from the variant's own values only, which is the right choice when your parent products hold placeholder or copied data that would otherwise leak into variant content.
See [Enrich variants from their own data only](/features/ai-agents#enrich-variants-from-their-own-data-only).
## Restart the export to a Shopify or Struct PIM integration
The **Reset Integration** dialog can now restart the export as well as the import. **Restart export** re-pushes your enriched Cernel values to Shopify or Struct PIM, so you can force the store or workspace back into step after an interrupted push. A **Send changes since** field scopes it: re-push everything, or only the values changed since a date you pick.
See [Resetting the integration](/integrations/shopify#resetting-the-integration) for Shopify and [Resetting the integration](/integrations/struct#resetting-the-integration) for Struct PIM.
## Bigger enrichment runs, tracked as one job
A single enrichment run now processes up to 50,000 products, raised from 5,000, so most catalogs enrich in one go instead of being split into batches. Each run is also dispatched as a single job, so you track one job per run on the **Jobs** page rather than one per 1,000 products. To enrich a catalog larger than 50,000 products, work through it in runs of 50,000 or fewer.
See [Running enrichment](/features/jobs-and-enrichment#running-enrichment).
## Quick filter from a column header
You can now narrow the product list by a single attribute without opening the filter builder. Open a column's menu from its header and use the **Quick filter** section to set a condition on just that attribute, with the same operators and value editors as the toolbar filter. A filtered column shows a funnel beside its name, and because both share one filter state, a quick filter also appears as a row in the filter builder and updates the table URL.
See [Quick filter from a column header](/features/jobs-and-enrichment#quick-filter-from-a-column-header).
## Picker agents can output an attribute, not just the title
A **Picker** agent that outputs **Text** and searches your product catalog can now choose what each pick carries. A new **Each pick outputs** setting offers the product's title (the default), a named attribute's value from the picked product, or whatever your search prompt asks for. This lets a Picker return, say, the material or the tagline of the product it chose, rather than only its title.
Picker is an early-access Preview feature whose behavior may change.
See [What a text Picker outputs](/features/ai-agents#what-a-text-picker-outputs).
## Approve without losing an unsaved edit
When you edit a proposed value inline on the **Review** surface and then approve it without saving, Cernel now asks first instead of quietly using the enriched value. A **You have unsaved changes** dialog lets you **Save and approve** to keep your edit, or **Approve without saving** to approve the value as the agent produced it. The edited card is also marked **Not saved yet** so it's easy to spot before you decide.
See [I edited a proposed value but didn't save it, then hit Approve. What happens?](/features/jobs-and-enrichment#frequently-asked-questions).
## Hide taxonomies you don't use
If you keep several taxonomies but only work in some of them, you can now hide the rest from your own view. On **Tools > Taxonomies**, open a taxonomy's actions menu and choose **Hide**, and it drops out of the taxonomy selector when you browse products by category. Hiding is per person, so it changes only your view and never your teammates', and it leaves every category and classification untouched. Choose **Show** to bring a taxonomy back.
See [Hiding a taxonomy from your view](/features/custom-taxonomies#advanced-configuration).
## Bulk edit shows the current value
When you open **Bulk edit values** on a selection, the editor now starts from the value those products already share, so you can see what you're about to replace instead of typing into an empty field. If the selected products hold different values, the field stays blank and says so, and what you enter still replaces every one of them.
See [Setting or clearing values by hand](/features/jobs-and-enrichment#setting-or-clearing-values-by-hand).
## Cover a whole branch from one automation
When you pick the attributes for an automation, the picker now also offers the attributes defined at categories below the one you chose, grouped under **From subcategories** and each labelled with the category it comes from. A single automation on a parent category can enrich attributes that differ from leaf to leaf, so you no longer need one automation per subcategory. Each product still only receives the attributes that apply to its own category.
See [Pick attributes to enrich](/features/automations#creating-an-automation).
## Import keeps HTML formatting
When you import a CSV, Cernel now recognizes cells that contain HTML markup, such as a description column with `` and `
` tags, and stores them as HTML. The product detail page and any connected storefront render the formatting instead of showing the raw tags. Cells without markup are still stored as plain text, so there's nothing to flag on your side.
See [My CSV has HTML in a column, like a formatted description. Will it render?](/integrations/csv-import-export#frequently-asked-questions).
## Know when a value changed, and who changed it
Open any attribute value on the product detail page and its details footer now shows **Updated** with the date and time the value was last written, for any origin (an enrichment, an import, or a manual edit). When the last change was made by hand, it also shows **Edited by** with that person's email. The timestamp covers the value as a whole, so it reads the same across every language. In the same update, a Single Select attribute that allows an empty value now offers a **No value** option in its editor, so you can clear the field back to unset.
See [See when a value was set and by whom](/features/product-detail#working-with-a-product).
## Saved views, shared across your team
Saved filters are now **saved views**, one click away from the new **Views** button in the product-list toolbar. A view remembers the whole list, its filters, search, sort, and columns, and it lives in your Cernel account rather than in the browser, so it's there when you sign in from another device. When you save a view you choose who can see it: keep it to **Only me**, or share it with **Everyone at your organization** so the whole team can apply and edit it. The **Review** surface gets its own saved views the same way.
See [Saving and sharing a view](/features/jobs-and-enrichment#saving-and-sharing-a-view).
## Know when CSV rows won't be imported
When you review a CSV import, Cernel now tells you up front if some rows won't make it in. If the file has rows it can't import, usually because they have no identifier value or an identifier that matches another row's, the preview shows a **Some products won't be imported** step with the count, and you acknowledge it before continuing to the create and update summary. Cernel also only treats a column as a product identifier when its values are almost entirely unique, so a non-unique column can't be mistaken for one.
See [Importing products from a CSV](/integrations/csv-import-export#importing-products-from-a-csv).
## Reading category values over the API
Documented the shape of a category (taxonomy classification) attribute in the public API. A category value carries a `nodes` array with one entry per category, so a product can now come back classified in more than one category at once. Values classified before multi-category taxonomies keep their older single-category shape and are never rewritten, so an API consumer should check for `nodes` and fall back to reading `path` and `node_id` from the object itself. If your integration reads classification values, update it to handle both shapes.
See [Reading a category (taxonomy classification) value](/integrations/public-api#reading-a-category-taxonomy-classification-value).
## API keys move to service accounts
The **Settings > Developer > API** page is now organized around **service accounts**: one account per integration, each holding its own keys. You can give an account several keys, revoke a single key without touching the others, and rotate keys with no downtime by adding a new one before revoking the old. Each key is shown in full only once, right after it's created. Renaming and deleting an account are admin-only, and a revoked key stays listed so a past call still has an explanation. This replaces the earlier model of one API key per organization; keys made before the change keep working and move to an account of their own the next time they're used.
See [Managing API keys with service accounts](/features/developer-tools#managing-api-keys-with-service-accounts).
## Language control per agent and per attribute
Two new ways to shape multi-language output beyond the organization-wide settings. Every agent now has a **Languages** tab with an instruction box for each enabled language, plus a toggle to keep or replace your organization's language instructions for that agent. And each attribute can pin which languages it's written in: turn on **Override language settings** in its Enrichment Settings to set every language to Generate, Translate, or Skip, overriding whatever an enrichment run asks for.
See [Fine-tuning language output](/features/languages#fine-tuning-language-output).
## Map a property without switching tabs
The **Properties** tab on an integration now has a **+** button on every property row. Click it to open the mapping picker with that property already selected, so you can connect a source field to a Cernel attribute without switching to the Property Mapping tab and back.
See [Mapping from the Properties tab](/integrations/shopify#mapping-from-the-properties-tab).
## Delete values in bulk
The bulk-select selection bar gains a **Delete** button, with **Del** or **Backspace** as a shortcut. It empties every selected value across all enabled languages in one step, after a confirmation, without opening the editor. A value cleared this way shows as a genuinely blank cell rather than the muted **No value** marker an agent leaves when it looked and found nothing.
See [Deleting values](/features/jobs-and-enrichment#deleting-values).
## CSV imports name themselves
Uploading a CSV no longer needs a name typed by hand. As soon as you pick a file, Cernel fills the **Name** field with the file's own name, so you can go straight to analyzing it. Anything you already typed is kept, and you can rename the import at any time.
See [Importing products from a CSV](/integrations/csv-import-export#importing-products-from-a-csv).
## Empty select values export as blank, not "None"
When a Single Select or Multi Select agent enriches an attribute with no matching option, that empty value now exports as an empty cell in your CSV instead of the literal text `None`. Downstream systems no longer read those cells as real content. Re-run an older export to clear any `None` text it produced.
See [Exporting your catalog as a CSV](/integrations/csv-import-export#exporting-your-catalog-as-a-csv).
## Reclassify products in bulk
You can now add a **Classification** column to the product table from **Column settings** and use bulk select and bulk edit to move many products to a different category at once, picking the target from the taxonomy tree. This replaces writing a per-product prompt or re-running classification when you just need to move a batch of products.
See [Moving products to a different category in bulk](/features/jobs-and-enrichment#moving-products-to-a-different-category-in-bulk).
## Tell an empty cell apart from an enriched blank
A blank attribute cell in the product table now shows which kind of blank it is. A truly empty cell means nothing has ever been written, while a muted **No value** means an agent ran and found nothing to write, carrying the same enrichment tint as any other AI-written value. Hover over a value to confirm its source.
See [Understanding value sources](/features/jobs-and-enrichment#understanding-value-sources).
## Filter by where a value came from
The product filter gains three ready-made conditions: **Is enriched**, **Is not enriched**, and **Is manually edited**. They match on where a value came from, not only whether one exists, so you can build enrichment batches even when a connected integration or CSV import already fills the same field. For example, **Is not enriched** on Description isolates the products AI hasn't touched yet, even if the feed already put text in that field.
See [Filtering the product list](/features/jobs-and-enrichment#filtering-the-product-list).
## Check one product's attributes over the API
A new endpoint lists the attributes a single product requires and whether each one holds a value: `GET /api/v1/products/{product_id}/attributes`. It returns every attribute the product's categories ask for, the category that set each one, and an `is_completed` flag per attribute, so a custom pipeline can see exactly what is still missing on a given product rather than an aggregate count. You can scope resolution to a single taxonomy or one category's subtree, and count the `is_completed` entries yourself to compute completeness at whatever scope you need.
See [Listing the attributes a product requires](/integrations/public-api#listing-the-attributes-a-product-requires).
## Multiple categories per product
When you create a custom taxonomy, you can now turn on **Allow multiple categories per product** so the AI can place each product in several categories at once instead of just one. A new **Multicategory Agent Settings** section in Classification Settings sets the most categories a product can get (1 to 5) and whether a category and one of its own subcategories can be held together. You can also tick or untick a product's categories by hand. This is a permanent choice made when the taxonomy is created, and single-category taxonomies, including the built-in Cernel Taxonomy, are unchanged.
See [Placing products in more than one category](/features/custom-taxonomies#placing-products-in-more-than-one-category).
## Reference a product's defining attributes in prompts
Agent prompts gain a new **Product Defining Attributes** reference in the `/` menu. It inserts the values that make the current product a distinct variant, such as its Size or Color, so you can tell an agent "write for this specific Large, Blue variant" without hardcoding attribute names. Cernel resolves these from wherever the variant axis was introduced in the product hierarchy, so a product nested under both a Size and a Color split surfaces both.
See [Using Data Sources in prompts](/features/data-sources#using-data-sources-in-prompts).
## Select a range of attributes at once
In the **Configure Enrichment** modal, you can now click one attribute, hold **Shift**, and click another to select every attribute between the two in one go. The range follows the list as displayed, so it respects whatever you've typed in the attribute search box. This makes picking a long run of attributes faster on categories with large attribute sets.
See [Running enrichment](/features/jobs-and-enrichment#running-enrichment).
## Bulk edit values from the product table
A new **Bulk select** mode turns the product table into a grid you can select across. Pick individual values, whole rows, or whole columns (drag or hold **Shift** to take a block), then set a shared value, clear the field, or send the whole selection to enrichment in one action. Manual edits ask you to confirm the count first, and a **Send for review** option lets the changes wait for approval instead of writing straight to your products. The same bulk selection works on the Review surface.
See [Editing values in bulk](/features/jobs-and-enrichment#editing-values-in-bulk).
## Track product completeness over the API
The product changes endpoint can now return a per-product **completeness summary**. Pass `include_summary=true` and each change carries how many attributes the product's category defines, how many of those an AI agent can fill, and how many are populated in each enabled language. This lets a custom pipeline show enrichment progress or gate a downstream publish without a separate lookup.
See [Tracking product completeness](/integrations/public-api#tracking-product-completeness).
## Rename a job
You can now rename any job from the **Jobs** page, in any status. Enrichment setup has several steps and the job title is easy to skip past, so the **Rename job** action in a job's **Actions** column lets you give a run a clearer name after it has started, or even once it has finished. The new name shows everywhere the job appears, including the header job-status list.
See [Renaming a job](/features/jobs-and-enrichment#renaming-a-job).
## Delete an automation from the list
You can now delete an automation directly from the **Automations** list through its row menu, without opening the automation first. Deleting is permanent and asks you to confirm, and the built-in Cernel Classification Automation can't be removed. Previously delete was only available on an automation's detail page.
See [List-view actions](/features/automations#list-view-actions).
## Shopify import adds store URLs, handles, and variant IDs
The Shopify integration now imports a few more identifiers alongside the existing product data. For each product you get its **online store URL** and its **URL handle** (the storefront slug), and for each variant you get the variant's **Shopify ID** and its **online store URL** (the storefront link with that variant preselected). The online store URL is populated for products published to your Online Store sales channel; products that aren't published there import without a URL until you publish them.
See [What data syncs](/integrations/shopify#from-shopify-into-cernel).
## CSV import handles more file encodings
CSV import now reads an Excel **CSV UTF-8** export exactly as saved. Previously the file's leading byte-order mark attached to the first column header, so that column matched nothing and silently dropped from the import. UTF-16 and UTF-32 files that start with a byte-order mark are also read correctly. When a file's encoding can't be determined, Cernel stops the import and asks you to re-save as **CSV UTF-8**, rather than importing scrambled text.
See [the CSV import FAQ](/integrations/csv-import-export#frequently-asked-questions).
## Variants show up in Review
Proposed values for product variants now appear on the **Review** surface whenever you select a category in the sidebar or apply a search or filter, alongside their parent products. Previously these variant values dropped out of view as soon as a category or filter was applied, leaving that enrichment work with no way to reach it. Each variant now lists as its own row and is approved, edited, or rejected like any product, and the header **select all** includes variant values when you decide a whole category or job at once.
See [the enrichment FAQ](/features/jobs-and-enrichment#frequently-asked-questions).
## Events tab on the product detail page
The product detail page gains an **Events** tab that lists the system activity Cernel has recorded for that specific product, such as when it was enriched, classified, or synced with an integration. Each entry is graded **Info** or **Error**, so you can filter by minimum severity to focus on problems, and expand a row for the full details. The feed is scoped to the product you're viewing, so it never mixes in another product's activity.
See [Working with a product](/features/product-detail#working-with-a-product).
## Enrichment tolerates unusable images
When one of a product's images can't be processed (it can't be fetched, isn't a valid image, or is unusually large), Cernel now skips just that image and generates the value from the product's remaining inputs, instead of failing the enrichment. A run only fails when no usable input is left. The agent also records a short note in its **Reasoning** when it leaves an image out, so you can tell exactly what was skipped and why.
See [the enrichment FAQ](/features/jobs-and-enrichment#frequently-asked-questions).
## Select all covers the whole review queue
Using **select all** on the Review surface now approves or rejects every in-review value that matches your current filters, including products beyond the ones loaded on screen. In a single-job review, it covers that job's entire pending set. Previously select all only reached the rows already loaded, so a large queue needed scrolling to the bottom before you could decide it in one action. You can still deselect individual products to leave them out, and the confirmation dialog notes how many you excluded.
See [Approving, rejecting, and dismissing](/features/jobs-and-enrichment#approving-rejecting-and-dismissing).
## Higher-quality translations
When a language is set to **Translate**, Cernel now follows the same length, tone, and format rules that the original prompt used when it generated the source value. A value written to a 150-word limit, for example, stays within that limit after translation instead of drifting. Every translated value also passes the same quality check Cernel applies to generated content, so output that comes back corrupted is rejected and retried automatically.
See [Languages](/features/languages#frequently-asked-questions).
## Search within child products
The product table's search and filters now reach child products, not just parents. Turn on the new **Search within children** toggle in the toolbar (available once you've entered a search or applied a filter) and matching variants appear under their parent product, with columns for the properties that set each one apart and the matched text highlighted. This makes it easy to find and act on individual variants, which previously the table's search and filters could not target.
See [the variant search FAQ](/features/jobs-and-enrichment#frequently-asked-questions).
## New "Does not contain" product filter
The product list gains a **Does not contain** operator, so you can filter to the products whose attribute value does *not* include a term you enter. It joins the existing operators (Equals, Contains, Has data, Has no data, and more) for building enrichment batches and finding the products you want to work on.
See [Filtering the product list](/features/jobs-and-enrichment#filtering-the-product-list).
## Enrichment includes variants by default
When you open the enrichment modal, **Product Scope** now starts on **Include child products**, so a master product and its variants are enriched together. Variant-heavy catalogs no longer need to change the scope on every run. You can still narrow it to the selected products only, or to only child products, per run.
See [Running enrichment](/features/jobs-and-enrichment#running-enrichment).
## Enrichment options for automations
Automations now offer the same controls as a manual enrichment run. Set the **Product Scope** to reach child products, toggle **Review** to decide whether results wait for approval or apply automatically, turn on **Only enrich missing fields** to backfill without overwriting, and use **Language Configuration** to generate, translate, or skip each language. The options are saved with the automation and applied to every run it triggers.
See [Enrichment options](/features/automations#enrichment-options).
## Fuller Shopify metafield import
The Shopify integration now imports every metafield value type. **Measurement** metafields (weight, dimensions, volume, temperature, and similar) import as a numeric value together with its unit, and their multi-value list variants come through as lists. Value types Cernel doesn't model natively import as plain text so nothing is dropped.
See [What data syncs](/integrations/shopify#what-data-syncs).
## A richer product detail page
Opening a product now gives you everything Cernel holds for it in one place. A **Completeness** ring shows how much of the category's attribute set is filled in, and the **Attributes** tab lists every value with its language coverage and its origin (enriched, manual, or imported). Edit a value inline, fill in a missing one, or open **Edit translations** to update every language at once. Each value keeps a version history you can restore from.
Products with variants get a **Variants** tab showing what makes each one distinct, and every connected integration gets its own tab with the raw properties it sends and how they map to your attributes.
See [Product detail](/features/product-detail) for the full guide.
## Manage your jobs more easily
You can now give an enrichment run a **Title** when you start it, so it's easy to find on the Jobs page later. Leave it blank and Cernel names the job for you from the attributes and category you picked. The Jobs page also gained a search box and filters (status, trigger, who started it, product, and date range) to narrow a long history, and you can now **cancel** a job that's still pending or running straight from its row.
See [The Jobs page](/features/jobs-and-enrichment#the-jobs-page).
## Reuse a CSV import as a template
You can now start a new CSV import from an existing one with **Use as template for new import**, even when the file you upload doesn't line up with the original column for column. Cernel matches columns by name: columns that match keep their original mapping, and anything new starts in **Skipped columns**, ready for you to map. A vendor changing or reordering their columns no longer blocks the reuse.
See [Importing products from a CSV](/integrations/csv-import-export#importing-products-from-a-csv).
## Jobs & Review
Enrichment now cleanly separates running a job from deciding what goes live. The **Jobs** page tracks every run (status, progress, and who started it) while the new **Review** surface is where you approve, edit, or reject the values your agents propose. Work through one product at a time or decide in bulk; open a job to review just its values, or switch to **Review** on the Products area to handle everything waiting for a decision. Each proposed value shows the prompt, the agent's reasoning, and the inputs behind it, so you can decide with full context.
See [Jobs & Review](/features/jobs-and-enrichment#reviewing-proposed-values) for the full guide, or read the story behind it on the [blog](/blog/jobs-and-review).
## Picker agent (Preview)
A new **Picker** agent type *selects* the best value (or values) from a set of candidates, instead of generating new content: the cleanest packshot, the strongest tagline, or the top few options. It runs in two phases: find candidates (from your prompt, your catalog, or your Data Sources), then pick from them by letting the AI rank against a rubric or by choosing at random.
Picker is an early-access **Preview** feature whose behavior may change.
See [Picker agent](/features/ai-agents#picker-agent).
## Redesigned CSV import and export
CSV import and export now have a dedicated home in the sidebar. Open **CSV** under **Tools**. Importing walks you through where your file comes from (a **catalog** you manage in one place, or **vendor** files that arrive in many shapes), suggests how each column maps to your attributes and product identifiers, and shows a preview of exactly what will be created or updated before the import runs.
Exporting is now template-based: save a reusable column layout as a **CSV export template**, then run it from the Products page whenever you need a file. You can still pick columns ad hoc at export time.
See [CSV Import & Export](/integrations/csv-import-export) for the full guide, or read the story behind the redesign on the [blog](/blog/an-improved-csv-experience).
## Reapply mappings for API integrations
After you change an attribute, an agent, or a property mapping, you can now re-run the current mappings across every product in an **API integration**. Open the integration's **Settings** menu and choose **Reset Integration → Reapply mappings**. Because API integrations receive products directly, there's nothing to re-import; reapplying mappings re-processes your existing products in place, much faster than a full restart.
See [Managing the product lifecycle](/integrations/public-api#managing-the-product-lifecycle).
## Choose the agent type up front
When you create an agent by describing what it should do, you can now optionally pin the type of content it generates (Text, HTML, Single Select, Multi Select, External Data, or Media) before Cernel writes the prompt. Leave it unset and Cernel detects the type from your description, or select one to lock it in when you already know what you need (for example, **Single Select** for a gender classifier).
See [Creating an agent](/features/ai-agents#creating-an-agent).
## Recolor image backgrounds on Media agents
Media agents that generate images can now replace the background of every image with one solid color, ideal for product and studio shots that need a clean, consistent backdrop. Open the Media agent's **Advanced Settings** tab and switch on **Recolor background** to set the target color, choose how shadows are handled (**Replace background**, **Preserve shadows**, or **Hybrid**), and pick the edge-processing engine.
See [Advanced configuration](/features/ai-agents#advanced-configuration).
## Per-language enrichment toggle
Each language's detail page (**Tools > Languages** → click a language) now has a **Use translation prompt for all language enrichments** toggle. While it's on - the default - Cernel automatically instructs your agents to write that language's enriched content *in* that language, so output always comes back correctly localised. Turn it off when you'd rather control the output language entirely through your own prompts.
See [Setting up languages](/features/languages#setting-up-languages).
## Alt text and file name instructions for Media agents
Media agents that generate images now have **Alt Text Instructions** and **File Name Instructions** fields in the **Advanced Settings** tab. Tell the AI how to describe each image (for accessibility and SEO) and how to name the generated file, and reference product data like the title or color by typing `/`. Leave a field empty to keep Cernel's defaults.
See [Media agents: image output, alt text, and file names](/features/ai-agents#advanced-configuration).
## Live streaming in the agent sandbox
The agent sandbox's **Review & Test** step now streams results live. Each product's card updates with a rotating status as the agent works and shows its output the moment that product finishes, so early results appear while the rest are still running, instead of everything landing at the end. Click **View live agent thinking** on a card to watch the agent's reasoning stream in real time; it stays available afterward, including for products that errored, so you can see what the agent did before a failure.
See [Run the agent](/features/sandbox#step-by-step-guide).
## Breadcrumb navigation in the prompt reference picker
The `/` reference picker in the agent prompt editor now shows a clickable breadcrumb trail at the top of each submenu (for example, `Data Sources > Models > ToV`), so you can jump back to a parent level instead of starting over. Search inside the picker is also space-tolerant: type `Specifications type 1` and it matches entries named `specifications_type_1`.
See [Referencing Data Sources in your prompt](/features/ai-agents#configure-the-prompt).
## Live counter on CSV exports
The **Export to CSV** modal now shows a live **Exported N products** count on the button while the file streams, replacing the previous spinner. Large exports finally show their progress instead of looking stuck.
See [Download the CSV](/integrations/csv-import-export#on-demand-export-from-the-products-table).
## Multiple languages per API integration
An API integration is no longer locked to a single language. Pick any number of languages when you create or edit the integration; the first one becomes **Primary** and acts as the fallback when a property is pushed without a language. Properties carry an optional `locale` field, and Cernel stores each localized variant separately and surfaces it to enrichment, the product UI, and the `/changes` endpoint.
The new `PATCH /products` and `GET /products` endpoints (see [Patching products](/integrations/public-api#patching-products-partial-updates) and [Listing products](/integrations/public-api#listing-products)) shipped alongside, so you can update individual localized values and look products up by identifier without re-sending full payloads.
See [Setting up the API integration](/integrations/public-api#setting-up-the-api-integration) and [Working with multiple languages](/integrations/public-api#working-with-multiple-languages).
## Only enrich missing fields
The enrichment modal has a new **Only enrich missing fields** toggle. Turn it on and the AI only generates values for attributes that are currently empty; existing values you've reviewed or hand-edited are left alone. Turn it off to re-enrich every selected attribute and overwrite current values. Use it to backfill a newly-added attribute across a large catalog without touching products you've already finished.
See [Running enrichment](/features/jobs-and-enrichment#running-enrichment).
## Sandbox stays put until you tell it to run
The agent sandbox no longer auto-runs when you open the **Review & Test** step, switch attribute types, or send a chat refinement. The 5 random products are still pre-selected for you, but Cernel waits for an explicit **Run** click before calling the LLM. Chat refinements still rewrite the prompt and save a new version in history. You click **Re-run** when you want to see the new output. This puts you in control of when the (potentially slow) enrichment pass actually fires.
## Cancel an in-progress sandbox run
While a sandbox run is in flight, the **Run** button becomes **Cancel**. Click it to abort the request immediately. Any results that already came back are kept, you get a *Run cancelled* toast, and the button returns to a startable state so you can adjust and try again. Especially useful for External Data agents in Agentic mode, where a single pass can take a couple of minutes.
See [Run the agent](/features/sandbox#step-by-step-guide).
## Agentic mode for External Data web research
External Data agents that pull text data from the web now have a **Mode** selector with two options:
* **Classic**: you define the exact search queries and trusted sources; Cernel searches them and combines the results.
* **Agentic**: Cernel plans and runs the searches itself, one product at a time, based on each product's details. You don't write search queries; you control scope through **Block these domains** and **Restrict to these domains**, and accuracy through **Match by** (a product identifier such as SKU or GTIN, or **Broad search** on the title).
Use Agentic mode when your products vary too much for one query template to cover: for example, sourcing technical specs across thousands of SKUs from manufacturers you don't enumerate up front. The **What to Extract** prompt (renamed from Synthesis Instructions) tells the agent what to pull out of the matched results.
Agentic external data also works end-to-end inside the [Agent Sandbox](/features/sandbox): you can preview a run, refine the prompt through chat, and re-run on the same products, just like every other agent type.
See [External Data agents: Classic vs Agentic mode](/features/ai-agents#advanced-configuration).
## Shopify product variants
Shopify integrations now have a **Variants** control on the integration detail panel. Click **Enable**, confirm the dialog, and Cernel starts importing each Shopify variant as its own variant record under the parent product. Enabling variants is a one-way action, so the dialog warns up front before you commit.
See [Working with product variants](/integrations/shopify#working-with-product-variants).
## Struct PIM is now a supported integration
Connect a Struct PIM workspace directly from **Tools > Integrations > Add integration**. Both Struct PIM v3 and v4 are supported, and you can optionally target a specific dimension when Cernel pushes enriched content back to Struct PIM.
See [Struct PIM integration](/integrations/struct).
## Redesigned Automations with multi-taxonomy support
Automations now live on dedicated pages, `/automations` for the list and `/automations/new` (or `/automations/{id}`) for the detail view, instead of a four-step modal. Each automation is configured through a single editable **sentence builder** that reads as one line: *"New and updated products in \[category] will automatically enrich \[attributes] narrowed to only products matching \[filters]"*.
Each automation is now scoped to one taxonomy explicitly, so you can run independent automations on different taxonomies for the same product. You can also pick **Unclassified products** as the target, which limits the automation to setting the taxonomy's classifying attribute, useful for getting unclassified products into the right category before further enrichment runs.
Run history has moved to a dedicated **Run history** tab on the automation detail page.
See [Creating an automation](/features/automations#creating-an-automation) and [Multi-taxonomy and Unclassified products](/features/automations#multi-taxonomy-and-unclassified-products).
## Free-text locale codes when adding a language
The **Add Language** modal in **Tools > Languages** now accepts any valid locale code as free text instead of picking from a fixed dropdown. Type a code like `en`, `da`, or a region-specific variant such as `sv_FI` or `pt_BR` and the platform validates it on submit. This unlocks locales that weren't in the previous list and gives you region-specific content where you need it.
See [Add a new language](/features/languages#setting-up-languages).
## On-demand CSV product export
Export products to CSV directly from the products table, no integration setup required. Pick any combination of attributes, identifiers, product fields, child products and integration data, drag to reorder columns, and customise headers before downloading.
See [On-demand export from the products table](/integrations/csv-import-export#on-demand-export-from-the-products-table).
## Dedicated Jobs page
Job tracking now lives on its own [Jobs page](/features/jobs-and-enrichment#the-jobs-page) with stats (Elements Run Total, Total Jobs, Avg Elements Per Job, Elements Run Today), a By user activity widget, and a filterable jobs table. The Dashboard keeps a Recent jobs widget for at-a-glance access.
## Automations, Data Sources, Integrations and Languages moved to Tools
These four areas now live under a new top-level **Tools** section in the main sidebar instead of inside Settings. Direct URLs are now `/automations`, `/data-sources`, `/integrations`, and `/languages`.
Settings continues to host Platform, Global Prompts, Usage, Users, API, and Webhooks. See the [Settings overview](/features/settings#tools-overview) for the new split.
## Event Log in Settings
A new **Events** tab in Settings surfaces recent system events and integration activity in one place. Filter by severity, domain, event kind, or resource type to drill into a specific run.
See [Event Log](/features/settings#event-log) for details.
## Documentation site is live
The Cernel Knowledge Platform at docs.cernel.com is now available. Browse feature guides, integration setup instructions, and use-case workflows to get the most out of Cernel.
* Full documentation for all platform features
* Step-by-step guides for Shopify, CSV, Feed, and API integrations
* Use-case workflows for hands-free enrichment, image sourcing, and more