
ServiceNow API
IT Service Management- Overview
- Setup
- Data & mappings
- Operations & API
- Changelog
The ServiceNow API connector integrates with ServiceNow custom API endpoints defined by an OpenAPI 3.x specification. Unlike the standard ServiceNow connector which syncs predefined tables, this connector dynamically discovers models from a client-provided OpenAPI JSON spec, enabling integration with custom scoped applications and proprietary endpoints.
The connector parses the OpenAPI spec at runtime, groups the endpoints by the resource each one acts on, and registers one model per resource — working out which endpoint serves that resource's list, create, update and delete. This allows per-client customization without code changes. A resource is modelled only if it can be read; see A resource is modelled only if it can be read.
Data retrieved from ServiceNow API
| Connector Object | Required | Maps to Data Model |
|---|---|---|
| Problem | Yes | Problem |
| ProblemPtask | Yes | ProblemPtask |
Model relationships
For detailed steps on how to view the data retrieved from ServiceNow API in the Brinqa Platform, see How to view your data.
Known limitation — only one path template is supported. The id is substituted into the first {...} and any others are left alone, so a nested path such as PATCH /problem/{problem_id}/note/{sys_id} would put the record id in {problem_id} and leave {sys_id} unresolved. The leftover template is logged as a warning, but the URL has already been built by then; and because an unrecognized first template rules no candidate out (above), such an endpoint is not rejected during discovery either.
The renamed attribute is the name to use everywhere on the platform: field mappings, queries and reports all target source_type, never type.
Connection settings
When setting up a data integration, select ServiceNow API from the Connector dropdown and provide the following:
| Setting | Required | Default | Description |
|---|---|---|---|
| ServiceNow URL | Yes | https://<TENANT>.service-now.com | ServiceNow instance URL (e.g. https://mytenant.service-now.com) |
| User name | Yes | — | User with access to read records via the custom API endpoints. |
| Password | Yes | — | User password. |
| Client ID | No | — | (Optional) Client ID for OAuth application. When specified, the connector will use OAuth auth, otherwise it will revert to Basic auth. |
| Client secret | No | — | (Optional) Client secret for OAuth application. |
| OpenAPI Specification | Yes | — | The OpenAPI 3.x JSON specification content describing the custom ServiceNow API endpoints. |
| Model overrides | No | — | (Optional) JSON object keyed by model name to override spec-derived behavior per model. Discovery logs the model name and the endpoints it chose for each one, so start from that summary. Endpoint selection: "listEndpoint", "createEndpoint", "updateEndpoint", "deleteEndpoint" — each an endpoint as "METHOD /path", or "none" to leave that operation unsupported. The method may be omitted, in which case the usual method for that role is assumed: GET to list, POST to create or update, DELETE to delete — so a path served by any other method has to name it. "operations" restricts which write operations are exposed, as any of "create", "update", "delete"; naming "update" where only a create endpoint exists reuses it as an upsert, whether or not "create" is named alongside it. Record addressing for update/delete: "uidBodyField" (request-body field carrying the record id, for endpoints with no '{id}' in the path) and "uidQueryParam" (query parameter carrying it, for endpoints with no request body). Records and identity: "recordsPath" (dotted path to the record array, e.g. "result.records"), "uidField", "nameField", "updatedField". On a model that also creates or updates records, "uidField" must name a field the list response provides AND the create response returns AND the update endpoint can carry — the connector refuses to load a model whose operations cannot agree on one identity, since a create would otherwise report an id no sync reproduces. Changing "uidField" on a model that has already synced re-keys its records: purge the integration''s data and run a full sync afterwards. Pagination and filtering: "pageParam", "pageStartIndex", "sinceParam", "sinceTimeZone". Also "enabled" (set false to skip the model) and "requiredParams" (query parameter values to supply, e.g. '''{"parent":"PRB0001000"}'''). Example: '''{"Problem":{"recordsPath":"result.records","uidField":"sys_id","createEndpoint":"POST /api/example/problem/create"}}'''. |
| Page size | No | 100 | The maximum number of results to return per page. |
| Maximum retries | No | 5 | The maximum number of retry attempts before giving up a request. |
Authentication
The connector supports two authentication methods:
Basic Authentication
Used when Client ID and Client Secret are not provided.
| Header | Value |
|---|---|
Authorization | Basic <base64(username:password)> |
OAuth 2.0 Password Grant
Used when Client ID and Client Secret are provided.
Endpoint
| Method | URL |
|---|---|
POST | https://<TENANT>.service-now.com/oauth_token.do |
Request Headers
| Header | Value |
|---|---|
Content-Type | application/x-www-form-urlencoded |
Request Body
grant_type=password&client_id=<clientId>&client_secret=<clientSecret>&username=<username>&password=<password>
Sample Response
{
"access_token": "HLZ6xZCgGwfOG2Z3PDE3...",
"refresh_token": "M3zT2Q9Te8wlMue0sy-LX4...",
"scope": "useraccount",
"token_type": "Bearer",
"expires_in": 1799
}
Response Fields
| Field | Type | Description |
|---|---|---|
access_token | String | Bearer token used to authorize subsequent API requests |
refresh_token | String | Token used to obtain a new access token |
scope | String | Scope granted to the token |
token_type | String | Token type (Bearer) |
expires_in | Integer | Access token lifetime, in seconds |
Usage
Once authenticated, all subsequent API requests include the bearer token:
Authorization: Bearer <access_token>
How to obtain ServiceNow API credentials
Create a ServiceNow user
For the ServiceNow connector to access the ServiceNow API, you must create a user account. To create a new ServiceNow user, follow these steps:
-
Log in to your organization's ServiceNow server as an administrator.
-
Navigate to All > User Administration > Users.
-
Click New.
-
Provide a User ID, First name, and Last name for the new user, and ensure you select Active as well. Complete the other fields as desired.

-
Click Submit.
-
Locate the new user in the Users table, and click the user ID.
-
Click Set Password and generate a new password for the user. Take note of this password and provide it to the user accessing the account.
-
Click Close in the "Set Password" dialog, and then click Update.
Copy the User ID and the Password into the corresponding fields in the integration configuration.
Note: If you do not have the permissions to create a new user, contact your ServiceNow administrator. For additional information, see ServiceNow documentation.
Assign the required roles and permissions
After you have created the ServiceNow user, you can assign the necessary roles to the user so that they have the proper permissions to retrieve data from the ServiceNow API. To assign roles to the user, follow these steps:
-
Locate the new user in the Users table and click the user ID.
-
Locate the Roles section on the page and click Edit.
-
Under Collection, select the desired roles, and then click Add.
The user account must have the following roles to successfully access your ServiceNow API:
itilsnc_platform_rest_api_access
-
Click Save.
Note: If you do not have the permissions to assign roles to users, contact your ServiceNow administrator. For additional information, see ServiceNow documentation about how to assign roles, create a new role, and base system roles.
(Optional) Obtain the client ID and client secret for OAuth2 authentication
The ServiceNow connector supports OAuth2 authentication using the Password grant type. If you want to use OAuth2 authentication, you must provide a client ID and client secret in addition to the ServiceNow username and password. To obtain the credentials, follow these steps:
-
Log in to your organization's ServiceNow server as an administrator.
-
Navigate to All > System OAuth > Application Registry.
-
Click New.
-
Click Create an OAuth API endpoint for external clients. A new page appears.
-
Provide a name for the OAuth2 client application, fill in the Client Secret field, and select Active. You can also leave the Client Secret field blank if you want the system to auto-generate one. Leave the other fields as is.
-
Click Submit.
You are taken back to the Application Registries page.
-
Click the name of the new OAuth2 client in the table.
-
Click Toggle Password Visibility next to the Client Secret field to reveal the secret.

Copy the Client ID and Client Secret values and paste them into the Client ID and Client secret fields in the connector configuration. Although you can return to this page to view the Client ID and Client secret, you should handle them with care by ensuring that they are stored in a secure location.
Note: If you do not have the permissions to create the credentials for OAuth2 authentication, contact your ServiceNow administrator. For additional information, see ServiceNow documentation.
Get OpenAPI specification from ServiceNow
For the connector to autogenerate the models it will sync and push data to, you will need to provide an OpenAPI specification. The specification can be defined and downloaded from ServiceNow. To define, download, set, and configure the OpenAPI specification please follow the steps below.
Define schema in ServiceNow
ServiceNow allows users to create the request schema, response schema, and query parameters for their scripted REST APIs in ServiceNow. To create the specification your ServiceNow user account will need the web_service_admin role.
For each resource you wish the connector to consume:
-
Define response and request schemas
-
Define the query parameters exposed by your resource
-
Set the API resource query parameters
Download OpenAPI specification from ServiceNow API Explorer
Once the response schema, request schema, and query parameters are defined for your scripted REST API you can download the OpenAPI specification directly from the REST API Explorer in ServiceNow.
-
Go to All > System Web Services > REST > REST API Explorer
-
Select the Namespace, API Name, and API Version for your API
-
Click on Export OpenAPI Specification (JSON) to download the OpenAPI specification

Add OpenAPI specification and configure connector
Once you have the OpenAPI specification you can add it to the connector configuration to create the integration.
-
Copy and paste the contents of the OpenAPI specification downloaded from ServiceNow into the OpenAPI Specification field in the connector configuration.
-
Depending on your OpenAPI specification you might need to configure model overrides. See the model override reference below for possible issues and their solution.
-
After adding your OpenAPI Specification and Model overrides continue with connector creation as normal
Model override reference
| # | Spec issue | What the spec looks like | Symptom | Override + sample resolution |
|---|---|---|---|---|
| 1 | Records nested under a wrapper the connector doesn't recognize | GET /api/x/problem returns {"data":{"items":[…]}} | The GET isn't recognized as a list, so the resource is not modelled at all | recordsPath<br/>{"Problem":{"recordsPath":"data.items"}} |
| 2 | Resource has write endpoints, but its GET isn't recognized as a list | POST /api/x/ticket/create and GET /api/x/ticket/search, whose response the spec leaves undescribed | Model is never created; the endpoints appear as unused in the discovery summary | listEndpoint<br/>{"Ticket":{"listEndpoint":"GET /api/x/ticket/search"}} |
| 3 | Several endpoints of one resource qualify as its list | GET /api/x/user/list and GET /api/x/user/search, both returning record collections | Ties break on fewest path segments, then alphabetically, so /list wins; records come from the wrong endpoint | listEndpoint<br/>{"User":{"listEndpoint":"GET /api/x/user/search"}} |
| 4 | More than one create-shaped POST on the resource | POST /api/x/user and POST /api/x/user/create, where the plain collection POST is the real create | A create verb in the path wins, so creates are sent to /create | createEndpoint<br/>{"User":{"createEndpoint":"POST /api/x/user"}} |
| 5 | A POST at an item path that performs an action rather than an update | POST /api/x/problem/{sys_id} that reopens the record | A POST on a path carrying an {id} template is read as the update, so every update triggers the action | updateEndpoint<br/>{"Problem":{"updateEndpoint":"none"}} |
| 6 | A single endpoint handles both create and update | POST /api/x/problem/create is the resource's only write, and the API treats it as an upsert | Update is reported as unsupported — an endpoint is only ever given one role | operations<br/>{"Problem":{"operations":["create","update"]}}<br/>Only a create widens into an update, never the reverse |
| 7 | Update endpoint takes the record id in the request body, and the spec does not declare it | POST /api/x/user/update with no {id} in the path and an undocumented body — a body that declares sys_id is found on its own | Update is reported as unsupported: the endpoint declares no way to identify the record | uidBodyField<br/>{"User":{"uidBodyField":"sys_id"}}<br/>Name the identity field itself |
| 8 | Delete identifies the record through the query string, and the spec does not declare the parameter | DELETE /api/x/user with no {id} in the path and no declared sys_id parameter | The delete is dropped from the model: it declares no way to identify the record | uidQueryParam<br/>{"User":{"uidQueryParam":"sys_id"}} |
| 9 | The write endpoints declare several id fields, but the API honors only one | list returns sys_id and number, and the update body declares both, but ServiceNow accepts only the record number (for example PRB0001000) | Candidate order picks sys_id, so updates are rejected by ServiceNow. Where the body declares number alone, the connector narrows to it unaided | uidField<br/>{"Problem":{"uidField":"number"}} |
| 10 | Create endpoint defines no response schema | POST /api/x/incident/create documents a response with no schema | The model loads, but a create fails after the record was created — nothing in the response identifies it for future syncs | uidField (or disable the write)<br/>{"Incident":{"uidField":"number"}} |
| 11 | Records are keyed by a business identifier while the write endpoints use a system id | GET /user returns user_name and email; POST /user responds with sys_id | Model does not load; setting uidField alone does not resolve it | disable the write endpoints<br/>{"User":{"createEndpoint":"none","updateEndpoint":"none","deleteEndpoint":"none"}} |
| 12 | No recognized id field in the records | records carry only ticket_ref | Records are skipped; if the resource also writes, the model refuses to load | uidField<br/>{"Ticket":{"uidField":"ticket_ref"}} |
| 13 | Records have no number, name or short_description | records carry title instead | The record NAME is left empty | nameField<br/>{"Ticket":{"nameField":"title"}} |
| 14 | Last-updated field has an unconventional name | records carry last_modified rather than sys_updated_on | Incremental sync cannot narrow the window; every sync behaves as a full sync | updatedField<br/>{"Ticket":{"updatedField":"last_modified"}} |
| 15 | The API can filter by timestamp, but the connector never sends one unless it is named | query parameter sys_updated_on_greaterthan | The full data set is retrieved and filtered by the connector instead of the API | sinceParam (and sinceTimeZone, default America/New_York)<br/>{"Problem":{"sinceParam":"sys_updated_on_greaterthan"}} |
| 16 | The API pages by page number under a parameter the connector does not recognize | the list takes a 0-based pageIndex; page, pageNumber, page_number and pageNo are detected without configuration | An offset is sent instead and ignored, so the sync repeats the first page or stops early | pageParam and pageStartIndex<br/>{"Problem":{"pageParam":"pageIndex","pageStartIndex":0}} |
| 17 | The list endpoint requires a query parameter the connector cannot supply | GET /api/x/problem/ptask requires parent | The model is deferred: it cannot sync standalone, and appears only if a parent's response embeds its records | requiredParams<br/>{"ProblemPtask":{"requiredParams":{"parent":"PRB0001000"}}} |
| 18 | Records read from a parent record's embedded list also need to be written | POST /api/x/problem/ptask/update exists, but the records come from the Problem response | Write endpoints are not attached to these models by default | name the endpoint and the id field<br/>{"ProblemPtask":{"updateEndpoint":"POST /api/x/problem/ptask/update","uidField":"sys_id"}} |
| 19 | The specification exposes resources you do not want to sync | any endpoint group with no use in Brinqa | Unwanted object classes and extra requests to ServiceNow | enabled<br/>{"ProblemPtask":{"enabled":false}} |
On a model that also creates or updates records, uidField must name a field the list response provides and the create response returns and the update endpoint can carry. The connector refuses to load a model whose operations cannot agree on one identity, since a create would otherwise report an id no sync reproduces — see Identity on a model that writes.
Changing uidField on a model that has already synced re-keys its records. Records synced under the old identity are never matched again. Purge the integration's data and run a full sync afterwards — see Changing the spec or the API can change the UID.
Attribute mappings
Expand the sections below to view the mappings between the source and the Brinqa data model attributes:
Problem
| Source Field Name | SDM Attribute |
|---|---|
*(dynamic)* | (all response fields) |
Instant.now() | LAST_CAPTURED |
| number or short_description | NAME |
| sys_id or number | UID |
ProblemPtask
| Source Field Name | SDM Attribute |
|---|---|
*(dynamic)* | (all response fields) |
Instant.now() | LAST_CAPTURED |
| number or short_description | NAME |
| sys_id or number | UID |
Operations & API
Expand each connector object to see its operation options, delta-sync behavior, and the API it uses. See connector operation options for how to apply operation options (keys and values are case-sensitive).
Problem
Operation options
| Option | Type | Default | Description |
|---|---|---|---|
order_by_desc | String | — | Field name to order by descending |
count | String | 100 | Number of results per page |
include_null_values | String | false | Include JSON keys with null values |
include_tasks | String | — | Include task records in response |
return_fields | String | — | List of fields to return |
use_display_values | String | — | System, display, or both |
order_by_asc | String | — | Field name to order by ascending |
include_journals | String | — | Include journal records |
start | String | 0 | Pagination offset |
Delta sync
Supported. The connector performs an incremental (delta) sync via the since sync token, filtering on sys_updated_on.
API
- Type: REST endpoint
ProblemPtask
Operation options
This object does not support any operation options.
Delta sync
Supported. The connector performs an incremental (delta) sync via the since sync token, filtering on sys_updated_on.
API
- Type: REST endpoint
- Where this model's own list endpoint cannot be called — a required query parameter with no value to supply — its records are read from the parent
Problemrecord's embedded array instead. The model is then child-sourced and read-only: its records are keyed by whatever the parent's array carries, which need not be the identifier its own write endpoint expects, so no write endpoint is attached by default. To write to it anyway, name the endpoint withcreateEndpoint/updateEndpoint/deleteEndpointand pair it withuidFieldso the two agree on identity.
Changelog
The ServiceNow API connector has undergone the following changes:
| Version | Description | Migration Steps |
|---|---|---|
| 3.1.0 | New Features - Records can now be created, updated and deleted, not only read. The connector groups the endpoints in your OpenAPI specification by the resource each one acts on and registers a single model per resource, working out which endpoint serves its list, create, update and delete. A resource read at GET /user and written at POST /user, PATCH /user/{id} and DELETE /user/{id} — or one using verb paths such as GET /user/query, POST /user/create, POST /user/update and POST /user/delete — becomes a single User model supporting all four operations. Writes are attached to a model that reads: a resource with no list endpoint is not modelled on the strength of its write endpoints alone, since a record pushed to one could never be synced back and confirmed. Where such a resource is readable through a GET the inference did not recognize, modelOverrides.<Model>.listEndpoint names it. A model read from a parent record's embedded array — ProblemPtask, for example — is likewise left read-only, since its records are keyed by values the parent supplies, which need not match what its own write endpoint expects; createEndpoint / updateEndpoint / deleteEndpoint attach one explicitly. - One attribute set covering both reading and writing. A model's attributes are the union of what its list endpoint returns and what its create and update request bodies accept, each marked readable, createable and updateable as applicable. A field appearing on both sides is one attribute rather than a readable copy plus a separate writable one. A field the API accepts on a write but never returns is named with a push_ prefix, so it is clear which attributes you can expect values back in. Each write sends only the fields that operation's own endpoint accepts. - Endpoint and record-addressing configuration. modelOverrides gains listEndpoint, createEndpoint, updateEndpoint and deleteEndpoint to name the endpoint serving each operation — or "none" to leave one unmapped — plus operations to restrict which write operations are exposed, and uidBodyField / uidQueryParam to name the field carrying the record id on endpoints with no {id} in the path. Improvements - A modelOverrides setting the connector cannot apply now fails with an error naming it, instead of being ignored. An entry there exists to correct an inference, so quietly falling back to that inference is the one outcome it was written to prevent — and it was invisible, since the operation kept working against the endpoint you had rejected. This covers an unrecognized key, an endpoint name matching nothing on the resource, an unknown value in operations, and uidBodyField on a DELETE endpoint. Each error names the setting, what was configured, and what the resource actually offers. - Attempting an unsupported operation now returns an error listing the endpoints considered for it, what became of each, and the modelOverrides setting that would enable it, so an incorrect inference can be corrected without trial and error. The full endpoint mapping for every resource is written to the connector log at discovery and during Test Connection. - Model order is now stable across runs, so the display priority each model receives no longer changes between syncs. - A list endpoint that could not be reached while a model's attributes were being determined no longer leaves that model on a reduced attribute set until the connector restarts. The attempt is repeated on the next operation, so a model recovers on its own once the endpoint does. An endpoint that answers with no records is a different case and is taken at its word. - A fieldTransformations value the connector cannot read now fails with an error naming the option, instead of being ignored. A transformation exists to reshape the values a sync emits, so ignoring a broken one shipped untransformed data that looked entirely plausible — the same reasoning already applied to modelOverrides. The error reports where the value stopped parsing and which transformation types are recognized. - A rejected or unreachable OAuth token request is now reported as it occurs, instead of being reported as though no credentials were configured. An incorrect client secret, an expired grant and a network outage were previously indistinguishable, and surfaced only as authorization failures later in the sync. Test Connection now names the cause instead of reporting a downstream failure. Bug Fixes - A list endpoint answering with a damaged response — a truncated payload, or an error page in place of records — reported a successful sync with no records. Nothing distinguished that from the resource genuinely having become empty, so under a lifecycle strategy the records already held were retired. Such a response now fails the sync, naming the endpoint, and the records already held are left untouched. - A field transformation that failed was skipped, and the sync still reported success — leaving the record either without that attribute, or still holding the raw value the transformation was configured to replace. Neither is distinguishable from a sync that worked, so records that did not reflect the configured transformation accumulated with nothing to indicate it. A transformation is configuration, so a failure now fails the sync, naming the model, the target attribute and the reason. A transformation with nothing to do — no source value, or a value of a type it does not apply to — is a separate case and still simply produces nothing. - A field returning several values under an attribute declared to hold one was synced with all of them anyway, so a record contradicted the model it was declared against — an assigned_to declared as a single value arrived carrying three, and the platform consolidated a value the schema said could not be there. Cardinality is now settled in one place and records are held to it. A field the schema probe sees as an array in even one record is published multi-valued, instead of being collapsed to a single value because other records happened to hold a scalar. An array carrying one value is unwrapped, that being a serialization detail rather than a disagreement. Several values under a single-valued attribute now fail the sync, naming the model, the field, the record and the values: dropping or joining them would sync a record that looks entirely plausible, and only the specification can settle what a field can carry. The same applies to a fieldTransformations result, a transformation being configuration too. Where the specification declares a field single-valued and the probe sample already contradicts it, this is reported when the schema is built rather than partway into a sync. - A sinceTimeZone the connector could not read was silently replaced with the default, shifting the incremental sync window by hours — so an incremental sync quietly missed records, or re-fetched ones it already had, while reporting success. A value that is not a zone id is now an error naming it, reported at Test Connection rather than discovered from a gap in the data. - Records read from a parent record's embedded list could be emitted twice under the same identifier in a single sync. - Where two source columns wanted the same attribute name, records could carry the wrong one's value. A column named active is published as source_active because the platform reserves the original, and a source that already has its own source_active leaves two columns competing for it. Which one won was decided once for the model and again for each record, by different orderings, so a record could put one column's value under the attribute declared for the other — including where their types differ. The model's choice is now the only one, so the attribute always holds the column it was declared for, and the column that loses is absent from records as well as from the model. - A model whose source has a type, model or version column could not be registered. The platform reserves these three names alongside active, and an attribute colliding with one breaks model registration — yet all four are ordinary ServiceNow column names. Each is now published under the source_ prefix, exactly as active already was: a source type column becomes the source_type attribute. The original name is restored when a write is built, so the API still receives type. - A record column that a list endpoint also accepts as a filter was typed as text, whatever it actually held, because the parameter was registered before the records were examined and stopped their types being read. Such a column is now typed from the records — a numeric column as a number, a timestamp as a date. - A timestamp carrying a UTC offset was dropped from the record entirely, so an attribute the API had supplied a value for arrived empty and nothing reported it. Only a timestamp ending in Z, or in ServiceNow's own unzoned form, could be read. An offset-bearing value — 2024-01-01T10:00:00+05:00 — is now read and converted to UTC, as is an ISO timestamp carrying no zone at all. - A field returned as a reference — a display_value and value pair rather than a plain value — could abort a whole sync where the specification declared that field as a number, a timestamp or a boolean. The pair was unwrapped to text without regard to the declared type, so the record contradicted the model it was declared against and the platform rejected it. Most common where the API is queried with sysparm_display_value=all, which returns every field in that form. The unwrapped value is now read as the type the specification declares. - Composed schemas ( allOf) no longer discard their x-brinqa-uid / x-brinqa-name identity hints, so a record entity assembled from several schemas now honors them. | • All models: record identifiers are derived from the specification and from what the API returns, and this release changes how they are derived — a model with a create or update endpoint may now key records by a different field than before. Records held under the previous identifier will never be matched again and will accumulate alongside newly synced copies. This also applies after any later change to the OpenAPI specification or the upstream ServiceNow API; see Changing the spec or the API can change the UID in the README. — Action: purge the integration's data and run a full sync. • All models: a list endpoint's query parameters are no longer registered as attributes. A parameter describes what the endpoint accepts, not what a record contains, so these attributes could never hold a value — with one exception: a parameter that also names a real record column. That column remains an attribute, now discovered from the records, and its type may change as a result (most often text to number or date), since the parameter previously fixed it as text. — Action: purge the integration's data and run a full sync; review any report or query referencing an attribute named after a query parameter. • Models whose operations disagree on a record identifier: these no longer load, rather than reporting an identifier no sync reproduces. The error names what each endpoint can handle. — Action: set uidField to a field all of them handle, or set createEndpoint / updateEndpoint to "none", which leaves a working read-only model. • Models keyed by a natural identity that also write: whether a create can report an identifier back, and whether an update can carry one, is only ever recognized among the surrogate keys sys_id, number, id, uuid, guid and key. A model whose list keys records by a natural-identity field — user_name, username, login, email or sys_name — while its create or update endpoint offers a surrogate key therefore resolves no identity and does not load. uidField cannot resolve this case, since the named field is still not one the write side is recognized as handling. — Action: set createEndpoint / updateEndpoint to "none", which restores the model as read-only, keyed exactly as it was before. See Agreement is checked against the surrogate keys only in the README. • Models with a field that can carry several values: such a field arriving under an attribute declared to hold one now fails the sync instead of being synced with all of its values. Where the specification leaves a field undocumented, its cardinality is inferred from at most ten sampled records, so a field that can carry several values but happened to be sampled holding one is published single-valued and fails the sync when a later record carries several. — Action: declare any field that can carry several values as an array in the OpenAPI specification before upgrading. • Models with a type, model or version column: these columns are now published as source_type, source_model and source_version, so anything targeting the plain name resolves to nothing. — Action: repoint field mappings, queries and reports at the prefixed name, and purge the integration's data and run a full sync if the model had already synced the column. • Models with fieldTransformations configured: a transformation that fails now fails the sync instead of being skipped, so a sync will not complete until the transformation is corrected. The most common cause is a format or regex pattern applied to a field of a different type than it expects. Records synced before upgrading have been landing without that transformation applied — either missing the attribute or carrying its raw value. — Action: review configured transformations against the attribute types in the model's schema before upgrading, then resync once they are corrected. • Models with a sinceTimeZone override: a value that is not an IANA zone id is now an error rather than a silent fall back to the default, so no model loads until it is corrected. An existing integration with a mistyped zone has been running with its incremental window shifted by hours, which may have skipped records. — Action: correct the value before upgrading, and run a full sync if incremental syncs may have missed records. • fieldTransformations configuration: a value the connector cannot read is now an error rather than being ignored, so a sync configured with one fails instead of running untransformed. Anything already running with a broken value has been emitting raw values, not transformed ones. — Action: review any configured fieldTransformations before upgrading, and expect a first run after upgrading to report one that was never taking effect. • modelOverrides configuration: a setting the connector cannot apply is now an error, and no model loads until it is corrected — an unrecognized key, an endpoint name matching nothing on its resource, an unknown value in operations, or uidBodyField on a DELETE endpoint. Any of these was previously ignored, so an existing configuration containing one has not been doing what it appears to. — Action: review existing modelOverrides against the supported keys in the configuration help before upgrading, and expect a first run after upgrading to report anything that was never taking effect. |
| 3.0.0 | Overview The ServiceNow API connector integrates with ServiceNow custom (scoped-application) REST API endpoints to synchronize records described by a client-provided OpenAPI 3.x specification. A syncable model is discovered automatically for each list endpoint in the specification, so a single connector instance can be configured for any custom endpoint set without code changes. Category: IT Service Management Models | N/A |