Skip to content

SDK 4.8.0

Latest

Choose a tag to compare

@bryce-godfrey bryce-godfrey released this 16 Jun 19:29
35ef613

@servicenow/sdk — Release Notes

Version: 4.8.0
Availability: npm — https://www.npmjs.com/package/@servicenow/sdk


🚀 Overview

Version 4.8.0 is a big one. Playbooks are now authorable in Fluent with full support for triggers, lanes, activities, and decisions. Five new APIs are introduced in this release: RestMessage, Alias, AliasTemplate, RetryPolicy, and DataLookup. Declarative record deletion arrives via Now.del(), and the new now-sdk query CLI command lets you query your instance directly from the terminal — making AI-assisted development significantly more powerful when paired with now-sdk explain.

New APIs

Playbook
Define and maintain Playbooks through Fluent! Supported capabilities in this first release include triggers, lanes, activities, and decisions! We encourage all Playbook authors to try this out and share feedback in the discussions area — a rich roadmap of enhancements planned across upcoming releases

import {
  PlaybookDefinition,
  ActivityDefinitions,
  wfa,
} from "@servicenow/sdk/automation";

PlaybookDefinition(
  {
    $id: Now.ID["playbook_with_activity"],
    label: "Playbook with Activity",
    description: "A playbook demonstrating a simple instruction activity",
    name: "playbook_with_activity",
  },
  { triggers: [] },
  {
    lanes: () => {
      const lane_0 = wfa.playbook.lane({
        config: {
          $id: Now.ID["activity_example_lane"],
          label: "Main Lane",
          order: 1,
          startRule: wfa.playbook.run.Immediately(),
          restartRule: "RUN_ONLY_ONCE",
        },
        activities: () => {
          const instruction_0 = wfa.playbook.activity(
            ActivityDefinitions.Core.Instruction,
            {
              $id: Now.ID["activity_example_instruction"],
              label: "Welcome Instruction",
              order: 1,
              description: "Displays a welcome message to the user",
              startRule: wfa.playbook.run.Immediately(),
              restartRule: "RUN_ONLY_ONCE",
            },
            {
              message: "Welcome! Please review the details below.",
              wait: "yes",
            },
            {
              tagline: "Getting Started",
              title: "Welcome",
              description: "Follow the instructions to complete this task.",
              icon: "info-circle-outline",
            },
          );
          return { instruction_0 };
        },
      });
      return { lane_0 };
    },
  },
);

Now.del()
Defines marking records for deletion in Fluent apps. Supports coalesce key lookups, Now.ID references, and direct GUIDs.

Now.del("sys_user_role", { name: "x_myapp.obsolete_role" }); // coalesce keys
Now.del("sys_hub_flow", "my-old-flow"); // Now.ID key
Now.del("sys_hub_flow", "a1b2c3d4..."); // GUID

RestMessage
Defines outbound HTTP integrations (sys_rest_message) with a base URL, shared authentication (Basic or OAuth 2.0), shared headers, and one or more callable HTTP method functions (sys_rest_message_fn). Called at runtime via sn_ws.RESTMessageV2.

import { RestMessage } from "@servicenow/sdk/core";

RestMessage({
  $id: Now.ID["crm-integration"],
  name: "CRM Integration",
  endpoint: "https://crm.example.com/api",
  authenticationType: "oauth2",
  oauthProfile: "<oauth-entity-profile-sys-id>",
  headers: [
    {
      $id: Now.ID["crm-header-content-type"],
      name: "Content-Type",
      value: "application/json",
    },
  ],
  functions: [
    {
      name: "createContact",
      httpMethod: "POST",
      endpoint: "https://crm.example.com/api/contacts",
      content: '{"firstName":"${firstName}","lastName":"${lastName}"}',
      variables: [
        { $id: Now.ID["crm-var-first"], name: "firstName" },
        { $id: Now.ID["crm-var-last"], name: "lastName" },
      ],
    },
  ],
});

Alias
Defines a Connection & Credential Alias (sys_alias) — a named handle that integrations, Flow Designer actions, and scripts use to reference a connection and credential pair without hard-coding instance-specific values. Supports HTTP, JDBC, Basic, and JMS connection types.

import { Alias } from "@servicenow/sdk/core";

Alias({
  $id: Now.ID["my-http-alias"],
  name: "My HTTP Connection",
  connectionType: "httpConnection",
  description: "HTTP connection for external API",
});

Alias Template
Defines a Connection & Credential alias template (sys_alias_templates) — a reusable configuration that drives the wizard UI shown when a user sets up a connection alias.

import { AliasTemplate } from "@servicenow/sdk/core";

AliasTemplate({
  $id: Now.ID["my-http-template"],
  name: "My HTTP REST Template",
  dynamicDataSchema: {
    connectionFields: [
      {
        name: "connectionUrl",
        label: "Base URL",
        type: "text",
        mandatory: true,
      },
    ],
    credentialFields: [
      { name: "username", label: "Username", type: "text", mandatory: true },
      {
        name: "password",
        label: "Password",
        type: "password",
        mandatory: true,
      },
    ],
  },
  defaultDataTemplate: {
    connection: {
      table: "http_connection",
      name: "My HTTP Connection",
      connectionUrl: "https://api.example.com",
    },
    credential: { table: "basic_auth_credentials", name: "My HTTP Credential" },
  },
});

RetryPolicy
Defines a Retry Policy record (sys_retry_policy) that controls how outbound integration connections handle transient failures — including strategy (fixed_time_interval, exponential_backoff, or retry_after), attempt count, wait interval, and the encoded query condition that determines when to retry.

import { RetryPolicy } from "@servicenow/sdk/core";

RetryPolicy({
  $id: Now.ID["rest-exponential-retry"],
  name: "REST API Exponential Backoff",
  connectionType: "http_retry_conditions",
  retryStrategy: "exponential_backoff",
  count: 5,
  interval: 5,
  condition: "status_codeIN429,500,502,503,504",
});

DataLookup
Defines a Data Lookup definition (dl_definition) that automatically copies field values from a matching row in a custom matcher table (extending dl_matcher) to a target source record when configurable match conditions are met.

import { DataLookup } from "@servicenow/sdk/core";

DataLookup({
  $id: Now.ID["priority-impact-lookup"],
  name: "Priority Impact Lookup",
  sourceTable: "task",
  matcherTable: "dl_u_priority",
  matchRules: [
    {
      $id: Now.ID["match-priority"],
      sourceField: "priority",
      matcherField: "priority",
      exactMatch: true,
    },
  ],
  setRules: [
    {
      $id: Now.ID["set-impact"],
      targetField: "impact",
      matcherField: "impact",
      alwaysReplace: false,
    },
  ],
});

CLI

now-sdk query command
Runs a read-only Table REST API query against your authenticated ServiceNow instance directly from the terminal (no browser required). Useful for resolving live instance data while writing Fluent code: looking up sys_ids, inspecting table schemas, checking existing records, reading choice values, and more.

now-sdk query <table> --query '<encoded_query>' [--fields <f1,f2>] [--limit <n>] [-o json]

Pass -o json for machine-readable output — the response envelope includes ok, records, hasMore, and nextOffset for pagination:

# Resolve a role name to its sys_id
now-sdk query sys_user_role -q 'name=admin' -f 'sys_id,name' -o json

# Inspect incident table columns
now-sdk query sys_dictionary -q 'name=incident^elementISNOTEMPTY' \
  -f 'element,column_label,internal_type,reference' -o json

# Check whether a business rule already exists
now-sdk query sys_script -q 'name=My Rule^collection=incident' -f 'sys_id,name' -o json

Use with AI tooling. now-sdk query pairs naturally with now-sdk explain for AI-assisted Fluent development. now-sdk explain gives an AI agent SDK documentation and API reference; now-sdk query gives it live, instance-specific data (actual sys_ids, real schema, existing record state). Together they let an AI agent write accurate Fluent code against your instance rather than guessing at values.


Type System

$override on DataPolicy and UserPreference (#2661)
DataPolicy and UserPreference now support $override (Now.Internal.OverrideProperties) for merge-mode control.

ScheduledScript supports $meta (#2685)
ScheduledScript now accepts Now.Internal.Meta, enabling $meta: { installMethod: 'once' } for one-time execution scripts.

ACL field accepts custom column types (#2685)
The field property on ACL definitions now accepts string in addition to the typed union, allowing custom column names beyond the predefined set.


Bug Fixes

** Fixed corrupted zip files produced by pack for apps containing binary assets (e.g. .eot font files).

Script action output variable flattening — Fixed complex object types (FlowArray, FlowObject) in script action step output variables being flattened to simple string columns during transform.

Dashboard description and certified fields lost on round-trip — Dashboard API now correctly preserves the description and certified fields through round-trip build and transform.

Mandatory string fields dropped during transform — Mandatory string fields in Record definitions are now preserved during XML→Fluent transform.

Missing __action_status__ mapping with wfa.errorEvaluation() — Fixed missing __action_status__ sys_element_mapping record when wfa.errorEvaluation() is present. Without this record, datapills in error evaluation status messages were not rendered by the platform.

Table defaults accessible_from to 'public'Table now defaults accessible_from to 'public', enabling platform UI components (e.g. Studio) to reference the table without an explicit override.

now-sdk init crash on missing vendor prefixnow-sdk init no longer crashes when the instance's vendor prefix API returns undefined. Falls back to the x_ default prefix.