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

# Scan barcodes from other systems

> Configure ION to recognize barcodes from external systems using regex patterns or JSON field mappings.

By default, ION expects a specific format for internally defined barcodes, but you can also scan barcodes from other systems with some basic configuration.

Configuration is done through the API using the `createBarcodePattern` mutation. Each barcode pattern defines an `entityType` and either an `expression` (regex) or a `barcodePatternJson` (JSON field mapping). You cannot set both on the same pattern.

<Note>
  The two pattern types are also exclusive at scan time. When the scanned text is valid JSON, ION matches it against `barcodePatternJson` patterns only and skips every regex `expression` pattern, so a regex written against a JSON payload never matches. If your scanner emits JSON, use a JSON field mapping.
</Note>

## Using a regex expression

Use `expression` when your external barcode encodes data as a formatted string. ION uses [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) with named capture groups to extract field values from the scanned string.

### Regex example

Suppose you have an inventory barcode that follows a pattern similar to a [GS1 barcode](https://www.gs1.org/standards/barcodes/databar):

```
(01)<Part number>(17)(10)<Serial number>
```

The equivalent regular expression is:

```
\(01\)(?P<part_partNumber>.*)\(17\)\(10\)(?P<serialNumber>.*)
```

<Note>
  If your regex includes escape characters, double every backslash when passing the value as a JSON string. For example, `\(01\)` becomes `\\(01\\)` in the API input.
</Note>

Use the GraphQL explorer in ION to run this mutation:

```graphql theme={null}
mutation CreateBarcodePattern($input: CreateBarcodePatternInput!) {
    createBarcodePattern(input: $input) {
        barcodePattern {
          id
          _etag
          entityType
          expression
        }
    }
}
```

With these variables:

```json theme={null}
{
  "input": {
    "entityType": "PARTS_INVENTORY",
    "expression": "\\(01\\)(?P<part_partNumber>.*)\\(17\\)\\(10\\)(?P<serialNumber>.*)"
  }
}
```

## Using a JSON field mapping

Use `barcodePatternJson` when your external barcode scanner emits structured JSON rather than a formatted string. The value is a JSON string where each key is an ION field name and each value is the corresponding key in the scanned barcode's JSON payload.

Use the `part_` prefix to reference a field on the related part. For example, `part_partNumber` refers to the `partNumber` field of the inventory item's part.

### JSON field mapping example

Suppose your scanner emits:

```json theme={null}
{"pn": "EX-PART-001", "lot": "L-42"}
```

To map this to `PARTS_INVENTORY`, create a pattern that maps the scanner's keys to ION's field names:

```graphql theme={null}
mutation CreateBarcodePattern($input: CreateBarcodePatternInput!) {
    createBarcodePattern(input: $input) {
        barcodePattern {
          id
          _etag
          entityType
          barcodePatternJson
        }
    }
}
```

```json theme={null}
{
  "input": {
    "entityType": "PARTS_INVENTORY",
    "barcodePatternJson": "{\"part_partNumber\": \"pn\", \"lotNumber\": \"lot\"}"
  }
}
```

When ION scans a barcode that emits `{"pn": "EX-PART-001", "lot": "L-42"}`, it looks up the inventory item whose part number is `EX-PART-001` and lot number is `L-42`.

### Partial matching

Append a match mode suffix to an ION field name to match partial values:

| Suffix       | Behavior                                  |
| ------------ | ----------------------------------------- |
| `__prefix`   | Field value starts with the scanned value |
| `__suffix`   | Field value ends with the scanned value   |
| `__contains` | Field value contains the scanned value    |

For example, to match any part number that contains the scanned value:

```json theme={null}
{
  "input": {
    "entityType": "PARTS_INVENTORY",
    "barcodePatternJson": "{\"part_partNumber__contains\": \"pn\", \"lotNumber\": \"lot\"}"
  }
}
```

Match mode suffixes also work in regex patterns. Add the suffix to the field name inside the named capture group, for example `(?P<part_partNumber__prefix>.*)`.

### Ignoring barcode keys

A JSON pattern matches only when the scanned payload's keys, after removing the `_ignored` keys, exactly equal the set of keys you mapped. If your scanner emits keys that you don't use for matching, list them in the `_ignored` array:

```json theme={null}
{
  "input": {
    "entityType": "PARTS_INVENTORY",
    "barcodePatternJson": "{\"part_partNumber\": \"pn\", \"lotNumber\": \"lot\", \"_ignored\": [\"checksum\"]}"
  }
}
```

ION ignores the `checksum` key in the scanned JSON and matches only on `pn` and `lot`.

<Warning>
  Account for every key in the payload. A key you neither map nor add to `_ignored` causes the pattern to silently fail to match. When your scans don't resolve, first check that the mapped keys plus `_ignored` cover the full set of keys in the scanned JSON.
</Warning>

<Note>
  The `iuid` key is reserved for ION's own barcode labels and can't appear in a JSON field mapping. When a scanned payload contains an `iuid` key, in any letter case, ION uses it to look up the matching ION label directly and doesn't evaluate custom patterns. If the `iuid` value isn't exactly 32 characters, the scan fails with a validation error, so don't use `iuid` as a key name in external barcodes.
</Note>

## List existing patterns

To retrieve all barcode patterns configured for your organization:

```graphql theme={null}
{
  barcodePatterns {
    edges {
      node {
        expression
        barcodePatternJson
        entityType
        id
        _etag
      }
    }
  }
}
```
