---
title: "Enrich Row Async"
method: POST
path: "/api/v1/enrichment/enrich_async/{enrichment_id}"
tags: ["enrichment"]
---

# Enrich Row Async

`POST /api/v1/enrichment/enrich_async/{enrichment_id}`

Enrich rows in the dataset asynchronously.

Supports two selection modes (exactly one per request, enforced by
``EnrichRowRequest`` validator):

- ``feature_ids`` — explicit ids; legacy path, unchanged.
- ``selection`` — filter spec + fingerprint + expected count. The
  server validates the fingerprint (400 on mismatch), recomputes the
  live count (409 on drift), and resolves the matching ids
  server-side before enqueueing — no wire-payload of large id
  arrays.

## Query parameters

- `token` string, nullable — Firebase ID token for MVT authentication

## Request body

- EnrichRowRequest — Request schema for enriching rows. Two mutually-exclusive selection modes: - ``feature_ids`` — explicit ids the client has materialized (legacy path; row-detail trigger and small-N enrich-from-cell). - ``selection`` — the filter spec the client saw at confirm time; the server recomputes the matching id set and fingerprint/count under a live session. Used by the column-wide enrich confirm gate where the id list would exceed wire-payload limits. Exactly one must be provided; the model-validator enforces this so a request that drops both or duplicates both is rejected with 422.
  - `feature_ids` string[], nullable
  - `selection` FilterSelectionRequest — Snapshot-consumer payload. Caller asserts: "when I called ``/filtered-count`` with this spec I saw ``expected_count`` rows and the server returned this ``fingerprint``; act on that selection." The server recomputes both and rejects with ``SelectionDriftResponse`` on mismatch.
    - `filter_spec` SSRTableQueryParams, required — Combined query-param shape for the 5 AG-Grid SSR endpoints. Aliases match AG Grid's camelCase wire format (``startRow``, ``filterModel``, …) so the client contract is unchanged. Handlers parse JSON-encoded query strings into this model via the ``parse_ssr_query_params`` dep; any validation failure surfaces as 422 with a field path.
      - `startRow` integer
      - `endRow` integer
      - `sortModel` SortEntry[], nullable
        - `colId` string, required
        - `sort` 'asc' | 'desc', required
        - `sortMode` 'default' | 'null_push' | 'count', nullable
      - `filterModel` object, nullable
      - `filterId` string, uuid, nullable
      - `groupKeys` union[], nullable
        - union
          - string
          - integer
          - number
          - boolean
      - `rowGroupCols` RowGroupCol[], nullable
        - `id` string, required
        - `field` string, nullable
        - `displayName` string, nullable
      - `searchText` string, nullable
      - `geometry` GeoJSONPolygon — Narrow GeoJSON subset — matches the spatial-filter payload the frontend draws. Accept Polygon and MultiPolygon only; reject Point / LineString / feature collections, which ``ST_Intersects`` with a bbox wouldn't produce meaningful results against.
        - `type` 'Polygon' | 'MultiPolygon', required
        - `coordinates` unknown[], required
          - unknown
      - `favoritesOnly` boolean
    - `enrichment_state` string, nullable
    - `enrichment_name` string, nullable
    - `fingerprint` string, required
    - `expected_count` integer, required
  - `high_priority` boolean — Execute with high priority if True
  - `point_action` boolean — True for a deliberate single-cell enrichment. Only a point action skips the coordinator; column kickoffs stay coordinator-keyed even when they resolve to a single row.

## Response `200`

Successful Response

- EnrichmentBatchStartResponse — Response from POST /enrichment/enrich_async/{enrichment_id}. Enqueue-only; clients drive cell freshness via the polling endpoint. ``feature_ids[i]`` corresponds to ``workflow_ids[i]`` — clients use this parallel mapping to attribute polled workflow results back to rows when they didn't materialize the id list themselves (selection path).
  - `workflow_ids` string[], required
  - `feature_ids` string[], required
  - `coordinator_workflow_id` string, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/maia-analytics/apis/maia-api.md) · [All operations](https://skmtc.net/maia-analytics/apis/maia-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/maia-analytics/maia-api/versions/ba2b8d962161/schema)
