> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mixpeek.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# System Collections

> The mxp_ collections Mixpeek provisions per namespace, what each stores, and what you can do with it

Mixpeek maintains a set of system collections in every namespace, named with the `mxp_` prefix.
Each is created lazily. It appears the first time a matching event occurs, not at namespace setup.
You can filter, retrieve, cluster, and export them with the same API you use on any other collection.

The `_`, `mxp_` and `mvs_bucket_` prefixes are reserved. Creating a collection under any of them fails
with a 422 that names the reserved prefixes. `mvs_bucket_` belongs to the
[bucket-backed collections](#bucket-backed-collections) below.

***

## Bucket-backed collections

Every bucket has one more system collection, named after the bucket:
`mvs_bucket_<bucket_id>`. It holds one document per object in that bucket, so
the bucket's objects are searchable, filterable and alertable through the same
API as any other collection.

**You do not create it.** A bucket gets its collection when the bucket is
created, and a bucket that predates this gets it the first time a bucket id is
named where a collection id goes:

```bash theme={null}
curl -X POST "$API/v1/retrievers" \
  -H "Authorization: Bearer $KEY" -H "X-Namespace: $NS" \
  -d '{
    "retriever_name": "over-my-bucket",
    "collection_identifiers": ["bkt_dc47fce8"],
    "stages": [{"stage_name": "s1", "config": {
      "stage_id": "attribute_filter",
      "parameters": {"field": "object_id", "operator": "exists", "value": true}
    }}]
  }'
```

The response comes back with the resolved collection id, and the collection
appears in `collections/list` as `mvs_bucket_bkt_dc47fce8`. Studio hides these
collections behind their own filter chip, which you can clear. Referencing the
same bucket again reuses the collection. The `mvs_bucket_...` name works
anywhere the bucket id does.

**It is payload-only.** The collection declares no vector indexes, so it costs
no embedding and no GPU. `vector_indexes` on the collection is `[]`.

**It is written for you.** Creating, updating or deleting an object updates its
document in the same request. You cannot target the collection with a batch
action or create another collection under its name.

### What is on a backing document

| on the object | on its backing document |
| - | - |
| `object_id`, `bucket_id` | `object_id`, `bucket_id`, at the root |
| `key_prefix`, `blobs`, `source_details` | the same fields, at the same paths |
| `metadata.<your field>` | `metadata.<your field>`, filterable at the same path |
| `status`, `error`, `error_type` | `_internal.object.status`, `_internal.object.error`, `_internal.object.error_type` |
| (lineage) | `_internal.lineage.root_object_id` and `_internal.lineage.root_bucket_id` |

`object_id`, `key_prefix` and `_internal.object.status` carry keyword indexes,
so filters on them stay fast on large buckets.

<Warning>
  **A filter on a field the document does not carry returns an empty set, not an error.**
  HTTP 200 with zero documents reads as "the bucket is empty" rather than
  "that field does not exist". Use the paths in the table above. To check a field
  before you filter on it, read one document with
  `POST /v1/collections/{id}/documents/list` and look at the key.
</Warning>

Each object produces exactly one document, so for a bucket B:

```
objects(B) = documents(mvs_bucket_<B>)
```

Read the object count from `GET /v1/buckets/{bucket_id}` (`object_count`) and
the document count from `documents/list` with `include_total=true`. A failed
object keeps its document, with the failure under `_internal.object.status` and
`_internal.object.error`. Filter on `_internal.object.status` equal to `FAILED`
to list them; the total matches the bucket's `failed_object_count`.

### Filtering and alerting on a bucket

Everything that works on a collection works on the bucket:

```bash theme={null}
# every object in the bucket whose metadata says brand = acme
curl -X POST "$API/v1/collections/mvs_bucket_bkt_dc47fce8/documents/list?include_total=true" \
  -H "Authorization: Bearer $KEY" -H "X-Namespace: $NS" \
  -d '{"filters": {"AND": [
        {"field": "metadata.brand", "operator": "eq", "value": "acme"}]}}'
```

Point a retriever at it, put an alert on that retriever, or build a tier-1
collection sourced from it.

<Note>
  Deleting a bucket object cascades: the backing document and every document
  derived from it are removed with it.
</Note>

***

## What is writing today

Lazy creation means an absent collection is usually just an event you have not triggered. For some of these it means something else: nothing writes them yet.

<Warning>
  **Three of these have no writer reaching them today**, so they will not appear however long you wait.

  | Collection | Why it is empty |
  | - | - |
  | `mxp_batch_failures` | Written from the engine, which has no write path to collections |
  | `mxp_infra_metrics` | The scrape task is in no schedule |
  | `mxp_healing_events` | No production caller |

  Read the sections below as what each collection is for, not as something you can query now.
</Warning>

<Note>
  **Two are named differently on namespaces that predate the rename.** If you have existing data and the documented name returns nothing, look under the old one.

  | Documented | Older namespaces |
  | - | - |
  | `mxp_retriever_evaluations` | `mxp_evaluations` |
  | `mxp_compute_utilization` | `mxp_resources` |

  There is no alias, so the two names hold separate data.
</Note>

Writes are best-effort. A write that cannot reach the collection is dropped and logged rather than failing the request that triggered it, so a gap here never breaks the operation it describes.

***

## Retriever signal collections

These four collections record what your retrievers do. They back [learned fusion](/docs/relevance/learned-fusion)
and are the input to [evaluations](/docs/retrieval/evaluations).

### `mxp_retriever_interactions`

Stores every interaction a user reports on a search result: clicks, dwells, bookmarks, downloads.

**What you can do with it:**

* Study the signals the [Thompson-sampling bandit](/docs/relevance/learned-fusion) learns from, which
  shift retriever weights toward features your users engage with. The bandit aggregates its state
  from ClickHouse rather than from this collection, which is a best-effort mirror of the same
  interactions. Deleting rows here does not reset the bandit, and a dropped mirror write does not
  change ranking.
* Filter by `interaction_type` to measure click-through rate per retriever or per feature.
* Export to a reranker training set: cluster by `session_id`, then label by `interaction_type`.

<Info>
  This is the primary input to relevance tuning. A namespace with no interaction data
  falls back to equal-weight fusion across retriever stages.
</Info>

### `mxp_retriever_queries`

Stores every query submitted to your retrievers, with the query embedding.

**What you can do with it:**

* Cluster by query embedding to discover the most common search intents in your namespace.
* Filter on `results_count = 0` to find queries that return nothing — then decide whether to
  expand your extractor coverage or tune your retriever stages.
* Join with `mxp_retriever_executions` on `execution_id` to correlate query shape with latency.

### `mxp_retriever_executions`

Stores one document per retriever run, with status, latency, result count, and execution mode.

**What you can do with it:**

* Monitor retriever health: filter on `status = degraded` or `status = timeout` to surface
  failures without reading server logs.
* Track latency over time: retrieve by `retriever_id` and aggregate `duration_ms` with a
  rollup stage.
* Alert on spikes: wire an alert against this collection with a `duration_ms` threshold.

### `mxp_retriever_rollups`

Stores pre-aggregated health windows per retriever and per namespace.

**What you can do with it:**

* Build dashboards without running aggregation queries on the raw execution log.
* Use `scope = retriever` for per-retriever panels; use `scope = namespace` for namespace-wide health.
* Compare `window_start_ts` ranges to detect degradation trends across deployments.

<Note>
  Rows appear after the rollup sweep runs, which is every 15 minutes.

  `baseline_*` and `*_delta` stay null until the namespace has 24 hours of history
  (`SIGNALS_ROLLUP_BASELINE_HOURS`). The degradation comparison above needs that
  history, so a new namespace gets rows with those fields empty.
</Note>

***

## Evaluation and annotation collections

### `mxp_retriever_evaluations`

Stores the result of each evaluation run: nDCG, precision, recall, and status.

**What you can do with it:**

* Track retriever quality over time after tuning, configuration changes, or new extractors.
* Compare `evaluation_id` across runs on the same `dataset_id` to confirm an improvement is real.
* Fail a CI gate: query this collection after each deploy and assert nDCG did not drop.

### `mxp_document_annotations`

Stores every human label applied to a document, with the annotator and target document.

**What you can do with it:**

* Use as ground truth for [supervised relevance tuning](/docs/relevance/annotations): the evaluation
  pipeline reads this collection to score retriever output against your labels.
* Audit annotation coverage: filter by `retriever_id` to see which results have been rated.
* Train a reranker: export labels keyed on `target_document_id` as positive or negative signal.

***

## Platform event collections

### `mxp_platform_events`

Stores lifecycle events for resources in your namespace: buckets, collections, extractors created
or deleted.

**What you can do with it:**

* Trigger outbound webhooks on resource changes: any event written here fires your configured
  webhook URL automatically.
* Audit your namespace history: query by `event_type = collection_created` to see when pipelines
  were added.
* Detect unexpected deletes: alert when `event_type = bucket_deleted` appears.

### `mxp_change_events`

Stores an ordered, monotonically sequenced log of all resource changes in your namespace.

**What you can do with it:**

* Replay your namespace history: read from a known `seq` to catch up on what changed while a
  downstream system was offline.
* Build integrations: poll for `seq > last_seen` to drive a sync to an external system.
* Audit in sequence: unlike `mxp_platform_events`, this collection guarantees ordering by `seq`.

<Info>
  `mxp_platform_events` and `mxp_change_events` cover the same resource lifecycle, but differently.
  `mxp_platform_events` fires webhooks and is suitable for alerting. `mxp_change_events` is ordered
  and suitable for replay and synchronization.
</Info>

***

## Compute and infrastructure collections

### `mxp_compute_utilization`

Stores per-batch compute cost: documents processed, duration, and throughput.

**What you can do with it:**

* Get an email alert when throughput drops below 0.5 docs/sec or a batch runs longer than 1 hour.
  Mixpeek sends this automatically for anomalous batches.
* Filter by `measured_collection_id` to compare ingestion cost across your collections.
* Identify expensive extractors: join with `mxp_batch_failures` on `batch_id` to see whether
  high-cost batches also have high failure rates.

### `mxp_infra_metrics`

Stores infrastructure metric snapshots: CPU, memory, pod count, queue depth.

**What you can do with it:**

* Trigger scale-up alerts: Mixpeek fires an outbound webhook when `engine_pod_count` drops below
  your configured floor (`INFRA_MIN_ENGINE_PODS`).
* Retrieve historical metrics to understand whether a slow batch correlated with resource pressure.
* Filter by `source = prometheus` or `source = ray` to separate infrastructure metrics from
  local-dev estimates.

### `mxp_batch_failures`

Stores one document per object that failed extraction, with error type, extractor name, and retry
eligibility.

**What you can do with it:**

* Find which objects failed in a batch: filter by `batch_id` and read `error_type` and
  `error_message` to understand the cause without reading server logs.
* Identify systemic failures: filter by `collection_id` across batches to find extractors that
  fail consistently on a particular collection.
* Drive targeted retries: filter on `can_retry = true` and `retry_count < 3` to get the set
  worth re-submitting.

***

## Operational collections

### `mxp_webhook_deliveries`

Stores a delivery record for every webhook event your namespace generated: payload, status,
retry count, and last error.

**What you can do with it:**

* Verify delivery: filter by `event_id` to confirm a specific webhook fired and succeeded.
* Debug failures: filter on `status = failed` and read `last_error` to see what the endpoint
  returned.
* Monitor retry depth: filter on `retry_count >= 3` to find events stuck in the retry ladder
  before they reach the dead-letter queue.

<Warning>
  **A row records that a delivery was attempted, not how it went.** Today `status` is written as `pending`, `retry_count` as `0`, and `last_error` as empty, and nothing updates them afterwards.

  So the three uses above do not work yet. Filtering on `status = failed` or `retry_count >= 3` matches nothing, and a row does not confirm a webhook succeeded.
</Warning>

### `mxp_healing_events`

Stores every auto-repair action the platform took on your namespace: stalled job cancellations,
circuit breaker trips, batch repairs.

**What you can do with it:**

* Audit platform interventions: query by `affected_resource` to see what the platform touched
  and why.
* Correlate with batch failures: join on `batch_id` to see whether a batch failure was preceded
  by a healing action.
* Monitor recurrence: if `source = circuit_breaker` appears repeatedly for the same resource,
  that is a signal to investigate the upstream service.

### `mxp_alert_executions`

Stores one document per alert evaluation: which alert fired, the condition that was met, and
the severity.

**What you can do with it:**

* Review alert history: filter by `alert_id` to see every time an alert fired, without reading
  the alert configuration.
* Suppress noise: query for repeated `alert_id` occurrences in a short window to identify
  alerts that need threshold adjustment.
* Build alert analytics: cluster by `severity` and `retriever_id` to find which retrievers
  produce the most alerts.

<Warning>
  **A row is written when an alert is created, not when it fires.** `condition_met` is set to `true` on that row regardless, and nothing writes on a later firing.

  So this collection currently counts alerts you configured. Treat it as a record of alert creation until firing is wired up.
</Warning>

***

## Reference table

| Collection | Created when | Signal type |
| - | - | - |
| `mxp_retriever_interactions` | First interaction reported | `retriever_interaction` |
| `mxp_retriever_queries` | First retriever query runs | `retriever_query` |
| `mxp_retriever_executions` | First retriever execution | `retriever_execution` |
| `mxp_retriever_rollups` | First rollup computed | `retriever_rollup` |
| `mxp_retriever_evaluations` | First evaluation run | `retriever_evaluation` |
| `mxp_document_annotations` | First annotation created | `document_annotation` |
| `mxp_platform_events` | First resource lifecycle event | `platform_event` |
| `mxp_change_events` | First resource change | `change_event` |
| `mxp_compute_utilization` | First batch completes | `compute` |
| `mxp_infra_metrics` | First infra metric scraped | `infra_metric` |
| `mxp_batch_failures` | First extraction failure | `batch_failure` |
| `mxp_webhook_deliveries` | First webhook fires | `webhook_delivery` |
| `mxp_healing_events` | First auto-heal action | `healing_event` |
| `mxp_alert_executions` | First alert fires | `alert_execution` |

Query any of these collections with `POST /v1/collections/{collection_name}/documents/list`,
filtering on `signal_type` and any payload field. All standard retriever stages work against them.

## `universal_extractor`

Provisioned at namespace creation, alongside the `default` namespace, an `uploads` bucket, and a
`search` retriever. When you upload files from Studio, Mixpeek runs the universal extractor over
them: multimodal embeddings at 3072 dimensions plus generated descriptions.

This collection carries no system prefix. You can rename, reconfigure, or delete it like any
collection you created yourself.
