ServiceNow as a Migration Target
Records that are already in a Cortex archive can be created as new ServiceNow tickets through the ServiceNow Table API. Cortex does the writing, so the source archive is never touched and the original vendor database does not have to be reopened.
The target is a ServiceNow API data source configured under Admin → Data Sources - see Getting Your ServiceNow Data for the connection settings (instance URL, credentials, extra Table API base URLs). The same saved connection can be used for a mirror and for a migration.
Migration targets are create-only in ServiceNow. Cortex creates records; it does not update or delete records that already exist in the instance.
Before you start
- Configure the ServiceNow API data source. Cortex reads the instance's tables, fields and choice values when you build the mapping, then creates the records over the Table API. The user you connect with needs Table API access to read that metadata and permission to create records on the target tables.
- Know which table you are creating into. Business tables and their subclasses are both offered, so pick the table you actually want the ticket to be - an
incident, or a subclass of it. - Have your target values ready. Required fields, choice values, assignment groups and users all have to resolve on the instance, or the record is rejected (see When a record is rejected).
A restricted metadata read does not stop you working, but it removes help from the mapping screen: if the connection cannot read sys_choice or sys_user_group, the dropdowns fall back to plain text and Cortex logs a warning instead of failing. If the instance blocks the table catalog altogether, import a schema bundle and Cortex uses it for the target table list and for inherited fields.
Choosing the target
In the Target System & Table section of the Migrate Data screen, the ServiceNow data source appears even though it is not offered for browsing or searching. The ServiceNow API data source is create-only in Cortex, so it is deliberately kept out of Browse, search and other read pickers, and is offered only where records are written - Migrate Data and Utilities → Migration configurations.
Tables are listed from the live instance. Where ServiceNow stores a subclass inside a physical parent table (an incident is stored in the task table, for example), Cortex sends the create to the physical table with sys_class_name set, so the record is still created as the subclass you selected. See ServiceNow TPH mirrors for how that storage shape works.
Field mappings
The target field list contains only the fields Cortex can write. ServiceNow's virtual fields, read-only fields and its own system elements are hidden from the mapping screen, so anything you can map is a field the Table API accepts.
Everything else works like any other migration target:
- Map a target column to a source field, a fixed Value, an Expression, or one of the email lookups - see Field Mappings.
- Map the instance's choice values onto your source values with Value Translations; dropdown fields offer the instance's own choice labels, read from
sys_choice(English rows only - where both a table and its parent define the same value, the closer table's label wins). - Date, date/time and time values are converted to the format the Table API expects, including values that arrive in the source system's own culture format. Date-only source values stay date-only.
Ordinary mapped text is sent exactly as it is - leading indentation and line breaks included.
Requestor, Assigned To and Assignment Group
These are the three values a migrated ticket almost always needs, and each is filled through a normal field mapping:
| ServiceNow field | How to fill it | What Cortex sends |
|---|---|---|
caller_id / requested_for | Lookup Requester Via Email Address | The sys_id of the sys_user whose email address matches the source value. |
assigned_to | Lookup User Via Email Address | The sys_id of the matching sys_user. |
assignment_group | Source Field or Value holding the group's exact name, or its sys_id | The group's sys_id. The translation dialog offers the live group list. |
A user lookup needs an email address, and a group needs a name that exists on the instance (or a sys_id you already know). Cortex resolves the value while the record is created and fails the record with a message naming the value if it cannot - it never writes an email address or a group name into a reference field as raw text.
These three are deliberately not offered as related-record transfers. A relationship transfer creates a new child record in the child table, which for a user or group reference would create a duplicate sys_user or sys_user_group row instead of linking the ticket to an existing one. Use the field mappings above.
When a record is rejected
Cortex passes ServiceNow's own response back on the record, so the reason is visible without going to the instance:
- a validation or mandatory field failure,
- an ACL (permission) refusal from the credentials Cortex uses,
- a user email or assignment group that could not be resolved.
Rejected records are collected rather than stopping the run, and can be retried individually - see Running and Monitoring a Migration.
What Cortex does not do
- It does not update or delete existing ServiceNow records. The write path is create-only.
- It does not read records back. The ServiceNow API data source cannot be browsed or searched in Cortex; it exists to create records and to read the metadata that supports that.
- It does not copy journal entries or attachments. The attachment transfer option is offered only for target systems Cortex can upload files to - FreshService and Halo.
Records are created one at a time in the run order you see in the task, and Cortex records the new sys_id against each source record, so a retry of a failed record does not duplicate a ticket that was already created.
See also
- Getting Your ServiceNow Data - the ServiceNow API connection and the schema bundle fallback
- ServiceNow TPH mirrors - how subclasses are stored and written
- Field Mappings and Value Translations - building the mapping
- FreshService as a Migration Target - the other API target with its own settings