# How coreAI uses entity types to distinguish products, documents, and contacts

Structured entities give coreAI the ability to distinguish a product from a PDF, a job listing, or a contact person — something a flat text import cannot do. When the source system sends the right type, the assistant can answer with the right context, and the same fields can be reused as filters later.

## Why structured entities beat a flat text import

If everything that lands in the knowledge base is raw text, the model has to guess whether a passage describes a product, a help article, or a person. The guess is often good enough to answer approximately, but not good enough to show a product image, a price, or correct contact details when the user actually asks for exactly that.

When the data is sent in as typed entities, coreAI knows what each row represents. A product card can be presented with price and stock status, a job listing can be kept out of a general FAQ answer, and a PDF can be referenced as documentation rather than marketing copy. The result is answers that match the question both in content and in form.

## The seven entity types coreAI understands

API v2 supports seven entity types, and each type has its own required fields:

- `products` — product catalog with name, product number, price, stock status, and images. Requires `name` and `productNumber`.
- `contents` — articles, help texts, and editorial marketing copy. Requires `name` and `longDescription`.
- `documents` — PDFs and other formal documentation.
- `events` — time-bound entries like events, webinars, and open days.
- `educations` — courses, study programs, and training tracks.
- `job_postings` — open job listings.
- `contacts` — people and roles, with email, phone, and place of work.

All types use the same upsert path against `/assistants/{assistantId}/sources/{contentImporterId}`, but the `attributes` block and the set of required fields varies. The `type` field decides how coreAI stores, indexes, and presents the entity in an answer.

## Properties make entities filterable

Each entity can have a `properties` block with short, structured values — `categoryName`, `publishedAt`, `market`, and the like. Use camelCase names and one of four types: `string`, `number`, `boolean`, or `date`. Properties are not meant for long text; they are metadata that describes the entity in a way that can be compared and sorted.

The same keys become filter fields in chat and search calls. coreAI supports these operators:

- `$eq` — exact equality, for example `market = "no"`
- `$gt`, `$gte`, `$lt`, `$lte` — comparisons on numbers and dates, for example `publishedAt >= "2026-01-01"`
- `$in` — the value is one of a given list, for example `categoryName in ["jackets", "trousers"]`

Filters go on the `filters` field in a chat or search call, and coreAI uses them to narrow which entities are candidates for an answer. That means you can fill the knowledge base broadly — every market, every category, every publication level — and still ask one specific call to answer from just one slice.

## When a filtered assistant is the right answer

A typical example: a company runs online stores in several countries with a shared product catalog, but each store should only show its own products and prices. Instead of building one assistant per market, you send all the products in with a `market` property (`"no"`, `"se"`, `"dk"`) and let the widget on each store pass `{ "market": { "$eq": "no" } }` in the chat call. The same pattern works for separating published from internal documents, or for letting a search show only events that have not yet taken place (`startDate` with `$gte` on today's date).

The robust integration is to type the entities correctly from the start, keep a small and deliberate set of properties, and use filters instead of duplicating assistants when one logical knowledge base needs to serve several contexts.