Lookup Lists
Lookup lists are Excel-like reference tables stored at the team level in Team Resources. They validate and normalize extracted field values by matching them against predefined columns of data, and can enrich annotations with related data from the matched row.
Navigate to: Team → Resources → Lookup Lists
From there you can create lists, import data from Excel or CSV, edit values, manage translations, and download or erase list data.
Anatomy of a Lookup List
A lookup list consists of columns and rows:
- Column names must match the field's
name_id(also called the export key). Validation for a field searches the column with the same name. - Up to 26 columns are supported (A through Z).
- Description columns (up to 3) provide the human-readable subtitle shown in the annotation interface.
- Rows hold your reference data. One row represents one real-world record.
The examples below use this vendor list. The columns vendor_name and country correspond to fields with those exact name_ids:
| vendor_name | vendor_id | iban | country |
|---|---|---|---|
| Acme Trading | V-001 | NL91ABNA0417164300 | NL |
| Acme Trading | V-002 | DE89370400440532 | DE |
| Bolt Logistics | V-003 | NL63RABO0123456789 | NL |
| Cato Freight | V-004 | BE68539007547034 | BE |
How Matching Works
When a field is validated against a lookup list, the system builds a search from:
- The field's own value, searched in the column matching the field's
name_id. - Translations of that value (see Translations), used as alternative search values.
- Context fields, if configured: each context field's value (plus its translations) is searched in its own matching column.
A row matches when every searched column contains one of the search values. Matching is:
- Exact - no fuzzy or approximate matching. Use translations to handle known variations.
- Case-insensitive -
acme tradingmatchesAcme Trading. - Wildcard on empty cells - an empty cell in a searched column does not disqualify the row. At least one searched column must contain an explicit match, but a row with an empty
countrycell would match any country context.
Match Outcomes
| Outcome | Result |
|---|---|
| Exactly one row | The field is valid. The value is normalized to the stored list value, and the row's data is attached as metadata. |
| Multiple rows | A warning is raised: "Found N similar matches." The first row is applied provisionally; a reviewer's manual pick resolves the ambiguity and is kept. |
| No rows | An error for required fields ("No match found with reference data"), a warning for non-required fields. |
Worked Examples
Using the vendor list above, for a field vendor_name with context field country:
- Extracted
Bolt Logistics, countryNL→ one row matches (V-003). Valid, with full row metadata attached. - Extracted
acme trading, countryDE→ matching is case-insensitive, and the country context narrows it down to one row (V-002). Valid, with metadata. - Extracted
Acme Trading, no country available → two rows match (V-001 and V-002). Warning: "Found 2 similar matches." The reviewer picks the correct vendor from the suggestions; the pick is kept on later validation passes. - Extracted
ACME→ no row containsACMEinvendor_name. Error (if the field is required). Fix it by adding a translationACME→Acme Trading, or by adding the value to the list.
Value Normalization
On a successful match, the annotation value is replaced with the value as stored in the list. If the extracted value was acme trading and the list stores Acme Trading, the exported value is Acme Trading. The change is recorded in the annotation's audit log ("Lookup → Acme Trading").
Row Metadata
When validation resolves to one specific row, all filled cells of that row are attached to the annotation as a metadata object, keyed by column name:
{
"vendor_name": "Acme Trading",
"vendor_id": "V-002",
"iban": "DE89370400440532",
"country": "DE"
}
- Only filled cells are included; empty cells are omitted.
- Description columns are additionally joined into the subtitle shown under the field in the annotation interface.
- Downstream usage - metadata is available in exports and to subsequent processing steps, so one matched value can carry related reference data (IDs, bank accounts, tax rates) into your output.
Metadata is only attached when it is certain to belong to the matched record. How strictly that is enforced is controlled by the next setting.
The "Match unique row" Setting
The field-level setting Match unique row determines what a "match" means:
Enabled (default): require a unique row
The value and all configured context fields are combined to find one specific row. Any ambiguity between rows, including identical duplicate rows, is surfaced as a warning so a reviewer can resolve it. Because the match identifies a single row, the full row's data is attached as metadata.
Disabled: require a unique value
The value and context fields filter rows exactly as before, but the match is judged per distinct value instead of per row:
- The same value in 4 matching rows is one match. No ambiguity warning is raised.
- Two or more different candidate values still warn ("Found 2 similar matches") so a reviewer can pick.
- An empty field can be filled from context alone: if all rows matching the context carry the same value, that value is applied.
- Use this when repeated rows are expected: category columns, denormalized record tables, lists where the same value legitimately appears many times.
What happens to metadata
A multi-row match cannot be tied to one specific row, so attaching an arbitrary row's full data could silently pick the wrong record. Instead, with Match unique row disabled, metadata is limited to the columns that participated in the match: the field's own column plus the configured context columns. Consider a field validating category:
| category | product_code | tax_rate |
|---|---|---|
| Cat | P-100 | 9 |
| Cat | P-200 | 21 |
| Cat | P-310 | 21 |
| Dog | P-500 | 9 |
Extracted value Cat matches three rows and is one valid match. Metadata is { category: "Cat" }: the rows' product_code and tax_rate belong to individual records and are never attached, even when the rows happen to agree on them.
This makes the metadata shape predictable per field configuration: business rules and exports see the same set of possible keys on every document, chosen by you (the field and its context fields), never a key that appears or disappears depending on the day's list content. Need tax_rate downstream? Keep Match unique row enabled and add context fields until the match resolves to one row, which attaches the full row as before.
The description columns are shown when all matching rows share the same description, and left empty otherwise.
Translations
Translations are a preprocessing step that maps known variations onto the values stored in the list:
- The extracted value is looked up in the field's translation table.
- Any translated forms are added as additional search values alongside the original.
- Matching then proceeds as normal, using all of them.
Use translations for:
- Common misspellings and OCR errors -
Acrne Trading→Acme Trading - Alternative formats -
Acme Trading B.V.→Acme Trading - Historical or regional naming - old vendor names still appearing on documents
Translations are saved from the annotation interface when a reviewer corrects a value, so translation maps grow over time. If no translation exists, the original value is used as-is. Translation matching is case-insensitive too.
Autocomplete
With autocomplete enabled on the field, annotators can search the lookup list while editing:
- Typing shows matching list values as dropdown suggestions.
- Selecting a suggestion enters the exact stored value, so validation passes with no typing errors.
Default Value
A field can be given a default value used as the search value when nothing was extracted. This lets a lookup still resolve (and attach metadata) for documents where the field is absent but the correct row is known from context.
Data Import and Management
File Import
- Supported formats - Excel (.xlsx) or CSV
- Maximum size - up to 100,000 rows per import
- Import modes - Append (add to existing data) or Overwrite (replace all data)
Import Process
- Upload file - drag and drop or select the file
- Preview data - review how columns are mapped
- Choose mode - append or overwrite
- Import - large overwrites can take up to a minute
Available Actions
- Import data - add or replace data from Excel/CSV
- Download - export current list data and translations to Excel
- Erase data - remove all content while keeping the list structure
- Delete list - permanently remove the lookup list
Best Practices
- Match column names to
name_ids exactly - validation searches the column named after the field's export key. - Decide per field whether you need the row or just the value - keep Match unique row enabled (with context fields) when downstream steps consume metadata; disable it for simple allowed-value checks.
- Add context fields to kill ambiguity - if you see "Found N similar matches" warnings, a second column (country, ID, IBAN) usually makes rows unique.
- Build translations instead of polluting the list - keep one canonical row per record and map variations onto it.
- Download before large overwrites - exports double as backups.
- Monitor warnings - recurring multiple-match warnings or no-match errors point at missing context fields or missing translations.