ServiceNow Integration
This guide demonstrates the principle steps involved in creating an integration between Ironclad and ServiceNow, utilizing the Ironclad public APIs and ServiceNow’s native integration capabilities.
The use case we demonstrate here is a typical legal intake process, where business teams make requests for various types of legal agreements from ServiceNow, and those requests are handled using Ironclad’s contract management capabilities. The various technical approaches used here, however, should be applicable for a broad array of use cases involving Ironclad and ServiceNow.
Please note that the approach shown here is only meant to demonstrate an example solution for building this integration, but it is a custom integration and not an out-of-the-box supported connector. To view a list of out-of-the-box connectors that Ironclad supports, check out our Help Center.
The runtime interactions that we will show between Ironclad and ServiceNow for our example use case are summarized in the figure below.
This guide has the following sections:
- Background
- Basic Setup
- Handling a Legal Service Request
- Synchronizing Attribute Updates from Ironclad
- Reacting to Ironclad Approvals and Status Changes
- Capturing Final Ironclad Contract Details
Note: This guide and any software contained in it should be used at your own risk by individuals qualified to evaluate its effectiveness. IT IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL IRONCLAD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH YOUR USE OF THIS GUIDE OR ANY SOFTWARE IT CONTAINS.
Your use of the Ironclad API must comply with Ironclad’s API Terms of Use (available at https://legal.ironcladapp.com/api-terms-of-use) and the terms of the Enterprise Services Agreement (or equivalent) entered into between you and Ironclad.
- API Access: Your Ironclad environment will need to have API access enabled, since the ServiceNow application makes use of the Ironclad public APIs to enable the integration.
- Ironclad Account: Several of the solution patterns require specifying an Ironclad user for actions (e.g., who is approving, who is commenting, etc.). Creating a generic Ironclad user account that your integration can use to register actions is recommended for consistency and simplicity.
- Reference Documentation: Please see Ironclad’s API Reference documentation for the most up-to-date details on our endpoints. For information on building workflows in Ironclad, please see Ironclad Academy for guided training and Ironclad Support Center for product articles.
We assume that you are familiar with the basics of ServiceNow concepts, such as tables, forms, business rules, scripted REST APIs and flows. Our guide assumes a generic, non-customized ServiceNow environment to start, and we define some custom tables and other app elements to implement the integrated process. If you want to create a similar integration in your own ServiceNow instance, you will need a login that has appropriate privileges to create and update these app elements.
NOTE: Both Ironclad and ServiceNow have the concept of “workflows”. In the case of Ironclad, a workflow defines a contracting process for a particular type of agreement, while in ServiceNow a workflow is a general flow of actions that are taken in various IT service management scenarios (explicit requests from users, triggered by events, and/or run periodically on a schedule). In the guide that follows we will be clear about which type of workflow we are referencing as we describe the steps in configuring this solution. Whenever possible we will refer to Ironclad workflows as “workflows” and ServiceNow workflows as “flows” for clarity.
You’ll need an appropriate contract workflow defined in Ironclad. Our example uses two workflow templates - a Master Services Agreement (MSA) and a Non-Disclosure Agreement (NDA), but the only details we depend on here are some of the standard fields that exist on almost all Ironclad workflows (Agreement Date, Counterparty Name), as well as the following custom attributes that you will need to add to the workflows:
Attribute | Attribute ID | Type | Notes |
---|---|---|---|
SNOW Agreement Record ID | sNOWAgreementRecordId
|
Text | This stores the ServiceNow ID of the Legal Agreement Task record that triggered the workflow launch. |
SNOW Agreement Number | sNOWAgreementNumber
|
Text | This will store the human-readable Agreement Number of the ServiceNow Legal Agreement Task record that triggered the workflow. |
Total Contract Value (MSA only) | totalContractValue
|
Monetary | This will store the Agreement Value from the ServiceNow Legal Agreement Task record. |
In addition to the attributes above, your workflow will need to have an approval role named "Legal" in order to trigger the approval workflows in the ServiceNow code example.
In order to configure the ServiceNow API calls to Ironclad, you will also need to create an API key from your Ironclad instance. Tokens can be generated in Ironclad under [Your Name] > Company Settings > API > Tokens
. Be sure to make note of the API token value.
Once you have loaded the ServiceNow application components described in the next section into your ServiceNow instance, you will need to configure the webhooks in Ironclad that will send the necessary workflow events to ServiceNow. For each of the Scripted REST resources defined in the app, you’ll need to retrieve the ServiceNow endpoint for the resource and register them to receive webhooks from your Ironclad instance. In ServiceNow Studio, navigate to the Inbound Integrations -> Scripted REST Resources
, and for each item in this list, select it and capture the "Resource path" in the details for the REST endpoint. The full endpoint URL will be the domain of your developer instance (see your browser address bar, typically this will be of the form "devXXXX.service-now.com").
There are four webhooks you will need to configure in Ironclad. The table below lists the Ironclad events to be included in each webhook, and the corresponding ServiceNow Scripted REST resource whose endpoint should be configured as the target of the webhook:
Ironclad Workflow Events | ServiceNow Scripted REST Resource |
---|---|
workflow_approval_status_changed | Workflow Approval Change |
workflow_attribute_updated | Workflow Attribute Change |
workflow_cancelled | Workflow Cancelled |
workflow_completed | Workflow Completed |
As mentioned in the Background section, we are assuming a generic ServiceNow environment to start. Within this generic environment, this guide implements a very simple new service request type to handle legal agreements, using a custom task along with several UI and integration components to connect the request process to Ironclad.
All of the ServiceNow components used in this guide can be downloaded and installed into a ServiceNow environment using the details provided here. This section provides details on the set of components included in the code bundle for this guide. Once the components have been loaded as an application in ServiceNow, you should only need to configure the properties described in the System Properties section below in order to connect the integration to your Ironclad environment.
Property Name | Type | Notes |
---|---|---|
ironclad_api_key
|
string | This property contains the API key to be used to make API calls to your Ironclad instance. Generate a key as described in the Ironclad Setup section, and set this property to the key value. |
ironclad_environment
|
string | This property holds the API hostname for the Ironclad environment you are integrating. Options are:
|
ironclad_msa_template
|
string | The ID of the Ironclad workflow template to be launched when an “MSA” is chosen as the agreement type in the ServiceNow legal agreement request. |
ironclad_msa_signer_name_attribute
|
string | Attribute ID for the counterparty signer name in the MSA workflow. Signer attributes are auto-generated in each workflow with a unique identifier, so this attribute ID needs to be configured for each workflow. |
ironclad_msa_signer_email_attribute
|
string | Attribute ID for the counterparty signer email in the MSA workflow. Signer attributes are auto-generated in each workflow with a unique identifier, so this attribute ID needs to be configured for each workflow. |
ironclad_nda_template
|
string | The ID of the Ironclad workflow template to be launched when an “NDA” is chosen as the agreement type in the ServiceNow legal agreement request. |
ironclad_workflow_creator
|
string | The email address of the Ironclad user that should be used as the creator of workflows when they are launched. |
The Legal Agreement Task table is used to represent a request for the legal team to process an agreement in Ironclad. It inherits from ServiceNow’s standard Task table, to allow us to use process structures like Flows for this service type.
Our Legal Agreement Task table contains the following custom columns (in addition to all of the standard columns included on Task):
Column name | Type | Notes |
---|---|---|
Agreement Date | Date | The date to be used as the start of the legal agreement. |
Agreement Type | Choice | The type of agreement being requested. Our example only includes “MSA” and “NDA” as options. |
Agreement Value | Currency | The monetary value of the agreement. This is only used for MSA agreements. |
Counterparty Name | String | Name of the counterparty for the agreement (e.g., “Acme, Inc.”). |
Counterparty Signer Email | String | The email address of the person at the counterparty that will be signing the agreement. |
Counterparty Signer Name | String | The name of the person at the counterparty that will be signing the agreement. |
Ironclad Legal Approved | True/False | A flag that is used to indicate if the “legal” role has approved the workflow in Ironclad. |
Ironclad Workflow State | String | Used to store the current stage (created, review, sign, archive) of the workflow in Ironclad. |
Ironclad Workflow Status | String | Used to store the current status (active, paused, completed) of the workflow in Ironclad. |
Ironclad Workflow URL | URL | We will store a link to the Ironclad workflow here after it is launched. |
The sample process makes use of a single ServiceNow Business Rule, called “Ironclad: Launch Agreement Workflow”. This rule is configured to fire whenever a record is inserted into the Legal Agreement Task table, and it runs a script that collects the various details from the record and constructs a call to launch the MSA workflow in Ironclad.
The sample process also makes use of several Scripted REST Resources. These are used to capture workflow events from Ironclad to initiate actions in ServiceNow. There is a single Scripted REST API called “Ironclad Webhooks”, and this contains the following Scripted REST Resources. Each one is configured in Ironclad to send a specific type of event to the Scripted REST Resource endpoint.
- Workflow Approval
- Workflow Attribute Change
- Workflow Cancellation
- Workflow Completed
Calls from ServiceNow to the Ironclad public API are made using a REST Message component called “Ironclad”, defined with the appropriate endpoints and request/response details. The REST Message includes the HTTP methods described below:
HTTP Method Name | Type | Notes |
---|---|---|
get workflow | GET | Used to retrieve the full metadata of a specific Ironclad workflow |
get record | GET | Used to retrieve the full metadata for a specific Ironclad repository record. |
launch workflow | POST | Used to launch an Ironclad workflow |
get record attachment | GET | Used to retrieve an attachment for a specific Ironclad repository record |
The Legal Agreement Task table has a single Flow (in Flow Designer) called “Ironclad approval/cancel”. This flow is triggered on any updates to Legal Agreement Task records, and it checks for updates that warrant followup actions within the Legal Agreement service process.
Requests for legal agreement processing can flow from ServiceNow to Ironclad by configuring ServiceNow to launch Ironclad workflows when these service requests are received. In our example, legal agreement requests are created as records in the Legal Agreement Task table in ServiceNow. A request can be submitted by providing the information required on the form associated with table, as shown here:
When the new record is created on submission of this form, our “Launch Agreement Workflow” business rule is fired, and the script attached to this business rule uses the “launch workflow” method defined on our REST Message to send a workflow launch request to Ironclad, using the details provided in the Launch Agreement Workflow record. Here, we show a snippet of code from that script that shows the RESTMessageV2 being constructed and invoked in order to launch the Ironclad workflow. Notice that we are taking fields from the “current” variable here, which is set by ServiceNow to be the record whose insertion triggered this business rule:
.
.
.
// Create the Ironclad API request
var request = new sn_ws.RESTMessageV2("Ironclad", "launch workflow");
request.setStringParameter("ironclad_env", icEnv);
request.setStringParameter("ironclad_api_key", icKey);
var templateID;
// Create the base launch body using the details in the agreement request
var reqBody = {
attributes: {
counterpartyName: current.counterparty_name.toString(),
agreementDate: current.agreement_date.toString(),
sNOWAgreementRecordId: current.sys_id.toString(),
sNOWAgreementNumber: current.number.toString()
.
.
.
},
creator: {
email: creatorEmail,
type: "email"
},
};
// Set the workflow template id
switch (current.agreement_type.toString()) {
case "NDA":
reqBody.template = icNDATemplate;
break;
case "MSA":
reqBody.template = icMSATemplate;
break;
default:
break;
}
request.setRequestBody(JSON.stringify(reqBody));
var response = request.execute();
.
.
.
Once the launch request completes successfully, we populate fields on the task that hold the URL for the Ironclad workflow that was launched, as well as stage and status fields for the workflow:
.
.
.
// Update Legal Request with Ironclad workflow details
var wfData = JSON.parse(response.getBody());
current.setValue("ironclad_workflow_url", "https://" + icEnv + "/workflow/" + wfData.id);
current.setValue("ironclad_workflow_stage", wfData.step);
current.setValue("ironclad_workflow_status", wfData.status);
current.update("Ironclad launch details");
.
.
.
At this point, we’ve launched the Ironclad workflow and linked it to the ServiceNow task – the task’s record ID is stored in the sNOWAgreementRecordId
attribute on the Ironclad workflow, and the Ironclad workflow URL is stored in a field on the task in ServiceNow. As the workflow process is carried forward in Ironclad, we can also keep the ServiceNow task in sync with the Ironclad workflow in various ways, as we show in the following sections.
In some cases, changes made in Ironclad to workflow attributes may need to be synchronized with ServiceNow. E.g. a change in the item quantity in a purchase order may need to trigger a message to a procurement user in ServiceNow. In our MSA/order form example use case, we will show changes to the total contract value being synced back to a field on the ServiceNow task record.
Technically, this is accomplished using Ironclad webhooks, combined with use of the Ironclad public API to retrieve the contract details. The Ironclad “workflow_attribute_updated” event can be used to catch changes to any attribute on Ironclad workflows. In order for ServiceNow to be notified of these events, we need a callable endpoint that Ironclad can use to send the event. To accomplish this, we created a Scripted REST Resource in ServiceNow to act as this callback.
The Scripted REST Resource is created as part of a REST API we named “Ironclad Webhooks” as part of the ServiceNow application. The REST Resource that will capture attribute changes from Ironclad is named “Workflow Attribute Change”. The code behind this endpoint first pulls the workflow template ID from the event payload and checks to be sure that the event is being triggered from the target workflow type (MSAs, in our example). If the event is from the expected workflow type, the code then makes a call to Ironclad to get the full details of the workflow that was updated, using another REST Message type (“get workflow”) we configured on our “Ironclad” REST Messages component:
.
.
.
// See if an MSA was updated - no attribute updates are needed from NDAs
if (request.body.data.payload.templateID === icMSATemplate) {
// Get the updated workflow values
var icMsg = new sn_ws.RESTMessageV2("Ironclad", "get workflow");
icMsg.setStringParameter("ironclad_env", icEnv);
icMsg.setStringParameter("ironclad_api_key", icKey);
icMsg.setStringParameter("workflow_id", request.body.data.payload.workflowID);
var wfResp = icMsg.execute();
var wfData = JSON.parse(wfResp.getBody());
.
.
.
If the call to retrieve the Ironclad workflow data succeeds, we then extract the ServiceNow task record ID from its attributes, lookup the ServiceNow record and update the total contract value stored on the task. We also update the “Ironclad Workflow Stage” and “Ironclad Workflow Status” fields on the task, in case they have changed in Ironclad:
.
.
.
// Get the target Legal Agreement Request
var agreementReqId = wfData.attributes.sNOWAgreementRecordId;
var agreementRec = new GlideRecord("x_749125_legal_i_0_legal_agreement_task");
agreementRec.get(agreementReqId);
// Update the Legal Agreement Request
agreementRec.setValue("agreement_value", wfData.attributes.totalContractValue.amount);
agreementRec.setValue("ironclad_workflow_stage", wfData.step);
agreementRec.setValue("ironclad_workflow_status", wfData.status);
agreementRec.update("Ironclad update");
.
.
.
In order for our ServiceNow Scripted REST Resource to start receiving these events, we need to register its endpoint URL in Ironclad to receive “workflow_attribute_updated” events. The endpoint URL is composed of the “Resource path” value that can be found in the details of the Scripted REST Resource:
The full URL of the endpoint is prefaced with the domain of your specific ServiceNow instance. An example developer instance URL might look something like this, for example:
https://dev60711.service-now.com/api/x_749125_legal_i_0/ironclad_webhook/attribute_change
This full URL is used to configure the webhook subscription in your Ironclad instance, by going to the API settings (“[your name]->Company Settings->API”), and in the Webhooks tab there, click “Create Webhook” and populate the details:
With this webhook in place, any changes in workflow attributes in Ironclad will now fire an event that is sent to the ServiceNow endpoint, triggering the code above to update our Legal Agreement tasks.
It may be necessary to make Ironclad approvals or workflow status changes trigger changes or notifications in ServiceNow. To demonstrate how this can be accomplished, we’ll assume in our running example that an approval from the Legal role in Ironclad, or the cancellation of a workflow in Ironclad, should key fields in the Legal Agreement task for visibility, as well as add a message to the task record conversation.
We accomplish this by subscribing to some additional Ironclad workflow events in ServiceNow. Specifically, we want to capture workflow_approval_status_changed and workflow_cancelled events from Ironclad. We set up two new Scripted REST Resources within the Ironclad Webhooks API we created earlier. The two resources are called “Workflow Approval Change” and “Workflow Cancelled”. Each of these are configured with code that makes the appropriate change to the Legal Agreement task record when these events occur on the corresponding Ironclad workflow. In both cases, we validate the workflow type and retrieve the Service Now task record exactly as we did in the earlier “Workflow Attribute Change” example shown in the section Synchronizing Attribute Updates from Ironclad. With the task record in hand, we then make the appropriate field update. For the approval event, we have a boolean field named “Ironclad Legal Approved” on the task table, and we set the value of this to true or false depending on the approval status seen in the Ironclad event:
.
.
.
if (request.body.data.payload.approvalName === "Legal") {
if (request.body.data.payload.status === "approved") {
agreementRec.setValue("ironclad_legal_approved", true);
}
else {
agreementRec.setValue("ironclad_legal_approved", false);
}
}
.
.
.
For cancelled workflows, we update the standard task field “state” to be a “canceled” value, update the Ironclad workflow status and stage fields on the task, and also set the legal approval flag to false, since by definition a canceled workflow is not approved:
.
.
.
// Update the Legal Agreement Request
agreementRec.setValue("ironclad_workflow_status", wfData.status);
agreementRec.setValue("ironclad_workflow_stage", wfData.step);
// Task state of 4 is "canceled"
agreementRec.setValue("state", 4);
// Workflow is canceled, so negate the legal approval on the task
agreementRec.setValue("ironclad_legal_approved", false);
.
.
.
We insert a message into the task conversation by triggering a ServiceNow Flow (built in Flow Designer). Our Flow is named “Ironclad approval/cancel”, and it is set to trigger on any changes to Legal Agreement task records. When this Flow fires, it checks the values of the “Ironclad Workflow Status” and “Ironclad Legal Approved” fields, and if the workflow has been canceled or approved by legal, it places appropriate messages into the task conversation:
These messages provide additional visibility to ServiceNow users on the process details related to the workflow:
Of course, the triggered Flow could be implemented to do more complex updates, and/or trigger additional notification or approval processes in ServiceNow, depending on your requirements.
When a contract is fully executed in Ironclad, you will likely want to update the status of records in ServiceNow to reflect this. It may also be useful to reference the executed agreement document itself, either through a link to the document in Ironclad, or as a copy of the document stored in ServiceNow. To demonstrate how this can be accomplished, we will capture the completion of Ironclad workflows and update our Legal Agreement task record. We will also pull over the agreement document itself and attach it to the task record for direct reference in ServiceNow.
We create another Scripted REST Resource in our “Ironclad Webhooks” API. This one is called “Workflow Completed”, and we configure this endpoint as a subscriber to “workflow_completed” events in Ironclad, similar to how we configured the other webhooks in this running example. The code that is triggered in the Scripted REST Resource does the same check of the workflow template type, but instead of retrieving the workflow details, we instead retrieve the completed repository record details for the workflow. The workflow has completed, and when this occurs in Ironclad, a repository record is created with the final metadata values, and it also contains an attached agreement document representing the executed agreement signed by all parties.
Retrieving the Ironclad record involves using a different API endpoint configured in our “Ironclad” REST Messages component in ServiceNow. We use the record ID that is provided in the Ironclad workflow_completed event to retrieve the record details, then extract the needed document details from it:
.
.
.
// Get repository record details (assume first record is the target)
var recId = request.body.data.payload.recordIDs[0];
var icMsg = new sn_ws.RESTMessageV2("Ironclad", "get record");
icMsg.setStringParameter("ironclad_env", icEnv);
icMsg.setStringParameter("ironclad_api_key", icKey);
icMsg.setStringParameter("record_id", recId);
gs.info("Retrieving Ironclad record " + recId);
var recResp = icMsg.execute();
var recData = JSON.parse(recResp.getBody());
var fileName = recData.attachments.signedCopy.filename;
var contentType = recData.attachments.signedCopy.contentType;
.
.
.
To update the Legal Agreement task record, we use the record ID stored in Ironclad, but in this case we retrieve the ID from the record rather than from the workflow. When the workflow is archived to the repository in Ironclad, the agreement ID field is mapped to a corresponding field in the record. Record field names in Ironclad, however, have a unique ID appended to them, so we need to specify a different field name when we pull the value from the retrieved record:
.
.
.
// Get the target Legal Agreement Request
var recAgreementProp = "sNOWAgreementRecordId_f6eade0e-c9a4-4248-84de-50342857c99a_string";
var agreementReqId = recData.properties[recAgreementProp].value;
gs.info("Ironclad workflow completed for agreement request " + agreementReqId);
var agreementRec = new GlideRecord(legalAgreementReqTable);
agreementRec.get(agreementReqId);
.
.
.
We update the Legal Agreement task record in ServiceNow to reflect the new completed status:
.
.
.
// Update workflow status on agreement request
agreementRec.setValue("ironclad_workflow_stage", "Completed");
// Default value for "Completed" task state is 3.
agreementRec.setValue("state", 3);
.
.
.
We want to also attach the signed contract document to the task record, so we retrieve the attachment from Ironclad using another endpoint on our “Ironclad” REST Messages:
.
.
.
icMsg = new sn_ws.RESTMessageV2("Ironclad", "get record attachment");
icMsg.setStringParameter("ironclad_env", icEnv);
icMsg.setStringParameter("ironclad_api_key", icKey);
icMsg.setStringParameter("record_id", recId);
// We assume here that the standard "signedCopy" attachment is desired.
// If your workflow involves multiple documents, you may need to adjust
// this to target the required attachment.
icMsg.setStringParameter("attachment_key", "signedCopy");
// Attach signed contract to agreement request record
icMsg.saveResponseBodyAsAttachment(legalAgreementReqTable, agreementReqId, fileName);
var docResp = icMsg.execute();
.
.
.
Notice that we use the RESTMessageV2.saveResponseBodyAsAttachment()
method to request that the response from the Ironclad “get record attachment” call, which is the binary document data itself, be stored as an attachment on the task record. Once this occurs, ServiceNow users will be able to retrieve the contract document directly from the Legal Agreement task record:
Updated 10 months ago