---
title: "Suggest mapper correspondences for a sample"
method: POST
path: "/v1/import/mappers/suggest-mapping"
tags: ["Import"]
---

# Suggest mapper correspondences for a sample

`POST /v1/import/mappers/suggest-mapping`

## Request

- Base URL: `https://api.prod.keyban.io`
- URL: `https://api.prod.keyban.io/v1/import/mappers/suggest-mapping`
- Auth: API key in header `X-Api-Key`

Propose a `source -> destination` correspondence for each destination an
AI model recognizes in the submitted sample profile, to pre-fill the mapper
builder for review. Destinations it does not recognize are simply omitted.

The sample file is **not** sent: the caller parses it locally and submits only
a profile of its source fields (identifier, one example value, and for CSV the
aggregates measured over the scanned rows). The destination fields are derived
server-side from the passport-creation schema, so they cannot drift from what
the import accepts.

The answer is filtered against the submitted sources and the generated
destinations, so it can only ever reference fields that exist. It stays a
suggestion: nothing is persisted, and the import itself remains deterministic.

Never fails on the model's account: if it is unreachable or answers unusably,
correspondences come from a deterministic lexical matcher instead and
`degraded` is set.

**Read `confidence` before applying a correspondence.** The list reports every
destination that was recognized, including the ones judged unfit to pre-fill:
`high` and `review` are meant to be applied (`review` asks for a second look),
while `low` must be offered rather than filled in — its values would fail
passport validation on every row. `evidence` says *why*, and `origin` says who
proposed it; anything other than `llm` was produced without a model call.

## Request body

- string

## Response `200`

Suggested correspondences

- ImportMappingSuggestionDto
  - `mappings` object[], required: Suggested correspondences, one per recognized destination. Read `confidence` before applying: a `low` entry is reported so it can be offered, not pre-filled. Empty when nothing could be recognized — a valid outcome, not an error.
    - `destination` string, required: Destination dot-path into the passport-creation input, guaranteed to be one of the server-side destination fields.
    - `source` string, required: The `path` of the source to read it from, guaranteed to be one of the submitted sources. Destinations left unmapped are omitted rather than returned empty.
    - `origin` 'exact' | 'alias' | 'pattern' | 'llm', required: How the correspondence was established. Anything other than `llm` was produced by the deterministic matcher, without a model call.
    - `evidence` 'confirmed' | 'unaided' | 'unopposed' | 'contested' | 'inadmissible', required: How well the correspondence is corroborated, from confronting the answer with the deterministic matcher. Says what to check, where a numeric score would only say how much to worry: `contested` points at a namesake destination, `inadmissible` at values the destination cannot accept. Orthogonal to `origin` — who proposed a correspondence and how well it holds up are different questions.
    - `confidence` 'high' | 'review' | 'low', required: What to do with the correspondence. `high` and `review` are both meant to be applied — `review` asks for a second look — while `low` must NOT be applied automatically: offer it as a suggestion and leave the destination empty. Derived server-side from `evidence` so the cut-off has one home; do not re-derive it from `evidence` or `origin`. That cut-off is calibrated against the evaluation corpus that ships with the server, so it can be recalibrated server-side without a contract version change — a client that froze its own `evidence`-to-decision table would keep applying the previous calibration.
  - `degraded` boolean, required: True when the language model could not be reached or answered unusably, and the correspondences come from the deterministic matcher alone. The suggestion is then narrower — it favours leaving a destination empty over guessing — so it deserves a closer review. Never an error: a degraded suggestion is still returned with a 200.

## Other responses

- `400`: Invalid input data

---

[API](https://skmtc.dev/keyban/apis/keyban-rest-apis.md) · [All operations](https://skmtc.dev/keyban/apis/keyban-rest-apis/llms.txt) · [OpenAPI document](https://skmtc.dev/keyban/apis/keyban-rest-apis/revisions/0bb79a1da961?raw)
