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

# ServiceNow

> Connect ServiceNow ticket sync with OAuth client credentials, a dedicated integration user, and source-scoped polling.

## What Flow syncs from ServiceNow

ServiceNow ticketing connects Flow to your ServiceNow instance for source-scoped ticket sync. Flow uses OAuth client credentials and polling. It does not use inbound ServiceNow webhooks.

A ServiceNow source is a table and query scope, such as incidents assigned to one group, request items for one fulfillment team, or an approved custom task table. Flow does not mirror an entire ServiceNow instance.

Incidents and request items are both first-class sync tables, and both can name two people:

* **Opened by** is the person who filed the record.
* **Requester** is the person the record is for.

For example, a service-desk agent opens a hardware incident because a colleague's laptop will not start. Flow shows the agent under Opened by and the colleague under Requester. A request item uses the same two seats: the person who filed it, and the person it is for.

## Prerequisites

* A ServiceNow admin (or equivalent) who can manage system properties, users, roles or access control list (ACL) rules, and **System OAuth > Application Registry**.
* A Flow admin who can open **Integrations** and filter to **Ticketing**.
* Your ServiceNow instance URL (for example `https://acme.service-now.com`).

## Prepare the provider

Complete these ServiceNow steps before you authorize in Flow. You need a Client ID and Client secret tied to a dedicated integration user.

### Enable inbound OAuth client credentials (if needed)

Many instances already allow the client-credentials grant. Skip this step if your instance already issues tokens for that grant.

<Steps>
  <Step title="In the filter navigator, open `sys_properties.list`." />

  <Step title="Find or create `glide.oauth.inbound.client.credential.grant_type.enabled`." />

  <Step title="Set Type to `true | false` and Value to `true`." />

  <Step title="Save." />
</Steps>

If the property is missing, create it in the global application scope. Your instance also needs the usual OAuth and REST plugins that ServiceNow documents for inbound OAuth.

### Create a dedicated integration user

Create a non-personal service account for Ticket Sync. Do not reuse a personal admin login.

Grant least-privilege table access for the sources you plan to sync:

| Access | Tables / fields | Why |
| - | - | - |
| Read; create or write only when the configured direction needs it | `incident` | Incident ticket sync |
| Read; create or write only when the configured direction needs it | `sc_req_item` | Request-item ticket sync |
| Read, create, write | The custom task table you name as the source | Custom-table ticket sync. Grant write only when Flow should create or update those records. |
| Read for automatic setup | `sys_db_object`, `sys_dictionary`, `sys_choice` | Proves Task ancestry and discovers inherited fields and active choices. These setup-only reads are recommended but are not used on every poll. |
| Read | `sc_item_option_mtom`, `sc_item_option`, `item_option_new`, `sc_multi_row_question_answer`, `question_choice` | Request-item catalog answers, including multi-row sets and choice labels. Required for the Imported request form. |
| Read | `sys_journal_field` | Comments and work notes. Required for comment sync. |
| Read | `sys_user`, `sys_user_group` | Assignees, groups, requester, and opened-by lookups. Runtime status values come from the selected ticket row, not metadata tables. |
| Read (optional) | CI, Service, Service Offering, major incident, and related-record fields you want in ticket detail | Context tiles only. Core sync can continue without them. |

Table ACLs are not the only gate. On a custom or scoped table, also confirm **Allow access to this table via web services** on the table **Application Access** tab. Confirm **REST API Access Policies** (`sys_api_access_policy`) allow Table API **GET** for import and **POST** or **PATCH** when Flow writes back.

Flow does not require the ServiceNow `admin` role or write access to metadata tables. If your integration user cannot read the three setup metadata tables, an organization administrator can use the advanced manual path described in [Set up a custom table](#set-up-a-custom-table). Runtime table and field permissions still apply.

**Comment sync gotcha:** comments and work notes come from `sys_journal_field`, not from the incident or request-item row alone. If the integration user cannot read that journal table, ServiceNow can return an empty success response and Flow imports zero comments with no hard error. Prefer a narrow custom role with a read ACL on `sys_journal_field` over a broad admin role.

**Catalog form gotcha:** request-item answers live on `sc_item_option` and `sc_item_option_mtom`, not on the request-item row. Multi-row variable-set answers live on `sc_multi_row_question_answer`. If the option tables are denied, the request item still imports and Flow shows a fetch error on **Imported request form**. The last good copy stays. A denied multi-row or choice-label read keeps the rest of the form. Email and Requested for answers are ordinary form fields. Only masked or password answers are hidden.

**Custom table gotcha:** **Authorize ServiceNow** only proves a bounded read of `incident`. **Run filter** is a one-row GET of the table you selected. The first poll needs GET on that same table, and outbound create or update needs POST or PATCH. A REST API Access Policy or a disabled web-services flag on the custom table can let setup finish and still fail the first sync. ServiceNow can also return an empty success when the integration user cannot read the table. A filter count of zero is not proof that no records exist.

Keep the user active. Prefer a web-service style integration identity when your instance supports it.

### Create the OAuth client and copy credentials

<Steps>
  <Step title="Open Application Registry.">
    Go to **System OAuth > Application Registry**, then select **New**.
  </Step>

  <Step title="Create an external-client endpoint.">
    Choose **Create an OAuth API endpoint for external clients**. Enter a name such as `Flow Ticket Sync`, keep the client active, and save. Redirect URL is not required for client credentials.
  </Step>

  <Step title="Set Client Credentials and the application user.">
    Set **Default Grant type** to **Client Credentials**. Add **OAuth Application User** to the form if it is hidden (**Configure > Form Design** or **Form Layout**), then select the integration user from the previous task.
  </Step>

  <Step title="Attach a Table API auth scope.">
    Create or reuse a REST API auth scope for the Table API path (`now/table`) and attach it to this OAuth application so client-credentials calls can use the Table API.
  </Step>

  <Step title="Copy Client ID and Client secret.">
    Copy **Client ID** and **Client secret** from the Application Registry record. You paste both into Flow next. Store the secret in your password manager. You may not see the full secret again after you leave the form.
  </Step>
</Steps>

## Connect in Flow

<Steps>
  <Step title="Open Ticket Sync.">
    In Flow, open **Integrations**, filter to **Ticketing**, and choose ServiceNow.
  </Step>

  <Step title="Enter connection details.">
    Enter the ServiceNow instance URL, Client ID, and Client secret, then choose **Authorize ServiceNow**.
  </Step>

  <Step title="Create a source scope.">
    Pick the team, table, encoded query or assignment group, destination Flow ticket type, filters, and sync direction. Keep the scope narrow (one assignment group or encoded query) instead of polling the whole instance.
  </Step>

  <Step title="Enable polling.">
    Select **Save** and confirm the first import for that source.
  </Step>
</Steps>

| UI field | Required | Purpose |
| - | - | - |
| Team | Yes | Team that owns imported tickets for this source |
| ServiceNow instance URL | Yes | Tenant host (for example `https://acme.service-now.com`) |
| Client ID | Yes | Client ID from Application Registry |
| Client secret | Yes | Client secret from Application Registry |
| Source scope | Per team/source | Table, encoded query, assignment group, destination Flow ticket type, sync direction, and default create target |

## Create a source

Choose **Add source**, then work through the setup tabs. The same tabs open again when you edit a configured source, plus **Mapping preview**.

<Steps>
  <Step title="On the Source tab, pick the team inbox and ServiceNow table.">
    Choose ServiceNow incidents, ServiceNow request items, or a custom ServiceNow table you name yourself. Set **Destination Flow type** to Incident or Request. Flow preselects Request for request-item tables and Incident for incident tables, and you can change it.

    Changing the table on an existing source needs a disconnect and reconnect, so pick it deliberately.
  </Step>

  <Step title="On Sync settings, set the sync direction, ownership, and default create target.">
    Set **Sync direction**, **Ownership** for conflicts, and **Default create target** when new Flow conversations for this team should create a ServiceNow record here.
  </Step>

  <Step title="On Condition filters, narrow which records are eligible.">
    Use **Inbound filter** with an encoded query.
  </Step>

  <Step title="On Field mappings, map the ticket fields.">
    Map Subject, Description, Priority, Status, Requester, Opened by, Assignment team, and the resolve and close fields ServiceNow requires. See [Map identity](#map-identity) and [Clean up subject and description text](#clean-up-subject-and-description-text).
  </Step>

  <Step title="On Status mappings, match ServiceNow state values to Flow states." />

  <Step title="On Priority mappings, match ServiceNow priority codes to Flow priorities." />

  <Step title="Finish setup.">
    Choose **Save**, then confirm the first import.
  </Step>
</Steps>

## Set up a custom table

Automatic discovery is the recommended path. Flow reads `sys_db_object` to prove that the table descends from Task, `sys_dictionary` to find its effective inherited fields, and `sys_choice` to find active state and priority values. You review those results before activation.

Flow maps standard ServiceNow state labels automatically. If a custom state name has no clear meaning, Flow keeps the discovered state and asks you to choose its Flow state before activation. This review is normal and does not mean metadata access failed.

If ServiceNow denies those metadata reads, Flow shows two choices:

1. **Grant metadata read access** (recommended). Add read-only access to the three metadata tables, then verify again.
2. **Configure manually** (advanced). An organization administrator enters and reviews the exact runtime mappings and explicitly acknowledges that Flow cannot prove formal Task ancestry or discover the schema automatically.

### Complete manual setup

<Steps>
  <Step title="Enter mappings." />

  <Step title="Supply or match one test record with the source filter." />

  <Step title="Test table access." />

  <Step title="Review limitations." />

  <Step title="Activate." />
</Steps>

The manual test performs a bounded read from the selected source table. It must return at least one record with the configured identifier, display key, title, status, update/revision, and direction-specific mapped fields. Flow derives compatibility evidence from that server response and your reviewed mappings. The test does not create, update, or delete a ServiceNow record, and it does not prove the table's formal inheritance.

Manual mode cannot override a table that ServiceNow metadata positively proved is not Task-derived. Timeouts, throttling, malformed responses, and provider outages also do not open the manual fallback; retry those transient failures instead.

Once either verification path succeeds, Flow stores the setup evidence. Normal polling does not reread metadata. Removing metadata access later does not stop an unchanged source, although Flow can show a warning if an optional refresh fails. Changing the table or a runtime-critical mapping requires verification again.

## Map identity

Which identity rows appear on **Field mappings** depends on the table.

| Source table | Rows shown | Defaults | Choices |
| - | - | - | - |
| `incident` | Requester and Opened by | `caller_id` and `opened_by` | Caller, Opened by |
| `sc_req_item` | Requester and Opened by | `requested_for` and `opened_by` | Requested for, Opened by |
| Custom task table | Requester only | None | Fields discovered for the selected table, or an exact field entered and tested during manual setup |

Custom task tables stay single-person. Flow hides the Opened by row there rather than inventing a second person.

Both identity rows also offer a custom field entry for instances that store people on their own field, such as `u_requested_on_behalf_of`. Choose the custom option and type the exact field name.

If you point Requester and Opened by at the same field, Flow warns that both roles use one field and keeps a single person on the ticket. Map Opened by to a different field to keep two people.

## Clean up subject and description text

**Text cleanup** sits on the **Field mappings** tab and applies to Subject and Description. It is one ordered list of changes that Flow runs top to bottom for the field you selected.

| Part | Values |
| - | - |
| **Field** | Subject, Description |
| **Change** | Trim spaces, Truncate, Convert to plain text |
| **Direction** | Inbound, Outbound, Both ways |

Truncate adds a **Max characters** box with a default of 255, which suits a ServiceNow `short_description`. Convert to plain text removes HTML and similar markup.

<Steps>
  <Step title="Add a change.">
    Pick the field at the bottom of the section, then choose **Add change**. The new step starts as Trim spaces running Both ways.
  </Step>

  <Step title="Set the change and direction.">
    Choose the change, then choose whether it runs on import (Inbound), when Flow writes back (Outbound), or both.
  </Step>

  <Step title="Order the steps.">
    Use **Up** and **Down** to order the steps within a field, and **Remove** to delete one.
  </Step>

  <Step title="Read the summary.">
    Flow prints a plain sentence under the list for each field so you can confirm the order at a glance.
  </Step>
</Steps>

A typical ServiceNow setup is Truncate on Subject with 160 characters running Outbound, plus Trim spaces on both fields running Both ways. You can add up to eight changes per field, and the editor is the same during setup and in source settings.

## Status mappings

**Status mappings** matches ServiceNow state values to the six Flow states: Open, In progress, On hold, Resolved, Closed, and Canceled. Enter the ServiceNow choice value, such as `6`, not the display label. Flow shows the usual label under the box once it recognizes the value.

Add more than one state value under a Flow state with the plus control. Incoming tickets accept every listed value. When a Flow state lists more than one value, mark one as the outbound default with the check-mark control. It then reads **Current outbound default**.

**Resolve and close fields** sits under **Field mappings**. It lists the provider fields ServiceNow requires when Flow resolves or closes a synced record, such as close code and close notes. You can supply a constant default or the Flow resolution summary.

## Priority mappings

**Priority mappings** sits next to **Status mappings**. ServiceNow priority values group under four Flow priorities: Urgent, High, Normal, and Low.

Enter the ServiceNow priority number. Flow shows the usual label next to it, so you can confirm you typed the code you meant.

| ServiceNow code | Helper label | Flow priority by default |
| - | - | - |
| `1` | Critical | Urgent |
| `2` | High | High |
| `3` | Moderate | Normal |
| `4` | Low | Low |
| `5` | Planning | Low |

Three rules govern the tab:

* Incoming tickets use every listed value, so list each code your instance actually sets.
* One outbound default per Flow priority. When Low lists both `4` and `5`, the check-mark control decides which code Flow writes back. The chosen row reads **Current outbound default**.
* On an existing linked ticket, a code you never listed keeps the current Flow priority. A first-time import with no matching row starts at Normal. Later syncs do not treat that create default as a mapped translation.

## Preview a mapping

Open a configured source and use **Mapping preview**. Type a sample provider Title, Status, and Priority, then choose **Preview mapping**. Flow shows the Flow result per field and a **Held unmapped values** table for provider values with no status or priority row. Preview does not save mappings or create tickets.

## Imported request form

Request-item tickets carry a read-only **Imported request form**. Flow copies the ServiceNow catalog questions and answers onto the ticket. It keeps the shape of the original form, including plain fields, nested variable sets, and multi-row answers rendered as a table.

| Behavior | Detail |
| - | - |
| Read only | Flow displays the answers. Edits in Flow do not change the ServiceNow record |
| Refreshed by polling | Answers update when they change in ServiceNow. **Sync now** rebuilds the full copy |
| Not a Flow catalog item | Importing a request form does not create a Flow catalog item |
| Answers stay in ServiceNow | Flow does not write form answers back |
| Sensitive answers are hidden | Masked and password answers do not enter the copy |
| Failures keep the last good copy | A denied or failed option read shows a fetch error and leaves the previous copy in place |

## Capabilities

* ServiceNow OAuth client-credentials connect
* Per-team source scopes with table, encoded query, and assignment-group filters
* Polling-based import for supported ticket tables, including incidents and request items
* Custom ServiceNow task table sources when the table and ACLs are prepared for Ticket Sync
* Outbound create and update when Flow owns the linked record and the source direction allows it
* Two-person identity on incidents and request items
* Ordered text cleanup on Subject and Description in both directions
* Status and priority translation with per-value outbound defaults
* Comment and field sync with conflict policies
* Ticket detail context for operators, including CI, Service, Service Offering, Major incident state when available, and selected related records
* Read-only **Imported request form** on request-item tickets. Flow copies ServiceNow questions and answers. It does not create a Flow catalog item or write answers back.

## Scopes and permissions

ServiceNow ACLs and the OAuth application user must allow the table access in [Prepare the provider](#prepare-the-provider). Keep each Flow source narrow with one assignment group or encoded query. REST API Access Policies and **Allow access to this table via web services** can still block Table API calls after Authorize succeeds. For the complete custom-table permission and fallback model, see [Set up a custom table](#set-up-a-custom-table).

Authorize only proves a bounded read of `incident`. **Run filter** and the first poll use the table you selected as the source.

For ticket detail context, the integration user also needs read access to the optional fields you want Flow to display:

| Context field | ServiceNow field examples | Permission notes |
| - | - | - |
| CI | `cmdb_ci`, `cmdb_ci.name` | Reads the referenced configuration item label only. Flow does not sync CMDB records. |
| Service | `business_service`, `business_service.name` | Reads the business service reference when available. |
| Service Offering | `service_offering`, `service_offering.name` | Reads the service offering reference when available. |
| Major incident state | `major_incident_state` | Optional incident field. Not all instances or tables expose it. |
| Related Records | `parent_incident`, `rfc`, `caused_by`, `problem_id` and their `.number` fields | Used to show parent incident, change request, caused-by change, and Problem tiles. |
| Identity fields | `caller_id`, `opened_by`, `requested_for`, and any custom user field you map | Required to resolve Requester and Opened by to Flow people. |
| Imported request form | `sc_item_option_mtom`, `sc_item_option`, `item_option_new`, `sc_multi_row_question_answer`, `question_choice` | Required to copy request-item catalog answers onto the Flow ticket, including multi-row sets and choice labels. |

ServiceNow can allow the primary ticket read while denying a field or referenced record label. In that case Flow omits the optional field or shows an unavailable related-record state. Core ticket sync can continue. A denied catalog-option read does not block the request-item import.

Flow generates ServiceNow record URLs from the configured instance and trusted record identifiers. Provider-returned reference links are not stored or rendered.

## Limits

ServiceNow ticketing does not provide full CMDB sync, catalog item ordering, service catalog authoring, or broad change-request import. Request-item catalog answers are copied onto the Flow ticket as a read-only form. Related ServiceNow records are displayed as context for a linked ticket when the source exposes safe references.

## Troubleshooting

| Symptom | What to check |
| - | - |
| Authorize fails immediately | Confirm Client ID and Client secret match the Application Registry record, the client is active, and the instance URL is the base host only. |
| Error about the OAuth application user | Set **Default Grant type** to **Client Credentials**, populate **OAuth Application User**, attach a Table API auth scope, and confirm that user is active. |
| Client-credentials grant rejected before Flow can finish | Confirm `glide.oauth.inbound.client.credential.grant_type.enabled` is `true` when your instance requires it. |
| Custom-table discovery says metadata access was denied | Grant read-only access to `sys_db_object`, `sys_dictionary`, and `sys_choice`, or ask an organization administrator to choose **Configure manually**. Metadata write access and the `admin` role are not required. |
| Manual table test returns no records | Add a safe test record that matches the source filter, or adjust the filter. Flow cannot treat an empty `200` as compatibility proof because ServiceNow may hide denied rows that way. |
| Manual table test reports missing fields | Correct the field mappings or grant read access to the configured fields, then test again. Flow does not guess missing field names. |
| A custom source asks for verification after an edit | The table or a runtime-critical mapping changed. Verify the reviewed contract again before activation or polling resumes. |
| Authorize and **Run filter** succeed, then the first poll or **Run poll now** fails | Authorize only reads `incident`. Check REST API Access Policies for the selected table and methods GET, POST, and PATCH. On a scoped custom table, open **Application Access** and enable **Allow access to this table via web services**. |
| Tickets import but Flow cannot create or update the ServiceNow record | Grant create and write on the source table. Confirm REST API Access Policies allow POST and PATCH, not only GET. |
| Custom-table setup finishes with zero imported tickets | ServiceNow can return an empty success when the integration user cannot read the table. Recheck table ACLs, REST API Access Policies, and **Allow access to this table via web services**. |
| Tickets import but comments or work notes never appear | Grant the integration user read access to `sys_journal_field`. A denied journal read can look like success with zero comments. |
| Request item imports but Imported request form is missing or shows a fetch error | Grant read access to `sc_item_option_mtom`, `sc_item_option`, `item_option_new`, `sc_multi_row_question_answer`, and `question_choice`. Then use **Sync now**. The last good copy stays after a failed fetch. |
| Imported request form shows sys\_ids or empty multi-row fields | Grant read access to `sc_multi_row_question_answer`, `question_choice`, and the referenced answer tables such as `sys_user`. Then use **Sync now**. |
| Imported request form is empty on an older request item | That ServiceNow record has no stored catalog answers. Flow does not invent or backfill a form. |
| No Opened by row on the source | The source table is a custom task table. Custom tables stay single-person. Use `incident` or `sc_req_item` for two-person identity. |
| Incident or request item shows one person for both roles | Requester and Opened by point at the same field, or the same person filed the record for themselves. Check the two pickers on **Field mappings**. |
| Requester or Opened by never resolves to a Flow person | Grant read access to `sys_user` and confirm the mapped field holds a user reference. |
| A record imports with the wrong Flow state | Add the ServiceNow state value to the correct Flow state on **Status mappings**, then confirm the result on **Mapping preview**. |
| Priority never changes on a linked ticket | The ServiceNow code is not listed on **Priority mappings**. Existing tickets keep their current Flow priority. |
| Flow writes the wrong priority code back | More than one code sits under that Flow priority. Set the one you want as the outbound default. |
| Descriptions arrive with markup | Add a Convert to plain text change on Description running Inbound. |
| Optional CI / Service / related tiles missing | Check field and referenced-table ACLs for those optional fields. Core sync can still succeed. |
| Wrong or too many tickets import | Narrow the source encoded query or assignment group. Flow syncs the source scope, not the whole instance. |

## Related topics

* [Ticketing overview](/integrations/ticketing/overview)
* [Jira Service Management](/integrations/ticketing/jira-service-management)
* [ServiceNow KB](/integrations/knowledge/servicenow-kb): knowledge base ingestion (separate connection)
* [Troubleshoot connections and sync](/setup/troubleshooting/connections-and-sync)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.