fn lookup()
Verify OAuth credentials, capture instance metadata (release, scope prefix), and identify the user the token impersonates. Run this first to confirm connectivity.
fn tableQuery(table: string, query?: string, fields?: string)
Query a ServiceNow table with an encoded query string. Returns matching records as resource artifacts. Use sysparm_query syntax (e.g., 'active=true^stateIN1,2^ORDERBYsys_created_on').
| Argument | Type | Required | Description |
|---|
| table | string | yes | Table name (e.g., 'incident', 'sys_user', 'sys_app') |
| query? | string | no | Encoded query string (sysparm_query). Empty returns all records up to limit. |
| fields? | string | no | Comma-separated field list to retrieve (sysparm_fields). Defaults to all fields. |
fn tableGet(table: string, sysId: string, fields?: string)
Fetch a single record from a ServiceNow table by sys_id.
| Argument | Type | Required | Description |
|---|
| table | string | yes | Table name |
| sysId | string | yes | sys_id of the record |
| fields? | string | no | Comma-separated field list (sysparm_fields). Defaults to all fields. |
fn tableCreate(table: string, fields: record)
Insert a new record into a ServiceNow table. Pass field values as a JSON object.
| Argument | Type | Required | Description |
|---|
| table | string | yes | Table name |
| fields | record | yes | Field name → value object for the new record |
fn tableUpdate(table: string, sysId: string, fields: record)
Update fields on an existing ServiceNow record. Uses HTTP PATCH semantics — only provided fields are changed.
| Argument | Type | Required | Description |
|---|
| table | string | yes | Table name |
| sysId | string | yes | sys_id of the record to update |
| fields | record | yes | Field name → value object with only the fields to change |
fn tableDelete(table: string, sysId: string)
Delete a record from a ServiceNow table by sys_id. Destructive — verify the sys_id with tableGet first.
| Argument | Type | Required | Description |
|---|
| table | string | yes | Table name |
| sysId | string | yes | sys_id of the record to delete |
fn tableDeleteMany(records: array)
Fan-out: delete a batch of records (each a table + sys_id pair) in one execution — one model-lock acquisition instead of N tableDelete calls. Built for deprovisioning record sets recorded in a manifest (e.g. a customer's provisioned reports + dashboard canvas chain). Records already gone (404) are reported as 'absent', not errors — the method is idempotent and continues past them. Destructive — verify sys_ids against the source manifest first. Pass records via --stdin (nested array does not surv
| Argument | Type | Required | Description |
|---|
| records | array | yes | Records to delete, in order. Delete children before parents (e.g. canvas panes/prefs before portal pages before pa_dashboards) when cascade rules are uncertain. |
fn tableAggregate(table: string, query?: string, count?: boolean, avgFields?: string, sumFields?: string, minFields?: string, maxFields?: string, groupBy?: string)
Aggregate query against a ServiceNow table (count, sum, avg, min, max, group_by). Use this for data analysis without dragging full record sets across the wire.
| Argument | Type | Required | Description |
|---|
| table | string | yes | Table name |
| query? | string | no | Encoded query (sysparm_query) to filter records before aggregation |
| count? | boolean | no | Include record count (sysparm_count) |
| avgFields? | string | no | Comma-separated numeric fields to average (sysparm_avg_fields) |
| sumFields? | string | no | Comma-separated numeric fields to sum (sysparm_sum_fields) |
| minFields? | string | no | Comma-separated numeric fields for minimum (sysparm_min_fields) |
| maxFields? | string | no | Comma-separated numeric fields for maximum (sysparm_max_fields) |
| groupBy? | string | no | Comma-separated fields to group by (sysparm_group_by) |
fn restCall(path: string, body?: unknown, params?: record)
Generic REST call to any path on the ServiceNow instance. Use for Scripted REST APIs, Import APIs, application-specific endpoints, or anything outside the Table API. The OAuth token is applied automatically.
| Argument | Type | Required | Description |
|---|
| path | string | yes | URL path on the instance (e.g., '/api/sn_chg_rest/change' or '/api/x_amsoe_app/widget') |
| body? | unknown | no | Request body for POST/PUT/PATCH (object will be JSON-serialized) |
| params? | record | no | Query string parameters |
fn setupOAuthProvider(name: string, authUrl: string, tokenUrl: string, providerClientId: string, scopes: array, grantType?: string, usePkce?: boolean, codeChallengeMethod?: string, sysScope?: string, redirectUrl?: string, connectionAliasName?: string)
Fan-out: stand up a third-party OAuth 2.0 provider for an integration spoke in one execution (one model-lock acquisition). Creates the oauth_entity (Application Registry record), its default oauth_entity_profile, all oauth_entity_scope records (name + oauth_entity_scope both set), the profile↔scope m2m links, and optionally a shared Connection & Credential Alias — replacing ~3+N manual Table API calls. Set sysScope to land every record inside a scoped app (verified: sys_scope sticks on oauth_ent
| Argument | Type | Required | Description |
|---|
| name | string | yes | Display name for the OAuth provider (Application Registry record), e.g. 'Webex Spoke Integration' |
| authUrl | string | yes | Provider authorization endpoint URL (e.g., https://webexapis.com/v1/authorize) |
| tokenUrl | string | yes | Provider token endpoint URL (e.g., https://webexapis.com/v1/access_token) |
| providerClientId | string | yes | OAuth client_id to configure on the provider. Named providerClientId (not clientId) to avoid collision with the model's global clientId. Use: ${{ vault.get(<vault>, <client-id-key>) }} |
| scopes | array | yes | List of OAuth scope strings to request (each becomes an oauth_entity_scope linked to the profile) |
| grantType? | string | no | OAuth grant type (default authorization_code) |
| usePkce? | boolean | no | Enable PKCE (default true) |
| codeChallengeMethod? | string | no | PKCE code challenge method (default S256) |
| sysScope? | string | no | Scoped application sys_id to create the provider records IN. Omit for global scope. When set, sys_scope + sys_package are stamped on the oauth_entity, its oauth_entity_scope rows, and the profile↔scope m2m links so the provider ships as part of the scoped app. (Platform OAuth tables can be stricter about cross-scope writes than ordinary tables — verify the entity's resulting sys_scope after creation.) |
| redirectUrl? | string | no | Explicit redirect_url for the oauth_entity. Omit to let ServiceNow auto-generate (…/oauth_redirect.do). Set it when the provider's pre-registered redirect must match exactly. |
| connectionAliasName? | string | no | If set, also create a shared Connection & Credential Alias (sys_alias: type=connection, connection_type=http_connection, multiple_connections=true) with this name/id — the alias that per-account connections attach to (see addOAuthAccount). Returned as aliasSysId. |
fn addOAuthAccount(accountName: string, oauthEntityProfileSysId: string, connectionAliasSysId?: string, connectionAliasName?: string, connectionUrl: string, sysScope?: string, registryTable?: string, registryFields?: record, registryConnectionField?: string)
Per-account step for an interactive (authorization_code) OAuth provider: creates an OAuth 2.0 Credential bound to the provider's default profile, an HTTP Connection bound to a shared Connection & Credential Alias, and (optionally) an operational-registry row that references the connection. One call per account/tenant/org; many accounts share one alias (multiple_connections=true) and one oauth_entity, each holding its own token set — the multi-tenant pattern. The only remaining step is a one-time
| Argument | Type | Required | Description |
|---|
| accountName | string | yes | Human label for this account/org (e.g. 'Contoso Webex Org'). Used to name the credential and connection records. |
| oauthEntityProfileSysId | string | yes | sys_id of the provider's default oauth_entity_profile (setupOAuthProvider returns this as profileSysId). |
| connectionAliasSysId? | string | no | sys_id of an EXISTING Connection & Credential Alias to attach this connection to. Omit (recommended) to mint a dedicated PER-ORG alias — that keeps sn_cc.ConnectionInfoProvider.getConnectionInfo(alias) deterministic per tenant (one connection per alias). Pass a shared alias only for the multiple_connections pattern. |
| connectionAliasName? | string | no | Name/id for the per-org alias when one is minted (connectionAliasSysId omitted). Defaults to '<accountName>-alias' sanitized. |
| connectionUrl | string | yes | Base URL the connection targets, e.g. https://webexapis.com. host + protocol are derived from it. |
| sysScope? | string | no | Scoped application sys_id to create the credential, connection, and registry row IN. Omit for global (recommended: per-tenant OAuth wiring is customer-specific and must never enter an app's source or Store package). Enforced via session scope — the Table API ignores payload sys_scope on these tables. |
| registryTable? | string | no | Optional operational-registry table to insert a tracking row into (e.g. x_asei_cisco_hub_webex_org). The created connection's sys_id is injected automatically. |
| registryFields? | record | no | Field map for the registry row (e.g. {name: 'Contoso', webex_org_id: '...'}) . Combined with the auto-injected connection reference. Pass via --stdin or a workflow step (nested objects don't survive --input key=value). |
| registryConnectionField? | string | no | Field on the registry row that should reference the created http_connection (default 'connection'). |
fn findOrCreateCompany(name: string, outputName?: string)
Find a ServiceNow Company (core_company) by exact name, or create it if absent. Returns the company sys_id — the per-customer discriminator used to scope multitenant device/alert/incident data and reports. Idempotent; safe to call every onboarding run.
| Argument | Type | Required | Description |
|---|
| name | string | yes | Company (customer) name to find or create, matched exactly on core_company.name. |
| outputName? | string | no | Fixed name for the produced 'company' resource so a workflow can reference it via data.latest (e.g. 'customer-company'). Defaults to 'company-<sanitized name>'. |
fn provisionCustomerReports(company?: string, org?: string, reportSet: array, sysScope?: string)
Fan-out: create a set of sys_report records, each optionally filtered to one customer's company (or org). Pass the report specs; the method appends the per-customer scope clause (when a company/org is given) and inserts them all in a single execution (one model-lock — the factory pattern, not N separate calls). Two modes: CUSTOMER (company set → every report filtered to it; create in GLOBAL scope by omitting sysScope, so customer-specific artifacts never enter the app source / Store package) and
| Argument | Type | Required | Description |
|---|
| company? | string | no | core_company sys_id — the per-customer discriminator each report is filtered by (unless a report item sets scopeBy='org'). Omit (or pass empty) for a GENERIC all-orgs set with no customer filter. |
| org? | string | no | Optional webex_org (registry row) sys_id, used to scope any report item whose scopeBy='org'. |
| reportSet | array | yes | Report specs. Each becomes a sys_report; the method appends '^<scopeField>=<sysId>' to the filter. Extra keys pass through to sys_report. Pass via --stdin (nested array does not survive --input key=value). |
| sysScope? | string | no | Scoped application sys_id to create the reports IN. Omit for global — the right choice for customer-specific sets, which must never ship with the app. |
fn provisionCustomerDashboard(dashboardName: string, tabs: array, sysScope?: string)
Fan-out: assemble a complete responsive dashboard (Platform Analytics canvas) from already-provisioned sys_report records, in one execution. The canvas IS Table-API-buildable — the anatomy is pa_dashboards → per tab a sys_portal_page + sys_grid_canvas + pa_tabs + pa_m2m_dashboard_tabs, and per widget a sys_portal row + RenderReport sys_portal_preferences + a positioned sys_grid_canvas_pane (12-unit-wide grid; single scores ~h=8, charts ~h=14, lists ~h=16). Widgets reference reports by exact titl
| Argument | Type | Required | Description |
|---|
| dashboardName | string | yes | Display name of the pa_dashboards record, e.g. 'P&G Webex Fleet Operations'. |
| tabs | array | yes | |
| sysScope? | string | no | Scoped application sys_id for the dashboard/tab/pane records. Omit for global. |
fn commitAppSource(commitEndpoint: string, commitMessage: string, appSysId?: string)
Commit a scoped application's outgoing source-control changes to its linked git remote, server-side, and wait for completion. Wraps sn_vcs.AppSourceControl.commitOutgoingChanges() (the engine ServiceNow Studio's 'Commit Changes' calls) via a small commit endpoint the app exposes, then polls sys_execution_tracker until the commit+push finishes. This lets a single 'ship' command push the ServiceNow app to ADO alongside the swamp-catalog PR — no Studio click. The app must expose the commit endpoint
| Argument | Type | Required | Description |
|---|
| commitEndpoint | string | yes | Path of the app's commit Scripted REST op (POST), e.g. '/api/x_asei_cisco_hub/zz_webex_probe/commit-source'. It runs sn_vcs.AppSourceControl.commitOutgoingChanges(...).start() and returns { trackerId }. |
| commitMessage | string | yes | Commit message for the source-control commit. |
| appSysId? | string | no | sys_app sys_id to commit; forwarded to the endpoint (falls back to the endpoint's own application if omitted). |
Resources
instance-info(infinite)— ServiceNow instance metadata snapshot — release, build, scope prefix, and the user identity the OAuth token impersonates
record(infinite)— A single record from a ServiceNow table — full field set as returned by the Table API, tagged with table name and sys_id
aggregate(infinite)— Result of a ServiceNow Aggregate API query — count/avg/sum/min/max/group_by output
rest-response(infinite)— Response body from a generic ServiceNow REST call — for endpoints outside the Table API (Scripted REST APIs, Import APIs, custom application endpoints)
oauth-provider(infinite)— Summary of a third-party OAuth 2.0 provider stood up by setupOAuthProvider — the oauth_entity (Application Registry), its default profile, and the linked scopes, plus the remaining manual UI steps (Connection & Credential Alias + interactive token grant).
oauth-account(infinite)— A single per-account OAuth wiring created by addOAuthAccount — the OAuth 2.0 Credential (bound to the provider profile), the HTTP Connection (bound to the shared alias), and an optional operational-registry row, plus the interactive Get-OAuth-Token consent URL.
company(infinite)— A ServiceNow Company (core_company) resolved or created by findOrCreateCompany — the per-customer discriminator used to scope multitenant device/alert/incident data and reports.
report-set(infinite)— The set of sys_report records provisioned by provisionCustomerReports — filtered to one customer's company (or org), or an unfiltered generic all-orgs set when no company was given.
delete-batch(infinite)— Outcome manifest of a tableDeleteMany run — per-record deleted/absent/error outcomes for a batch deprovisioning, kept for verification and audit.
dashboard-canvas(infinite)— A responsive dashboard (Platform Analytics canvas) assembled record-by-record by provisionCustomerDashboard — the pa_dashboards row, per-tab page/canvas/tab sys_ids, and every widget's sys_portal + pane sys_ids, for verification and rollback.
source-commit(infinite)— Result of committing a scoped app's outgoing source-control changes via commitAppSource — the execution-tracker id and final state (success/failure) of the server-side commit+push to the app's linked git remote.