**Source URL:** https://limited.veevavault.dev/qualityone/migrations/references/migration-key-fields

# Migration Key Fields

Successful migrations require a key field set by the migrator that stays stable across Vault refreshes and reloads. Because the system-assigned ID can change between sandbox, validation, and production Vaults, we recommend using an external ID, which links source records to target records across environments.

## External IDs on Vault Objects

Vault objects require one key field for every row in a loader sheet. The field must be user-defined, configured as unique in the target Vault, and writable using Vault Loader or Vault API. We recommend using the external ID field when available, however, any unique key field satisfies this requirement.

<Aside>
App-delivered objects may have key fields under a suffix such as `__clin`, `__qdm`, or `__rim`.
</Aside>

Many Vaults already have the external ID field configured as unique. Verify the field is present and configured unique before adding it to loader sheets. Add a key field only if the object's existing configuration does not include one and the owning application has not locked it.

### Simple Join Objects

Simple join objects do not require an external ID or key field because their identity is the combination of the two parent record IDs. Adding a field to a simple join object disables its *Add* button in the Vault UI for [creating simple join records](https://platform.veevavault.help/en/gr/28740/#create-simple-relationship).

## External IDs on Vault Documents

Vault documents also have an external ID field. This field must be unique across documents, document attachments, record attachments, and attachment fields. The external ID field is not visible on the Doc Info page even when added to a field layout, but remains accessible via the Library grid view, reports, and [VQL](/qualityone/vql/query-targets/documents).

### Document Annotations

Document annotations use `external_id__sys`, not `external_id__v`. For Vault-to-Vault migrations, the recommended format is `{document_version_id}_{annotation_id}`.

## Other Key Fields

The following key fields exist in your Vault. Each is either set by you or managed by the system.

| Field | Set By | Purpose |
| --- | --- | --- |
| `external_id__v` / `external_id__c` (name and suffix may vary) | Migrator (user-defined) | Provides source traceability, serves as an upsert key, and supports parent-child linking. |
| `id` (BYOID, under Record Migration Mode) | Migrator, using BYOID | Preserves the source system's record ID for Vault-to-Vault migrations. See . |
| `link__sys` | Migrator or integration | Stores a source record's `global_id__sys` for Vault-to-Vault connections. Can be used as a key field only when the value is unique. |
| `global_id__sys` | Vault (system-managed, read-only) | Provides cross-Vault integration linking in the format `{vault id}_{record id}`, set by the record's ID. |

## External ID Naming Conventions

We recommend creating external IDs from a predictable pattern that is reconstructible from the source ID of the source system's primary or natural key. A predictable pattern means the key is reconstructible from source data if a load fails mid-run and must be restarted. Prefix external IDs with an object-type identifier to prevent collisions when multiple objects share the same numeric key space. For example, `STUDY-00123` or `SITE-US-00045`.

While the same external ID value can exist on two different objects without conflict, Vault API and Vault Loader reject a duplicate on the same object with the error message `OPERATION_NOT_ALLOWED: Another resource already exists with [external_id__v=<value>]`. For , there is a wider scope of uniqueness.

Do not derive external IDs from mutable attributes such as a record's status, name, or owner. Assign external IDs at the start of the transformation phase and leave them fixed. Regenerating keys after any records have been loaded invalidates all parent-child references in downstream files.

### Bringing Your Own ID (BYOID)

With [Record Migration Mode](https://platform.veevavault.help/en/lr/761685) enabled, you can supply the `id` column on `create` so that each target record's ID is generated cleanly from its source record ID. This strategy is particularly useful when performing Vault-to-Vault migrations.

Bring your own ID (BYOID) values brought from the source system must be 15 uppercase alphanumeric characters, with the object prefix as the first three characters and `Z` as the fourth. For example, `00PZA1B2C3D4E5F`.

If the structure of the ID needs to remain the same across multiple restage cycles, use a cycle counter. Replace characters 4–5 with `Z1` for the first load, `Z2` for the next restage, `Z3` for the one after, and so on. Each cycle claims fresh ID space that was never previously consumed. Because Vault does not enforce this convention, you must track the counter per engagement.

<Aside type="caution">
If your migration requires , populate the `external_id__v` field on `upsert` rather than using BYOID. Vault never frees a consumed record ID on `delete`, so delete-and-restage cycles that reuse the same ID values will fail. Only a full Vault refresh resets the ID.
</Aside>

## Managing Idempotent Reloads

Use the `idParam=external_id__v` query parameter on the [Create & Upsert Object Records](/vault-api/api-reference/26.3/vault-objects/create-upsert-object-records) endpoint to make loads re-runnable. Vault Loader matches incoming rows against existing records by external ID and creates or updates records accordingly. Vault Loader exposes this as the `UPSERT` action type with `idParam=external_id__v`.

<Aside type="caution">
If key fields are not set on the first load pass, a subsequent upsert has no values to match against and will create duplicates.
</Aside>

## Resolving References

When populating object reference fields in loader sheets, we recommend using the external ID lookup form rather than the system ID. Record IDs differ between sandbox and production environments, while external ID lookups are transferable across environments.

| Strategy | Column Header Format | Transferability |
| --- | --- | --- |
| System ID | `parent_field__v` = `00P000000000101` | Non-transferable |
| Name lookup | `parent_field__vr.name__v` = `'United States'` | Transferable only when `name__v` is unique on the target object |
| External ID lookup | `parent_field__vr.external_id__v` = `'COUNTRY-US'` | Transferable; preferred for migration |

When creating new relationships between documents, the [Create Multiple Document Relationships](/vault-api/api-reference/26.3/documents/document-relationships/create-multiple-document-relationships) endpoint accepts a document's external ID in place of `source_doc_id__v` or `target_doc_id__v`. Ordinary document reference fields on records still expect the literal Vault document ID.

### CSV Column Header Format

Both field-name form and the relationship-name form resolve correctly when using Vault API and Vault Loader. We recommend using the field-name form because it works with both API field names and relationship names without requiring the relationship name.

| Form | Column Header Format | Example |
| --- | --- | --- |
| Field-name form | `<field_api_name>.external_id__v` | `product_family__v.external_id__v` |
| Relationship-name form | `<relationship_name>.external_id__v` | `product_family__vr.external_id__v` |

To use the relationship-name form, you must confirm the actual `relationship_name` within the [object's metadata](/vault-api/api-reference/26.3/vault-objects/retrieve-object-metadata) `relationships[]` array. Vault API ignores incorrect relationship names, leaving the reference null.

<Aside>
Vault API's `/vobjects/` endpoints do not reject incorrect column headers, silently dropping these unrecognized headers. Therefore, you should verify reference fields have been populated after loading. If a CSV contains a duplicated column header, Vault API returns `SUCCESS` and uses the last value with no error. The same applies when both header forms target the same field simultaneously.
</Aside>

---

**Previous:** [Data Transformation Considerations](/qualityone/migrations/references/data-transformation)  
