
Video Text:
Today, let’s make sense of how ServiceNow can talk to other systems on the internet using something called “web services.”
Picture two friends who share a common language. They can exchange messages, ask for help, and share answers without any confusion. Now imagine if these two friends tried to communicate but each spoke a completely different language. They’d struggle, wouldn’t they? That’s often the case for different applications—they’re built with different programming languages and data formats. Without a common “language” or set of rules, it’s hard for them to understand each other.
This is where web services come in. They provide a standard way for applications to talk to each other, no matter what language they’re built in. By following common rules, each system can understand the other’s requests and responses, making everything run smoothly.
ServiceNow as a Web Service Consumer:
Look at this diagram. On the left, we have our ServiceNow instance. Think of it as a curious student, ready to learn. On the right, we have an external application that offers data or tasks—like a teacher or a resource library. The line between them is the network, and the “language” they use to talk is called a web service.
When ServiceNow wants something—say, a piece of data from that external application—it sends a request. This request basically says, “Please give me the info I need.” The external application is the provider. It processes the request and sends back a response. The response often comes with two key parts:
A Status Code, which tells you if everything went well. (For example, “200 OK” means success.)
A Response Body, which is the actual data, like a record of a user or the temperature in a certain city.
With web services, ServiceNow can grab data from all kinds of sources—geolocation coordinates, stock info, financial data, inventory details, weather updates, language translations, and so on. Instead of opening different websites manually, ServiceNow does it for you, behind the scenes.
Why ?
Because why build this in ServiceNow from scratch if you can just save time and use existing apps instead.
Video Text:
Now that we know ServiceNow can talk to external applications using web services, let’s explore one of the most common standards they use—something called REST (Representational State Transfer).
REST sets clear guidelines for how requests and responses should be structured. This makes it easier for any two systems to communicate, even if they’re built by different teams or in different programming languages.
By following these REST rules, it’s like we’re all agreeing to speak the same “universal language” when we request and share data.
For example, imagine you’re in a restaurant with a set menu.
Everyone orders using the same terms, like 'soup' or 'steak.' The waiter understands exactly what you mean, and the kitchen knows how to prepare it. You don’t need to know how the kitchen works; you just follow the menu, and the communication is clear. In the same way, with REST, systems follow a common 'menu' of request and response formats, so they can understand each other without knowing the details of the other system’s inner workings.”
Video Text:
Lets look at 2 benefits of REST
1. Separation of Client and Server:
In the REST architectural style, the implementation of the client and the implementation of the server can be done independently without each knowing about the other. This means that the code on the client side can be changed at any time without affecting the operation of the server, and the code on the server side can be changed without affecting the operation of the client.
As long as each side knows what format of messages to send to the other, they can be kept modular and separate. Separating the user interface concerns from the data storage concerns, we improve the flexibility of the interface across platforms and improve scalability by simplifying the server components. Additionally, the separation allows each component the ability to evolve independently.
By using a REST interface, different clients hit the same REST endpoints, perform the same actions, and receive the same responses.
Imagine the external application as a restaurant’s kitchen, and ServiceNow as the customer.
The restaurant can change its menu or how it cooks meals (server-side changes) without telling the customer. They can process their data the way they want, but still what they provide as a web service doesn’t change.
Or customer can change the way they eat the meal, without directly affecting the kitchen. Its on them how they use what they got.
Both sides evolve independently, as long as they stick to the agreed way of ordering and serving.
2. Statelessness
Systems that follow the REST paradigm are stateless, meaning that the server does not need to know anything about what state the client is in and vice versa. In this way, both the server and the client can understand any message received, even without seeing previous messages. This constraint of statelessness is enforced through the use of resources, rather than commands. Resources are the nouns of the Web - they describe any object, document, or thing that you may need to store or send to other services.
Because REST systems interact through standard operations on resources, they do not rely on the implementation of interfaces.
These constraints help RESTful applications achieve reliability, quick performance, and scalability, as components that can be managed, updated, and reused without affecting the system as a whole, even during operation of the system.
Each request ServiceNow makes stands on its own. The server doesn’t have to remember what you asked for before.
It’s like every time you place an order at a restaurant, you hand over a note with all the details, so the waiter doesn’t need to recall your previous meal. This makes everything simpler, more efficient, and easier to scale.
Video Text:
API stands for Application Programming Interface.
Imagine you’re in a restaurant:
You (the client) ask the waiter (the API) for a dish (data).
The waiter talks to the kitchen (the external provider) and brings back your meal (the response).
You didn’t need to cook it yourself or even know how the kitchen works. You just made a simple request and got what you wanted.
In the same way, ServiceNow doesn’t need to know all the details about the external app’s database. It just needs to know how to ask (the endpoint, headers, and method) and how to understand the answer (the response data).
Video Text:
Communication between Client and Server
In a REST architecture, clients issue requests to fetch or change resources, while servers reply with responses.
Let’s explore the common methods used to send these requests and provide responses.
Video Text:
Making Requests
In a RESTful setup, the client must send a request to the server to retrieve or modify data. Each request includes:
An HTTP verb (GET, POST, PUT/PATCH, DELETE) specifying the type of action.
Headers to pass along extra details about the request.
A Path to a resource indicating what you want to access or change.
An Authentication restricting who can access
Attention !
These are theory lectures. We will be configuring everything on our instance (PDI) later on, but i wanted to explain the concepts on already configured REST Message, so you see from the start how it could be configured and look.
Don't worry that you don't have this configured yet, we will configure everything in upcoming lectures.
I just think you will learn better if you will see some concepts multiple times, thats why first i show theory and then explaing how to configure from scratch, which is more practical.
Video Text:
HTTP Methods
When ServiceNow needs information from a RESTful web service, it sends such an HTTP request. Typically, these four main methods are used:
GET: Retrieve existing data.
POST: Create new data.
POST: Create new data.
PUT/PATCH: Update existing data.
DELETE: Remove data.
For instance, if ServiceNow wants the current weather for a city, it can send a GET request to a weather service’s URL, like https://api.weatherprovider.com/current?city=London. If everything works correctly, the server replies with a 200 OK status and returns weather details in a format such as JSON, for example: { "temperature": "15°C", "condition": "cloudy" }.
Video Text:
Headers and Accept parameters
Beyond choosing the right HTTP verb, clients can also include headers in their requests. One key header is Accept, which tells the server what kinds of content the client can handle. The server then aims to return the response in one of those supported formats.
MIME Types (Multipurpose Internet Mail Extensions) define these formats, using a type/subtype structure. Two common data exchange formats are JSON and XML:
application/json for JSON data
application/xml for XML data
If you specify Accept: application/json in your request, you’re telling the server: “I prefer JSON.” If it can’t provide JSON but you also listed application/xml, the server might respond with XML instead. This flexibility ensures you get data in a format ServiceNow can easily process.
For example, if ServiceNow wants the current weather for a city (like London), it might send a GET request to a weather service’s URL:
GET <https://api.weatherprovider.com/current?city=London>
Accept: application/json, application/xml
This request means ServiceNow will accept either JSON or XML. If the server returns JSON, it might look like this:
HTTP/1.1 200 OK
Content-Type: application/json
{
"temperature": "15°C",
"condition": "cloudy"
}
If it decides to return XML instead, you might see:
Content-Type: application/xml
<weather>
<temperature>15°C</temperature>
<condition>cloudy</condition>
</weather>
In ServiceNow’s Outbound REST Message configuration, you can add the Accept header directly. Just as you chose the HTTP verb (GET) and specified the endpoint (https://api.weatherprovider.com/current?city=${city}), you can also say Accept: application/json to ensure the data is returned as JSON. If you include application/xml as well, the server has the option to send data in XML when JSON isn’t available.
Short Analogy:
Similarly, just like a restaurant specifies which types of payment it accepts (credit card, cash, etc.), the Accept header ensures that ServiceNow receives data in a format it can process. This way, both ServiceNow and the server communicate effectively, avoiding misunderstandings and ensuring smooth transactions.
What is JSON?
JSON (JavaScript Object Notation) is a lightweight data format used to represent structured data. It’s easy for humans to read and write, and straightforward for machines to parse and generate. JSON has become one of the most common formats for exchanging data between clients and servers in RESTful APIs.
Key Points:
Text-Based Format: JSON is plain text, making it easy to transfer across networks.
Language-Neutral: Although inspired by JavaScript, JSON can be used with any programming language, including the ServiceNow platform.
Structured and Self-Describing: JSON uses a simple syntax with key-value pairs and arrays, making data clear and hierarchical.
JSON Structure
A JSON object is enclosed in curly braces { }. Inside, data is represented as key-value pairs. Keys are always strings, and values can be:
Strings
Numbers
Booleans (true/false)
Objects (another set of key-value pairs)
Arrays (ordered lists of values)
null
Example:
{
"name": "Alice",
"age": 30,
"isEmployee": true,
"skills": ["ServiceNow", "JavaScript", "REST"],
"address": {
"city": "New York",
"postalCode": "10001"
}
}
This JSON object describes a person named Alice, her age, employment status, skill set, and address details. Notice how key-value pairs are separated by commas, and arrays or objects nest data for clarity.
JSON in RESTful APIs
When ServiceNow makes a request to a RESTful API, it often specifies Accept: application/json to indicate it wants the response in JSON format. The server then returns data in JSON, allowing ServiceNow to parse it easily.
For example, retrieving weather data might yield:
{
"temperature": "15°C",
"condition": "cloudy",
"humidity": 65
}
ServiceNow can then use script logic to extract these values and display them on a form or store them in a table.
Why JSON Matters to ServiceNow Integrations
Ease of Integration: Since JSON is widely supported, ServiceNow can interact with most APIs that provide or accept JSON data.
Simple Parsing and Serialization: In server-side scripts, ServiceNow developers can quickly parse JSON strings into JavaScript objects and vice versa, making data manipulation straightforward.
Reduced Complexity: JSON’s clear structure makes it easy to understand what data is being returned, speeding up development and troubleshooting.
JSON vs. Other Formats
JSON vs. XML: Both can represent complex data, but JSON is typically more concise and easier to parse, with less overhead.
JSON vs. HTML: HTML is for displaying content on web pages, while JSON is purely for data exchange. JSON doesn’t handle layout or styling—it focuses solely on representing data in a structured way.
For most integrations, JSON’s simplicity, readability, and language neutrality make it a preferred choice.
Working with JSON in ServiceNow
It’s important to remember that JSON data is initially just a string. To work with it in scripts, you need to parse it into a JavaScript object. Once parsed, you can easily read and manipulate the data.
Parsing JSON:
ServiceNow provides the JSON() API in server-side scripts. For example, if you receive a JSON string from a REST API call, you can do something like:
var jsonString = '{
"name": "Alice",
"age": 30,
"isEmployee": true,
"skills": ["ServiceNow", "JavaScript", "REST"],
"address": {
"city": "New York",
"postalCode": "10001"
}
}';
// Parse the JSON string into a JavaScript object
var dataObj = JSON.parse(jsonString);
Now dataObj is a JavaScript object, and you can access its properties directly:
gs.info("Name: " + dataObj.name); // "Alice"
gs.info("Age: " + dataObj.age); // 30
gs.info("City: " + dataObj.address.city); // "New York"
Modifying Data:
Since dataObj is now a regular JavaScript object, you can modify its values, add new properties, or remove existing ones:
dataObj.skills.push("IntegrationHub"); // Add a new skill
dataObj.age = 31; // Update Alice's age
delete dataObj.isEmployee; // Remove the isEmployee property
Re-Stringifying the Object:
If you need to send the updated data back as JSON in another request, you can convert the object back to a JSON string:
var updatedJsonString = JSON.stringify(dataObj);
gs.info(updatedJsonString);
This updatedJsonString can then be used as a request body in a POST or PUT request, or logged for debugging purposes.
Summary:
JSON is initially a string: You receive it as text from APIs.
Parse JSON into an object: Use json.parse() to turn it into a JavaScript object you can manipulate.
Manipulate and re-serialize: Add, remove, or change properties, then convert it back to a string with json.stringify() if needed.
By understanding these steps, you can integrate JSON data seamlessly into your ServiceNow workflows, using it to power dynamic interfaces, automate tasks, and connect to external systems with ease.
Video Text:
In RESTful APIs, every request must include a path that specifies the exact resource the client wants to interact with. The path is part of the endpoint URL and provides a clear route to the desired data or functionality.
Key Points:
Structure of Paths:
Paths are designed to be clear and descriptive, often following a hierarchical structure. The first segment of the path is typically the plural form of the resource name, making nested paths easier to read and understand.
Example Structure (Weather API):
Consider https://api.openweathermap.org/data/2.5/weather. This indicates you’re accessing the weather resource within the OpenWeatherMap API. Even if you’ve never seen this URL before, the path conveys its purpose clearly.
Specificity:
Paths should include all necessary information to locate a resource. For collections, no ID is needed. For example, a POST to https://api.openweathermap.org/data/2.5/weather doesn’t require an ID; the server uses query parameters to determine what data to return.
Accessing Single Resources:
To get a specific resource, append identifying details to the path. For example:
GET <https://api.openweathermap.org/data/2.5/weather?q=London&appid=${apikey}&units=metric>
Here, query parameters (q=London, appid=${apikey}, units=metric) provide the details needed to retrieve London’s weather data.
ServiceNow Context:
When configuring an Outbound REST Message in ServiceNow, it’s essential to define the endpoint path accurately. By setting up variables like ${city}, ${apikey}, and ${units}, you can easily adjust queries without modifying the entire path. This approach leads to more reliable and maintainable integrations.
Paths and the Restaurant Analogy
Analogy:
Think of the path in a RESTful request like navigating a restaurant’s menu. The menu is divided into categories—appetizers, main courses, desserts—and each dish within a category has a unique number.
Hierarchical and Descriptive:
Just as “/maincourses/12” would tell you to order dish #12 in the main course section, a REST path guides you to the exact resource. There’s no confusion about where to look or what you’re getting.
Clarity Over Guesswork:
You wouldn’t ask for “the second appetizer” without mentioning which restaurant you’re in or which category you’re referencing. Similarly, REST paths specify the exact resource so there’s no guesswork.
No Extra IDs Needed for Collections:
When creating something new (like placing a custom order), you don’t need to provide an ID upfront. The restaurant (server) will assign one. In the same way, a POST request doesn’t always need an ID—the server handles it behind the scenes.
Video Text:
Authentication
Many APIs require authentication to ensure that only authorized clients can access their data. When working with RESTful APIs, authentication often involves passing credentials or tokens so the server knows who you are and what you’re allowed to do. Common methods include:
Basic Authentication: A username and password combination, often encoded and sent in a header.
OAuth 2.0: A more complex method using tokens that expire and can be refreshed, allowing more secure, controlled access.
With proper authentication configured, ServiceNow can safely interact with external APIs, retrieve data, and perform actions without exposing sensitive information or breaking security rules.
Analogy:
Think of authentication as showing your ID at a restaurant before entering a special VIP lounge. If you don’t have the proper credentials, the waiter won’t let you in. With the right “ID” (API key, username/password, or token), the restaurant knows you’re allowed to access this exclusive area. Similarly, a properly configured REST Message with authentication tells the server you’re a trusted client, granting you access to the resources you need.
Video Text:
Hello everyone, and welcome back to our course on Scripted REST APIs and Integration in ServiceNow. In today's video, we're going to walk through the process of creating a scoped application called 'CityWeatherInfo' using ServiceNow's Studio. This application will help us manage and store weather data for various cities. So, let's dive right in!
We will primarily use Regular Studio. Why? Because it’s the most universal tool. Regular Studio is available on all ServiceNow instances without any additional licensing. This means you’ll be able to follow along no matter what version of ServiceNow you’re using.
We’ll also take a brief look at the New Studio. It’s a more modern version of Studio with an updated interface and improved features. I’ll show you how an app could be developed there, but since not all instances have it yet, we won’t fully switch to it.
Lastly, we won’t be using Creator Studio. Creator Studio is part of App Engine Studio, which is a paid add-on. It’s mostly designed for citizen developers—people building apps without writing much code. Since we want to focus on coding and scripting, Creator Studio isn’t the right tool for us.
So, we’ll stick to Regular Studio to keep things accessible, universal, and focused on coding, with just a quick tour of New Studio to keep you up to date.
First, let's open ServiceNow Studio. If you're not already logged in, go ahead and log into your ServiceNow instance. Once you're in, navigate to the All menu on the left-hand side and select System Applications, then click on Studio.
Studio is our integrated development environment within ServiceNow, where we'll be building our custom application.
Now, click on the Create Application button to start building our new application.
Let's fill in the details for our new application. In the Name field, enter 'CityWeatherInfo'. This name clearly indicates that our application deals with weather information. Next, add a Description like 'Retrieves weather info for given cities'. This helps others understand the purpose of the application at a glance.
Make sure to select Scoped under Advanced Settings. Scoped applications help keep our customizations organized and prevent conflicts with other applications.
Once you've entered all the details, click Create.
After a moment, Studio will prompt you to continue. Click on Continue in Studio (Advanced).
Now, you'll see the Select Application dialog. Click on the WeatherLookup application to open it in Studio.
Video Text:
We are going to set up roles for our application. Roles are essential to ensure proper access control and define what specific users can and cannot do.
We will create three main roles:
Admin Role
This role is for the administrator of the application.
The admin is responsible for managing everything within the app, including configuration, settings, and overall control.
User Role
This role is for the end user—the person who interacts with the application to perform specific tasks.
It ensures the user has the necessary access to use the app’s core functionalities.
Integration Role
This role is for integration users.
It allows integration users or automated processes to access data from our application. For example, in this scenario, we’ll be integrating with an OpenWeather service to fetch and manipulate data such as temperature and weather information.
The integration role will have specific privileges to pull data from external services and update relevant fields inside our app.
Why These Roles?
Using roles allows us to isolate responsibilities. For example:
The admin has full control but isn’t necessarily the one interacting with external data.
The user only accesses core application features.
The integration role ensures external systems can interact with our app securely without granting unnecessary permissions.
Roles also help us protect our application from unauthorized access, ensuring security and scalability.
Video Text:
Creating the Groups
Let’s start by creating our three groups:
Go to User Administration > Groups.
Click on New to create a new group.
For the first group, name it Weather Administrator.
Assign the Weather Administrator role to this group.
Repeat this process for the next two groups:
Weather User group → Assign the Weather User role.
Weather Integration group → Assign the Weather Integration role.
Groups are a great way to manage permissions efficiently. Instead of assigning roles directly to individual users, you can add users to groups and let the group handle role management.
Creating the Users
Now that we have our groups, let’s create the users.
Go to User Administration > Users.
Click New and create the first user:
Username: weather_admin
Full Name: Weather Administrator
Add this user to the Weather Administrator Group.
Next, create the second user:
Username: weather_user
Full Name: Weather User
Add this user to the Weather User Group.
Finally, create the integration user:
Username: weather_integration
Full Name: Weather Integration User
Add this user to the Weather Integration Group.
Here’s an extra step: Scroll down to the "Allow web services" checkbox and enable it.
Enabling this option ensures the user can only be used for API integrations and not for logging into the UI.
By doing this, we’re setting up a dedicated integration user that is secure and follows best practices for web services.
Reviewing the Setup
Let’s quickly review what we’ve done:
- We created three groups: Weather Administrator, Weather User, and Weather Integration.
- Each group was assigned the corresponding role.
- We created three users and added them to their respective groups.
- For the integration user, we enabled web service access only, making it ready for use in integrations.
Why Is This Important?
Using groups and roles allows us to manage permissions cleanly and efficiently. Instead of assigning roles individually to each user, you add users to groups, and the group takes care of the access. This keeps the system organized and makes future changes much easier.
The integration user with web service access only is particularly important because it ensures secure API-based interactions, preventing any unauthorized use of the account through the UI.
Hi everyone! In this video, I’m going to show you two ways to test your brand-new CityWeather application:
REST API Explorer — a built-in tool in ServiceNow.
Postman — think of it like a friendly postal worker who can carry “letters” (your requests) back and forth between your computer and ServiceNow.
Why do we need these tools?
Well, in real life, whenever you mail a package, you want to make sure it reaches the right address and you get the correct package in return. In the world of APIs, these tools help us do exactly that—send requests and verify the responses we get back.
But before we start adding lots of features and complex logic to our CityWeather application, it’s important to test the basics first.
Imagine trying to send a heavily packed, oversized package without checking if it even arrives at the destination. Similarly, in API development, you want to ensure that your requests are successfully sent and received before building more intricate functionalities. This foundational testing helps prevent bigger issues down the line and ensures that your application runs smoothly as you add more value.
Let’s start with something already in ServiceNow: REST API Explorer. It’s a bit like a “preview window” where you can check if your requests to the CityWeather table are working before you go any further.
Open REST API Explorer
In ServiceNow, find the All menu on the left side.
Type “REST API Explorer” and click it.
Pick an API
You’ll see different options. For a quick test, we can use the Table API which works with most tables in ServiceNow.
Select your CityWeather table.
Set Query Parameters
For example, if you want to filter by city name, you could add a parameter like sysparm_query=city=Gaptsakh.
Hit Send to see if it fetches only records for Gaptsakh.
Check the Response
You’ll see a JSON response. If it shows the correct city data, great! If not, you might need to adjust your query or check your table name.
Speaker (Voiceover)
REST API Explorer is awesome for a having a quick test, but there is one limitation… it always uses your currently logged-in user. If you want to see how things work with different credentials or advanced security (like OAuth), you’ll need a bit more power. And that’s where Postman comes in.
Here is code from the lecture:
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
// implement resource here
// 1. Get the city name from the path parameter
var cityName = request.pathParams.city;
if (!cityName) {
response.setStatus(400); // Bad request
response.setBody({error: 'No city provided'});
return;
}
// 2. Query the CityWeatherInfo table
var grWeather = new GlideRecord('x_793388_cityweath_cityweatherinfo');
grWeather.addQuery('city', cityName);
grWeather.query();
// 3. If no record is found, return 404 (Record not found)
if (!grWeather.next()) {
response.setStatus(404); // Record not found
response.setBody({error: 'City not found'});
return;
}
// 4. Build the response object
var result = {
city: grWeather.getValue('city'),
temperature: grWeather.getValue('temperature'),
condition: grWeather.getValue('condition'),
humidity: grWeather.getValue('humidity'),
pressure: grWeather.getValue('pressure'),
};
// 5. Return the data
response.setStatus(200); // Success
response.setBody(result);
})(request, response);
Lecture's code (just copy and paste if you dont want to follow along):
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
// implement resource here
// 1. Declare an empty array for the response
var results = [];
// 2. Retrieve query parameters from the request
var city = request.queryParams.city; // City name
var condition = request.queryParams.condition; // Weather condition (Sunny, Cloudy etc)
var humidity = request.queryParams.humidity; // humidity level
var pressure = request.queryParams.pressure; // pressure level
var temperature = request.queryParams.temperature; // temperature value
// 3. Validate query parameters
if (!city && !condition && !humidity && !pressure && !temperature) {
response.setStatus(400); // Bad request
response.setBody({
error: 'No query parameters provided. Please provide city, condition, humidity, pressure or temperature'
});
return;
}
// 4. Initialize GlideRecord for the CityWeather Info
var grWeather = new GlideRecord('x_793388_cityweath_cityweatherinfo');
// 5. Add queries based on parameters provided
if (city) {
grWeather.addQuery('city', city); // Exact match on the city
}
if (condition) {
grWeather.addQuery('condition', 'LIKE', condition); // Contains match on the condition
}
if (humidity) {
grWeather.addQuery('humidity', humidity); // Exact match on the humidity
}
if (pressure) {
grWeather.addQuery('pressure', pressure); // Exact match on the pressure
}
if (temperature) {
grWeather.addQuery('temperature', temperature); // Exact match on the temperature
}
grWeather.query(); // querry the results
// 6. Process the results and build the response
while (grWeather.next()) {
results.push({
number: grWeather.getValue('number'),
city: grWeather.getValue('city'),
condition: grWeather.getValue('condition'),
humidity: grWeather.getValue('humidity'),
pressure: grWeather.getValue('pressure'),
temperature: grWeather.getValue('temperature'),
link: {
self: 'https://dev244043.service-now.com/x_793388_cityweath_cityweatherinfo.do?sys_id=' + grWeather.getUniqueValue()
}
});
}
// 7. Handle cases when no records are found
if (results.length == 0) {
response.setStatus(404); // Not Found
response.setBody({
error: 'No cities found matching the criteria'
});
return;
}
// 8. Return the data
response.setStatus(200); // OK
response.setBody(results);
})(request, response);
Lecture's code:
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
// implement resource here
try {
// 1. Parse the request body
var requestBody = request.body.data; // Parses the incoming JSON payload
if (!requestBody || !requestBody.city || !requestBody.temperature || !requestBody.condition) {
response.setStatus(400); // Bad Request
response.setBody({ error: 'Invalid input. City, temperature, and condition are required.' });
return;
}
// 2. Initialize a GlideRecord for the CityWeather Info table
var grWeather = new GlideRecord('x_793388_cityweath_cityweatherinfo');
grWeather.initialize();
// 3. Set the fields with values from the request body
grWeather.setValue('city', requestBody.city);
grWeather.setValue('temperature', requestBody.temperature);
grWeather.setValue('condition', requestBody.condition);
grWeather.setValue('humidity', requestBody.humidity || null);
grWeather.setValue('pressure', requestBody.pressure || null);
// 4. Insert the new record into the table
var sysID = grWeather.insert();
// 5. Build the response object
var result = {
sys_id: sysID,
number: grWeather.getValue('number'),
city: grWeather.getValue('city'),
temperature: grWeather.getValue('temperature'),
condition: grWeather.getValue('condition'),
humidity: grWeather.getValue('humidity'),
pressure: grWeather.getValue('pressure')
};
// 6. Return the response
response.setStatus(201); // Created
response.setBody(result);
} catch (error) {
// Handle unexpected errors
response.setStatus(500); // Internal Server Error
response.setBody({ error: 'An error occurred while processing your request.', details: error.message });
}
})(request, response);
Request body:
{ "city": "Lisbona", "temperature": 20, "condition": "Sunny", "humidity": 50, "pressure": 1015 }
Lecture's code:
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
// implement resource here
try {
// 1. Extract the city name from the path parameter
var cityName = request.pathParams.city;
if (!cityName) {
response.setStatus(400); // Bad Request
response.setBody({
error: "City parameter is required in the path."
});
return;
}
// 2. Parse the request body for the fields to update
var requestBody = request.body.data;
if (!requestBody) {
response.setStatus(400); // Bad Request
response.setBody({
error: "Request body is required. Please provide which field and with what values to update."
});
return;
}
// 3. Initialize a GlideRecord for the CityWeatherInfo table
var grWeather = new GlideRecord('x_793388_cityweath_cityweatherinfo');
grWeather.addQuery('city', cityName);
grWeather.query();
// 4. Check if the record exists
if (!grWeather.next()) {
response.setStatus(404); // Not Found
response.setBody({
error: "City not found: " + cityName
});
return;
}
// 5. Update the fields provided in the request body
if (requestBody.temperature) {
grWeather.setValue('temperature', requestBody.temperature);
}
if (requestBody.condition) {
grWeather.setValue('condition', requestBody.condition);
}
if (requestBody.humidity) {
grWeather.setValue('humidity', requestBody.humidity);
}
if (requestBody.pressure) {
grWeather.setValue('pressure', requestBody.pressure);
}
// 6. Save the changes to the record
grWeather.update();
// 7. Build the response object with updated values
var result = {
sys_id: grWeather.getValue('sys_id'),
number: grWeather.getValue('number'),
city: grWeather.getValue('city'),
temperature: grWeather.getValue('temperature'),
condition: grWeather.getValue('condition'),
humidity: grWeather.getValue('humidity'),
pressure: grWeather.getValue('pressure')
};
// 8. Return the updated record
response.setStatus(200); // OK
response.setBody(result);
} catch (error) {
// Handle unexpected errors
response.setStatus(500); // Internal Server Error
request.setBody({
error: 'An error occured while processing your request.',
details: error.message
});
}
})(request, response);
Request Body Example:
{
"temperature": 20,
"condition": "Sunny",
"humidity": 50,
"pressure": 1015
}
Lecture's Code:
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
// implement resource here
try {
// 1. Extract the city name from the path parameter
var cityName = request.pathParams.city;
if (!cityName) {
response.setStatus(400); // Bad request
response.setBody({
error: 'City parameter is required in the path'
});
return;
}
// 2. Initialize a GlideRecord for the CityWeatherInfo table
var grWeather = new GlideRecord('x_793388_cityweath_cityweatherinfo');
grWeather.addQuery('city', cityName);
grWeather.query();
// 3. Check if the record exists
if (!grWeather.next()) {
response.setStatus(404); // Not found
response.setBody({
error: "City not found: " + cityName
});
return;
}
// 4. Delete the record
grWeather.deleteRecord();
// 5. Return a confirmation response
var result = {
message: 'City weather record deleted sucessfully',
city: cityName
};
response.setStatus(200); // OK
response.setBody(result);
} catch (error) {
response.setStatus(500); // Internal Server Error
response.setBody({
error: 'An error occured while processing your request',
details: error.message
});
}
})(request, response);
GetMultipleCityWeather (v2) Script after adjustments:
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
// implement resource here
// 1. Declare an empty array for the response
var results = [];
// 2. Retrieve query parameters from the request
var city = request.queryParams.city; // City name
var condition = request.queryParams.condition; // Weather condition (Sunny, Cloudy etc)
var humidity = request.queryParams.humidity; // humidity level
var pressure = request.queryParams.pressure; // pressure level
var temperature = request.queryParams.temperature; // temperature value
// 3. Validate query parameters
if (!city && !condition && !humidity && !pressure && !temperature) {
response.setStatus(400); // Bad request
response.setBody({
error: 'No query parameters provided. Please provide city, condition, humidity, pressure or temperature'
});
return;
}
// 4. Initialize GlideRecord for the CityWeather Info
var grWeather = new GlideRecord('x_793388_cityweath_cityweatherinfo');
// 5. Add queries based on parameters provided
if (city) {
grWeather.addQuery(city);
}
if (condition) {
grWeather.addQuery(condition);
}
if (humidity) {
grWeather.addQuery(humidity);
}
if (pressure) {
grWeather.addQuery(pressure);
}
if (temperature) {
grWeather.addQuery(temperature);
}
grWeather.query(); // querry the results
// 6. Process the results and build the response
while (grWeather.next()) {
results.push({
number: grWeather.getValue('number'),
city: grWeather.getValue('city'),
condition: grWeather.getValue('condition'),
humidity: grWeather.getValue('humidity'),
pressure: grWeather.getValue('pressure'),
temperature: grWeather.getValue('temperature'),
link: {
self: 'https://dev244043.service-now.com/x_793388_cityweath_cityweatherinfo.do?sys_id=' + grWeather.getUniqueValue()
}
});
}
// 7. Handle cases when no records are found
if (results.length == 0) {
response.setStatus(404); // Not Found
response.setBody({
error: 'No cities found matching the criteria'
});
return;
}
// 8. Return the data
response.setStatus(200); // OK
response.setBody(results);
})(request, response);
Business Rule's code (remember to change to your app scope name/table name):
(function executeRule(current, previous /*null when async*/ ) {
if (!current.city) {
gs.info('WEATHER: City not provided; skipping weather fetch');
return;
}
try {
var r = new sn_ws.RESTMessageV2('x_793388_cityweath.OpenWeather', 'GetCurrentWeather');
r.setStringParameterNoEscape('city name', current.city); // take city from current record
r.setStringParameterNoEscape('units', 'metric'); // Metric is default
r.setStringParameterNoEscape('API key', gs.getProperty('x_793388_cityweath.weather_api_key')); // Store API key securely in property
var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
gs.info('WEATHER: response type is:' + responseBody);
gs.info('WEATHER: responseBody: ' + responseBody);
gs.info('WEATHER: httpStatus: ' + httpStatus);
if (httpStatus == 200) {
var responseBody_parsed = JSON.parse(responseBody);
gs.info('WEATHER: responseBody_parsed type is:' + typeof responseBody_parsed);
var temp = (responseBody_parsed.main && responseBody_parsed.main.temp) ? responseBody_parsed.main.temp : 0;
gs.info('WEATHER: temp is:' + temp);
var condition = (responseBody_parsed.weather && responseBody_parsed.weather.length > 0) ? responseBody_parsed.weather[0].description : 'N/A';
gs.info('WEATHER: condition is:' + condition);
var humidity = (responseBody_parsed.main && responseBody_parsed.main.humidity) ? responseBody_parsed.main.humidity : 0;
gs.info('WEATHER: humidity is:' + humidity);
var pressure = (responseBody_parsed.main && responseBody_parsed.main.pressure) ? responseBody_parsed.main.pressure : 0;
gs.info('WEATHER: pressure is:' + pressure);
current.temperature = temp;
current.condition = condition;
current.humidity = humidity;
current.pressure = pressure;
current.update();
gs.info('WEATHER: Data updated for: ' + current.city);
} else {
gs.warn('WEATHER: OpenWeather returned HTTP status: ' + httpStatus);
}
} catch (ex) {
var message = ex.message;
gs.error('WEATHER: ' + message);
}
})(current, previous);
Scheduled Job's code (make sure to change API/Table name):
(function() {
// 1. Query the CityWeatherInfo table
var cityWeatherGR = new GlideRecord('x_793388_cityweath_cityweatherinfo');
cityWeatherGR.query();
// 2. Loop through each record
while (cityWeatherGR.next()) {
if (!cityWeatherGR.city) {
gs.info('WEATHER SCHEDULED JOB: City not provided; skipping weather fetch');
return;
}
try {
var r = new sn_ws.RESTMessageV2('x_793388_cityweath.OpenWeather', 'GetCurrentWeather');
r.setStringParameterNoEscape('city name', cityWeatherGR.city); // take city from current record
r.setStringParameterNoEscape('units', 'metric'); // Metric is default
r.setStringParameterNoEscape('API key', gs.getProperty('x_793388_cityweath.weather_api_key')); // Store API key securely in property
var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
if (httpStatus == 200) {
var responseBody_parsed = JSON.parse(responseBody);
var temp = (responseBody_parsed.main && responseBody_parsed.main.temp) ? responseBody_parsed.main.temp : 0;
var condition = (responseBody_parsed.weather && responseBody_parsed.weather.length > 0) ? responseBody_parsed.weather[0].description : 'N/A';
var humidity = (responseBody_parsed.main && responseBody_parsed.main.humidity) ? responseBody_parsed.main.humidity : 0;
var pressure = (responseBody_parsed.main && responseBody_parsed.main.pressure) ? responseBody_parsed.main.pressure : 0;
cityWeatherGR.temperature = temp;
cityWeatherGR.condition = condition;
cityWeatherGR.humidity = humidity;
cityWeatherGR.pressure = pressure;
cityWeatherGR.update();
} else {
gs.warn('WEATHER SCHEDULED JOB: OpenWeather returned HTTP status: ' + httpStatus);
}
} catch (ex) {
var message = ex.message;
gs.error('WEATHER SCHEDULED JOB: ' + message);
}
};
})();
UI Page HTML:
<j:jelly xmlns:j="jelly:core" xmlns:g="glide">
<!--
UI PAGE: CityWeatherInfo Documentation
PURPOSE:
This UI Page summarizes all the configurations for our CityWeatherInfo app:
- Roles & Groups
- Table & Fields
- Scripted REST API Endpoints
- Security (ACLs, OAuth, IP Policies)
- Business Rule & Scheduled Job
- Mockaroo & Testing Tools
- Dashboards
-->
<html>
<head>
<title>CityWeatherInfo - Full Documentation</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 15px;
line-height: 1.4em;
}
h1, h2, h3 {
color: #03396c;
}
h1 {
margin-top: 0;
}
ul {
margin-left: 1.5em;
}
code {
background-color: #eee;
padding: 2px 4px;
font-family: Consolas, monospace;
}
hr {
margin: 25px 0;
}
.section {
margin-bottom: 30px;
}
</style>
</head>
<body>
<h1>CityWeatherInfo Application - Documentation</h1>
<p>
Welcome! This documentation describes the$[SP]<strong>CityWeatherInfo</strong>$[SP]application you built in ServiceNow.
It covers$[SP]<em>Roles & Groups, Table & Fields, Scripted REST API Endpoints, Security (ACLs, OAuth, IP Policies),
Business Rules, Scheduled Jobs, Dashboards</em>, and how to$[SP]<em>test</em>$[SP]them.
</p>
<hr class="section"/>
<div class="section">
<h2>1. Introduction & Purpose</h2>
<p>
The$[SP]<strong>CityWeatherInfo</strong>$[SP]application manages weather data for various cities.
We allow inbound REST calls to create, read, update, and delete weather records. Additionally, we fetch external
weather data from the$[SP]<em>OpenWeather</em>$[SP]public API, ensuring each city's information is automatically
updated (via Business Rule or a Scheduled Job).
</p>
</div>
<hr class="section"/>
<div class="section">
<h2>2. App Overview & Roles</h2>
<p><strong>Scoped Application Name:</strong>$[SP]<code>CityWeatherInfo</code>$[SP]</p>
<p><strong>Application Scope:</strong>$[SP]<code>x_793388_cityweath</code></p>
<ul>
<li><strong>Roles Created:</strong></li>
<ul>
<li><strong>Weather Administrator</strong>$[SP]: Full control over the app (admin responsibilities).</li>
<li><strong>Weather User</strong>$[SP]: End users who can view and use core functionalities.</li>
<li><strong>Weather Integration</strong>$[SP]: For integration users or automated processes that call the API.</li>
</ul>
<li><strong>Groups & Users:</strong>
<ul>
<li>Three groups corresponding to the above roles.</li>
<li>Three users:$[SP]<code>weather_admin, weather_user, weather_integration</code>.</li>
<li>The integration user has$[SP]<em>Allow web services</em>$[SP]enabled, preventing UI login.</li>
</ul>
</li>
</ul>
</div>
<hr class="section"/>
<div class="section">
<h2>3. Table & Fields</h2>
<p>
<strong>Table Name:</strong>$[SP]<code>x_793388_cityweath_cityweatherinfo</code><br/>
Used to store city weather data. Notable fields:
</p>
<ul>
<li><code>city</code>$[SP](String)$[SP]- The city’s name (required).</li>
<li><code>temperature</code>$[SP](Integer)$[SP]- Temperature in Celsius (or user’s chosen unit).</li>
<li><code>condition</code>$[SP](String)$[SP]- Describes weather (e.g., “Cloudy,” “Rainy,” etc.).</li>
<li><code>humidity</code>$[SP](Integer)$[SP]- Represents humidity percentage.</li>
<li><code>pressure</code>$[SP](Integer)$[SP]- Atmospheric pressure in hPa.</li>
<li><code>number</code>$[SP](Auto-generated unique ID).</li>
</ul>
</div>
<hr class="section"/>
<div class="section">
<h2>4. Scripted REST API & Endpoints</h2>
<p>
<strong>Scripted REST Service:</strong>$[SP]<code>CityWeatherInfo</code><br/>
<strong>API Namespace:</strong>$[SP]<code>x_793388_cityweath</code><br/>
<strong>Base Path:</strong>$[SP]<code>/api/x_793388_cityweath/cityweatherinfo</code>
</p>
<ul>
<li><strong>Active Versions:</strong>$[SP](v1, v2, v3). We eventually$[SP]<em>deactivated</em>$[SP]v1 & v2$[SP]for security reasons.</li>
<li><strong>Resources:</strong>
<ul>
<li><code>GET /weather/{city}</code>$[SP]- Retrieve single city’s data.</li>
<li><code>GET /weather</code>$[SP]- Retrieve multiple cities (optional query params like$[SP]city, condition, humidity, etc.).</li>
<li><code>POST /weather</code>$[SP]- Create new city weather record.</li>
<li><code>PATCH /weather/{city}</code>$[SP]- Update certain fields of a city’s weather.</li>
<li><code>DELETE /weather/{city}</code>$[SP]- Remove a city’s record from the table.</li>
</ul>
</li>
<li><strong>Versioning:</strong>
<ul>
<li>We enabled versioning so older clients can keep using v1, while new enhancements go to v2 or v3.</li>
<li>Eventually,$[SP]we$[SP]deactivated v1 & v2$[SP]to close security gaps.</li>
</ul>
</li>
</ul>
<p>
<em>See the 'Resources' related list on the Scripted REST Service record for full details.</em>
</p>
</div>
<hr class="section"/>
<div class="section">
<h2>5. Security Configuration</h2>
<p>
Our security approach has multiple layers:
</p>
<ol>
<li>
<strong>Table Settings:</strong>
<ul>
<li>“Allow access to this table via web services” is not needed because we use Scripted REST, not the Table API.</li>
</ul>
</li>
<li>
<strong>ACLs (Access Controls):</strong>
<ul>
<li>Default ACL:$[SP]<code>scripted_rest_external_default</code>$[SP]allowed$[SP]<code>snc_internal</code>.</li>
<li>We replaced it with custom ACLs requiring roles$[SP]<code>cityweather_api</code>$[SP]and$[SP]<code>cityweather_resource</code>.</li>
<li>This ensures only authorized users can call or see the data (e.g., the integration user in the Weather Integration group).</li>
</ul>
</li>
<li>
<strong>Table-Level ACL Enforcement (GlideRecordSecure):</strong>
<ul>
<li>We replaced$[SP]<code>GlideRecord</code>$[SP]with$[SP]<code>GlideRecordSecure</code>$[SP]in scripts to respect table ACLs at the code level.</li>
</ul>
</li>
<li>
<strong>OAuth Authentication:</strong>
<ul>
<li>We created an OAuth API endpoint for external clients$[SP]<em>(System OAuth → Application Registry)</em>.</li>
<li>We restricted the API by setting$[SP]<em>Enforce OAuth = true</em>$[SP]in the Scripted REST API or using$[SP]<em>API Access Policies</em>.</li>
</ul>
</li>
<li>
<strong>API Access Policies (Optional IP Filters):</strong>
<ul>
<li>We added an$[SP]<em>API Access Policy</em>$[SP]for version 3, requiring the$[SP]<code>OAuth token</code>$[SP]authentication profile and filtering by IP addresses if needed.</li>
</ul>
</li>
<li>
<strong>OAuth Scopes:</strong>
<ul>
<li>Scope$[SP]<code>CityWeather_read</code>$[SP]for GET requests,$[SP]<code>CityWeather_delete</code>$[SP]for DELETE requests.</li>
<li>This ensures a token with$[SP]<code>CityWeather_read</code>$[SP]can’t delete records, etc.</li>
</ul>
</li>
</ol>
</div>
<hr class="section"/>
<div class="section">
<h2>6. Business Rule for Auto-Updating Weather</h2>
<p>
We created an$[SP]<em>async</em>$[SP]Business Rule named$[SP]<strong>Populate Weather Data</strong>$[SP]on the
$[SP]<code>CityWeatherInfo</code>$[SP]table. Whenever a user inserts or updates a record:
</p>
<ol>
<li>The rule calls our$[SP]<code>OpenWeather</code>$[SP]REST Message ($[SP]<em>GetCurrentWeather</em>).</li>
<li>It passes the$[SP]<code>city</code>$[SP]name,$[SP]<code>units=metric</code>$[SP], and the secure$[SP]<code>API key</code>.</li>
<li>It logs the response and updates$[SP]<code>temperature, condition, humidity, pressure</code>$[SP]in the record.</li>
<li>Runs asynchronously so users aren’t blocked while waiting for the external call.</li>
</ol>
<p>
<strong>Key Points:</strong><br/>
- Leverages$[SP]<em>Preview Script Usage</em>$[SP]snippet to build the code.<br/>
- Retrieves the API key from system property$[SP]<code>x_793388_cityweath.weather_api_key</code>.<br/>
- Logs each step via$[SP]<code>gs.info</code>$[SP]and$[SP]<code>gs.warn</code>.
</p>
</div>
<hr class="section"/>
<div class="section">
<h2>7. Scheduled Job for Batch Updates</h2>
<p>
To keep existing city records up to date, we added a$[SP]<strong>Scheduled Job</strong>$[SP]
that runs every 6 hours. The script:
</p>
<ol>
<li>Queries all rows in$[SP]<code>CityWeatherInfo</code>.</li>
<li>For each city,$[SP]calls$[SP]<em>OpenWeather → GetCurrentWeather</em>$[SP]similarly.</li>
<li>Updates$[SP]<code>temperature, condition, humidity, pressure</code>$[SP]in bulk.</li>
<li>Ensures ongoing freshness of data, even if nobody edits the record manually.</li>
</ol>
<p>
<strong>Performance Note:</strong>$[SP]If you have thousands of records, consider
breaking it into smaller chunks or staggering updates.
</p>
</div>
<hr class="section"/>
<div class="section">
<h2>8. Dashboards and Visualization</h2>
<p>
We created a$[SP]simple Dashboard to display city weather data, consisting of:
</p>
<ul>
<li>A$[SP]<strong>List Report</strong>$[SP]showing$[SP]<code>City, Condition, Temperature, Humidity, Pressure</code>.</li>
<li>An$[SP]optional$[SP]<strong>Bar Chart</strong>$[SP]comparing city temperatures.</li>
</ul>
<p>
Dashboards in ServiceNow typically refresh data upon page reload or after a set interval.
If you want truly streaming, real-time data, consider a$[SP]<em>Now Experience UI</em>$[SP]or a custom widget.
</p>
</div>
<hr class="section"/>
<div class="section">
<h2>9. Generating Demo Data with Mockaroo</h2>
<p>
To populate test data, we used$[SP]<strong>Mockaroo</strong>$[SP]. Steps included:
</p>
<ol>
<li>Defining a schema in mockaroo.com with$[SP]<code>City</code>,$[SP]<code>Temperature</code>, etc.</li>
<li>Exporting as CSV.</li>
<li>Using$[SP]<em>System Import Sets</em>$[SP]+ a$[SP]<em>Transform Map</em>$[SP]to load it into$[SP]<code>CityWeatherInfo</code>.</li>
</ol>
</div>
<hr class="section"/>
<div class="section">
<h2>10. Testing & Tools (REST API Explorer, Postman)</h2>
<p>
<strong>REST API Explorer</strong>$[SP]is built into ServiceNow—great for quick checks using your current user session.
<strong>Postman</strong>$[SP]is an external tool allowing more advanced testing (different creds, environments, etc.).
We used$[SP]both to confirm each resource$[SP](GET, POST, PATCH, DELETE)$[SP]works as expected.
</p>
</div>
<hr class="section"/>
<div class="section">
<h2>11. Summary & Next Steps</h2>
<p>
The$[SP]<strong>CityWeatherInfo</strong>$[SP]application now provides:
</p>
<ul>
<li>A$[SP]secure$[SP]<em>Scripted REST API</em>$[SP]with CRUD endpoints, versioning, and advanced filtering.</li>
<li>Integrated$[SP]<em>ACLs</em>$[SP],$[SP]<em>OAuth</em>$[SP],$[SP]<em>IP restrictions</em>$[SP], and$[SP]<em>OAuth Scopes</em>$[SP]for security.</li>
<li>A$[SP]<em>Business Rule</em>$[SP]for automatic updates on record insertion/update.</li>
<li>A$[SP]<em>Scheduled Job</em>$[SP]for periodic refresh of all city records.</li>
<li>Optional$[SP]<em>Dashboard</em>$[SP]to visualize weather data in near real-time.</li>
</ul>
<p>
You can continue enhancing the app by adding performance analytics, refining ACLs, or building custom UI experiences
(e.g., Service Portal).
</p>
</div>
<hr class="section"/>
<div class="section">
<h2>Questions or Feedback?</h2>
<p>
Feel free to reach out or leave comments. We hope this$[SP]<em>CityWeatherInfo</em>$[SP]application demonstration helps
you create robust, secure, and user-friendly integrations in ServiceNow.
</p>
</div>
</body>
</html>
</j:jelly>
ServiceNow - Learn Scripted REST APIs and Integration
Do you want to build secure and reliable integrations in ServiceNow? In this course, I will guide you step by step through creating Scripted REST APIs and Real-World integration projects. Whether you are new to ServiceNow or already have some experience, you will gain the skills to handle complex integrations with confidence.
What You Will Learn
Scripted REST APIs:
Build, test, and manage your own APIs in ServiceNow.
Create endpoints for common tasks such as creating, reading, updating, and deleting records.
Apply versioning to support ongoing changes without affecting current users.
Real Projects That Matter:
CityWeatherInfo Application:
Design a complete application to manage weather data for different cities.
Set up roles, groups, tables, and fields that form the backbone of the app.
Create multiple API endpoints to interact with external data from services like OpenWeather.
Implement a business rule that automatically updates weather data when records are added or changed.
Use a scheduled job to refresh data regularly and create simple dashboards to visualize information.
Two-Way Instance Integration:
Keep user records synchronized between two ServiceNow instances.
Use business rules to trigger REST calls when a user record is created or updated.
Compare update timestamps to ensure that only the most recent data is maintained across both systems.
Set up GET, PATCH, and POST requests with proper error handling to keep data consistent and secure.
Security Best Practices:
Learn how to configure Access Control Lists (ACLs) and OAuth settings to secure your APIs.
Understand how to apply IP restrictions and basic authentication to protect data transfers.
Use clear logging and error management techniques to troubleshoot integration issues effectively.
Testing and Troubleshooting:
Gain hands-on experience with ServiceNow’s REST API Explorer and external tools like Postman.
Follow step-by-step instructions to test each endpoint and validate that your integration works as intended.
Hands-On, Practical Learning:
Work on projects that mirror real ServiceNow challenges, ensuring you build skills that are directly applicable to your work.
Learn methods for updating integrations without disrupting live services.
About Your Instructor
I’m Lukasz Szumilas, a ServiceNow Developer and Consultant with real-world experience from companies like Accenture and Nelem Solutions. With over 8,600 followers on LinkedIn and more than 100 published articles, I bring simple, effective lessons based on practical challenges. I share my learnings to help you succeed in your ServiceNow career.
Why Enroll?
By the end of this course, you will have the confidence and skills to build and maintain robust integrations in ServiceNow. You will earn a certificate that confirms your expertise and be prepared to apply these techniques in real projects. Sign up today and take a big step forward in your ServiceNow career!