# Lookup tables Source: https://neondeerdata.com/docs/platform/automations/lookup-tables/ Lookup tables map a value, such as a state code, to reference data your workflow needs, such as a sales territory or owner. ## What lookup tables are for A lookup table holds reference data your workflows need but your CRM records do not, for example State to Territory, Industry to Owner, Member to Slack ID, or Deal stage to Owner and SLA. A workflow gives Find lookup table row one value, such as a state code, and gets back the matching row's other values, such as the territory. - A table has fields (columns) and rows. Each row has one value per field. - Tables live on the Neon Deer platform, under `Tables` in the Automations app. Workflows can read them but never change them: there is no step that writes to a table. - Viewing, creating, editing, importing and exporting tables needs a workspace admin or a member with the `Manage Advanced Workflow Automations` permission. Others see `An app admin can manage lookup tables.` Roles come from your Neon Deer workspace; an Attio role grants nothing here. - Whether your workspace can use lookup tables, and how many custom tables and rows it can hold, depends on your Neon Deer plan (see [Settings → Billing in Neon Deer](https://app.neondeerdata.com/)). The Lookup tables page shows how many custom tables are used, and shows rows used once they reach 80% of the row limit. A single custom table holds up to 50,000 rows and 50 fields. ## Creating a table `New table` offers three ways to start. ### Blank table Enter `Table name`, `First field` and its `Type`. `Use this field for lookups` is on by default, which makes the first field the one workflows find rows by. If the lookup cannot be turned on, the table is still created and shows `Table created. Check its lookup field in Fields before adding rows.` Submitting the form twice does not create a second table. ### Import CSV 1. **Upload a `CSV file`.** The first row supplies the field names. `Table name` defaults to the file name. 2. **Pick `Find rows by`.** This column becomes the lookup field, so every row needs a different, non-empty value in it. 3. **Check each column's type.** The suggested type tries yes or no, number, date and email, and otherwise text. Numbers with leading zeros, such as ZIP codes, stay text. 4. **`Preview import`, then `Create table`.** The table, its rows and its lookup are created together. If any value has a problem, nothing is created and the preview says how many values need attention. Field keys from a CSV are `column_1`, `column_2` and so on, in column order. The key is what a workflow sees as the output key (see [How outputs reach workflows](https://neondeerdata.com/docs/platform/automations/lookup-tables/#outputs)). A file can be up to 1,048,576 bytes, with 1 to 2,000 data rows and 1 to 50 columns. ### Browse table library `Preview` and `Add table` copy a starter table into your workspace. Ready-made tables: U.S. states & Canadian provinces, U.S. & Canada territories, Countries, Worldwide territories, Free email domains, US ZIP codes to metro areas, US ZIP codes in major metros, Canadian postal prefixes to metro areas, NAICS industries, LinkedIn industries, and LinkedIn legacy industry names. The library also has templates for uses such as owner routing, value mapping, external IDs and stage mappings, and the synced [Workspace members table](https://neondeerdata.com/docs/platform/automations/lookup-tables/#members-table) and [status tables](https://neondeerdata.com/docs/platform/automations/lookup-tables/#status-tables). Copied starter tables are independent: a starter never updates your copy later. Their fields start unshared, so share the ones your workflows need (see [Sharing fields with workflows](https://neondeerdata.com/docs/platform/automations/lookup-tables/#sharing)). Synced tables follow the Attio data described below. ### Workspace members table - A synced table of your Attio workspace members, found by `Workspace member ID` or `Email`. Name, email, avatar, access level and standing are filled by the sync and are read-only. - `Slack member ID` is the one field you edit (it must look like a Slack ID, starting with U or W). `Slack mention` is computed from it as `<@ID>`. Slack member ID starts unshared; the synced fields start shared. - The platform tries to sync the roster every hour. If it cannot read your members, the table is left as it was rather than emptied, so check `Roster verified at` before relying on it being current. Members cannot be added or deleted here; that happens in Attio. ## Status tables A status table mirrors one Attio status attribute, such as **Deals > Stage**. Each status becomes a row, in the order shown in Attio. Add metadata such as an owner or SLA to each row, then read it in a workflow with [Find lookup table row](https://neondeerdata.com/docs/platform/automations/steps/find-lookup-table-row/). ### Create a status table 1. **Open `Browse table library`** in Neon Deer's Automations area and choose `Statuses`. 2. **Choose `Object` or `List`** , then select the object or list to read from. 3. **Choose a `Status attribute` and select `Create table`.** Only status attributes are offered. Create one table per status attribute. Choosing the same attribute again opens the existing table. ### Synced and editable columns | Column | Source | What it contains | | ---------------------------- | ---------------- | ----------------------------------------------------------------------------------------------- | | Status | Attio, read-only | The status name. | | Status ID | Attio, read-only | The status's identifier. The default lookup field. | | Archived | Attio, read-only | Whether the status is archived or has been removed from Attio. | | Target time in status (days) | Attio, read-only | The target duration in days. Empty if Attio has no target or the duration uses months or years. | | Owner | You edit | An Attio workspace member. | | SLA (days) | You edit | Your own time allowance for this status, in days. | `Owner` and `SLA (days)` start empty. You can remove either column or [add more fields](https://neondeerdata.com/docs/platform/automations/lookup-tables/#fields). All six default columns are available to workflows. An empty cell produces no output. Add, rename, reorder or archive statuses in Attio; edit your additional metadata in Neon Deer. ### Use a status table in a workflow In [Find lookup table row](https://neondeerdata.com/docs/platform/automations/steps/find-lookup-table-row/), select the status table and look up by `Status ID` (the default), or choose `Status` to match a name. Workflows match active statuses only. An archived status returns no match, so branch on `Found` before using the row's outputs. For example, add a table for Deals > Stage and fill in `Owner` and `SLA (days)` for the Proposal stage. When a workflow looks up that stage, it receives the assigned workspace member and your SLA value. Use those outputs to route follow-up work and set its deadline. Changing the stage's owner or SLA in the table updates what later workflow runs receive. ### Refreshes and archived statuses The table refreshes when you open it and about every hour. Opening it again within a minute does not trigger another refresh. New statuses become rows. Renamed statuses keep their rows and your metadata. Archived or removed statuses are marked `Archived` and keep your values. Neon Deer shows every status by default. Use `Hide archived statuses` to filter the view; this does not change what workflows can match. Your Attio connection must allow Neon Deer to read the chosen object's or list's setup. If access is missing, the table explains that its statuses cannot be read. A failed refresh leaves the existing rows and your metadata in place. ## Fields and lookup fields - A field has a label of 1 to 80 characters and a key: lowercase letters, digits and underscores, starting with a letter, up to 63 characters. Keys cannot be reused, even after a field is archived. - You can rename and edit only your own fields. Fields managed by Attio, by the system, or computed are read-only. - A field becomes a **lookup field** when you turn on `Can look up by` in the table's Fields tab. A table can have more than one lookup field; each lookup uses exactly one field. Workflows can choose only tables that have at least one lookup field. - No two rows may share a lookup value after normalization (see [How matching works](https://neondeerdata.com/docs/platform/automations/lookup-tables/#matching)). A duplicate is refused with `Another row already uses this lookup value.` Turning on a lookup for a field that already holds duplicates fails and changes nothing. - Turning a lookup off breaks workflows that find rows by it. The confirmation says so: stored values stay in the table, and if you turn it on again you must select it again in those workflows. - Once a field has been shared with workflows or used as a lookup, its type is locked. To use a different type, add a new field. ### Field types Each value is checked against its field's type in the grid, in CSV files and in lookups, and stored in a normalized form. Text values over 1,000 characters are refused. The normalized form is what lookups compare. | Type | Accepted values | Normalized and matched as | | ------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------- | | Text | Any text | Trimmed. Case-insensitive. | | Number | A finite number, in plain decimal or exponent form | Numeric value; `-0` is `0`. | | Yes or no | `true` or `false` | Boolean. | | Date | `YYYY-MM-DD`, a real calendar date | As entered. | | Date and time | ISO 8601 with seconds and a `Z` or `±HH:MM` offset | The instant: two values for the same moment match whatever their offsets. | | Email | A valid email address | Lowercased. | | Domain | A hostname such as `example.com`, without scheme, path or port | Lowercased, trailing dot removed. | | URL | Starts with `http://` or `https://` | Trimmed. Case-sensitive. | | Attio member | An Attio workspace member ID | Case-insensitive. | | Attio record | An Attio object ID and record ID | Case-insensitive. | A value that fails these rules is refused. The grid names the field; a CSV names the row and column. Error messages never repeat the value itself. ## Editing rows - The Data tab is a grid. Select a cell with a click or the arrow keys, edit with Enter, F2 or by typing, clear with Delete or Backspace, and copy and paste rectangles of up to 50 rows by 50 columns. `Add row`, `Duplicate row` and `Delete row…` manage rows in custom tables. In synced tables, edit your additional metadata here and manage the source rows in Attio. - Rows save automatically; the status line reads `Saving…`, `Unsaved changes`, `Some changes need attention` or `Saved`. A new row saves only once its lookup fields have values, and pasting or clearing cannot empty a lookup field. - A deleted row stops matching at once: workflows looking for it get no match. Other rows do not change. - If someone else changed the row first, the save is refused with `This row has changed. Refresh and try again.` Refresh and make the change again. ## Importing into an existing table `Import data` adds and updates rows from a `CSV file` or `Paste from spreadsheet` (tab-separated). The table needs at least one lookup field first. 1. **Choose `Match existing rows by`.** A row in the file whose value in this lookup field matches an existing row updates that row; any other row is added. 2. **Map columns to fields** , or choose `Skip column`. Headers that match a field's key or label (ignoring case) are mapped for you. Fields you do not map stay unchanged; an empty cell in a mapped column clears that value. 3. **`Preview import`.** The preview counts `Rows to add`, `Rows to update` and `Unchanged`. 4. **`Apply import`.** If the file or the table changed since the preview, it is refused; preview again. If any value has a problem, nothing is written. Common row errors: a value that does not match the field's type, an empty lookup value, a lookup value repeated in the file, or a lookup value another row already uses. Row numbers count the header as row 1\. The same file limits apply as for a new table. Importing into Workspace members or status tables can update your editable metadata on existing rows, but cannot create rows or change Attio-managed fields. ## Exporting `Export CSV` downloads `lookup-table.csv`: a header row of field labels and every active row, with every active field, including Attio-managed, system and computed fields. The file is UTF-8 with a byte-order mark. To stop spreadsheets from running a value as a formula, any cell or header that begins with `=`, `+`, `-` or `@` (or a tab or carriage return) is written with a leading apostrophe. Plain negative numbers such as `-12.5` are not changed. Import does not remove the apostrophe, so a lookup value such as `+EMEA` comes back as `'+EMEA` and no longer matches. Remove those apostrophes before importing an export back in. ## How matching works - A lookup compares one value with one lookup field and needs an exact match after the type's normalization. There is no partial, prefix, fuzzy, wildcard, range or multi-field matching. - Text, email, domain, member and record values match regardless of case, so `ca` finds a row stored as `CA`. URLs match only with the same case. - Because lookup values are unique, a lookup returns one row or none. An empty value is refused. - Neon Deer does not cache results: each run of the step reads the table as it is at that moment. ## How outputs reach workflows The [Find lookup table row](https://neondeerdata.com/docs/platform/automations/steps/find-lookup-table-row/) step connects a workflow to a table. It needs the app's [Neon Deer connection](https://app.attio.com/%5F/settings/apps/installed/workflow-utilities/connections) and a plan that includes lookup tables. | Input | What to set | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Table` | The table to read. Only tables with at least one lookup field are listed; a search shows the first 50 matches. | | `Find by` | One of the table's lookup fields. A member field is listed twice: by member, and as "\