> For the complete documentation index, see llms.txt.
Skip to main content

Check out Port for yourself ➜ 

Interact with ServiceNow records & incidents

This guide demonstrates how to implement Port workflows that create, update, trigger, and delete ServiceNow records and incidents directly from Port using webhook nodes.

Implement with AI

Send this guide to your coding agent.

Prerequisite: Install Port MCP

Common use cases

  • Provide developers and managers with safe, self-serve operations on ServiceNow records.
  • Create ServiceNow incidents from Port using a governed workflow.
  • Automate table record creation, updates, or removal as part of CI/CD or maintenance workflows.
  • Keep ServiceNow incident entities in Port aligned after incident creation or deletion.

Prerequisites

  • Complete the onboarding process.
  • Access to your ServiceNow account with permissions to manage records in relevant tables.
  • ServiceNow instance URL, username, and password. You can get these credentials from your ServiceNow account.
  • Optional - Install Port's ServiceNow integration. The integration creates the ServiceNow incident blueprint and keeps ServiceNow incident data updated in Port.
ServiceNow integration

The ServiceNow integration is optional for these examples, but it creates the incident blueprint boilerplate for you.

Set up data model

If you have not installed the ServiceNow integration, create the ServiceNow incident blueprint before setting up incident workflows.

Create the ServiceNow incident blueprint

  1. Go to the Data model page in Port.

  2. Click + Blueprint.

  3. Click Edit JSON.

  4. Copy and paste the following JSON configuration into the editor:

    ServiceNow incident blueprint (click to expand)
    {
    "identifier": "servicenowIncident",
    "title": "ServiceNow Incident",
    "icon": "Service",
    "schema": {
    "properties": {
    "category": {
    "title": "Category",
    "type": "string"
    },
    "reopenCount": {
    "title": "Reopen Count",
    "type": "string"
    },
    "severity": {
    "title": "Severity",
    "type": "string"
    },
    "assignedTo": {
    "title": "Assigned To",
    "type": "string",
    "format": "url"
    },
    "urgency": {
    "title": "Urgency",
    "type": "string"
    },
    "contactType": {
    "title": "Contact Type",
    "type": "string"
    },
    "createdOn": {
    "title": "Created On",
    "type": "string",
    "format": "date-time"
    },
    "createdBy": {
    "title": "Created By",
    "type": "string"
    },
    "isActive": {
    "title": "Is Active",
    "type": "boolean"
    },
    "priority": {
    "title": "Priority",
    "type": "string"
    },
    "sysId": {
    "title": "System ID",
    "description": "ServiceNow sys_id used by the Table API for update and delete operations",
    "type": "string"
    }
    },
    "required": []
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "aggregationProperties": {},
    "relations": {}
    }
  5. Click Save.

If you already installed Port's ServiceNow integration, add the sysId property above to your existing servicenowIncident blueprint so the delete workflow can call ServiceNow with the correct Table API identifier.

Set up Port secrets

Existing secrets

If you have already installed Port's ServiceNow integration, these secrets should already exist in Port. To view your existing secrets:

  1. Open the Credentials modal.
  2. Click on the Secrets tab.

To add a secret to Port:

  1. Open the Credentials modal.

  2. Click on the Secrets tab.

  3. Click on + Secret and add the following secrets:

    • SERVICENOW_INSTANCE_URL - The ServiceNow instance URL. For example, https://example-id.service-now.com.

    • SERVICENOW_API_TOKEN - A base64 encoded string of your ServiceNow instance credentials generated with:

      echo -n 'your-instance-username:your-instance-password' | base64

    Use single quotes so shell characters in the password (such as $) are not expanded.

Set up the workflows

We will create five workflows to interact with ServiceNow from Port:

  • Create a ServiceNow record.
  • Update a ServiceNow record.
  • Delete a ServiceNow record.
  • Trigger a ServiceNow incident.
  • Delete a ServiceNow incident.

Each workflow uses a self-service trigger and one or more webhook nodes to call ServiceNow's REST API directly. To create each workflow:

  1. Go to the Workflows page of your portal.
  2. Click on the + Workflow button in the top-right corner.
  3. In the Name field, enter the workflow name shown in each section below, then click Confirm.
  4. On the editor page, click the see workflow JSON button (the code icon) to open the JSON editor.
  5. Copy and paste the workflow JSON below to replace the example workflow, then click Save.

Create a ServiceNow record

Create a workflow named Create ServiceNow Record with the JSON below.

Create a ServiceNow record workflow (click to expand)
{
"identifier": "create_servicenow_record",
"title": "Create ServiceNow Record",
"icon": "Servicenow",
"description": "Create a new record in a specified table in ServiceNow using a JSON payload",
"nodes": [
{
"identifier": "trigger",
"title": "Create ServiceNow Record",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"table_name": {
"icon": "DefaultProperty",
"type": "string",
"title": "Table Name",
"description": "Name of the table in ServiceNow"
},
"request_body": {
"type": "object",
"title": "Request Body",
"description": "JSON payload for the new record. The payload must follow the table schema in ServiceNow"
}
},
"required": ["request_body", "table_name"],
"order": ["table_name", "request_body"]
}
}
},
{
"identifier": "create_record",
"title": "Create record in ServiceNow",
"config": {
"type": "WEBHOOK",
"url": "{{ .secrets.SERVICENOW_INSTANCE_URL }}/api/now/table/{{ .outputs.trigger.table_name }}",
"method": "POST",
"synchronized": true,
"headers": {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Basic {{ .secrets.SERVICENOW_API_TOKEN }}"
},
"body": {
"{{ spreadValue() }}": "{{ .outputs.trigger.request_body }}"
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "create_record"
}
]
}

Update a ServiceNow record

Create a workflow named Update ServiceNow Record with the JSON below.

Update a ServiceNow record workflow (click to expand)
{
"identifier": "update_service_now_record",
"title": "Update ServiceNow Record",
"icon": "Servicenow",
"description": "Update an existing record in a specified table in ServiceNow based on system ID and a JSON payload",
"nodes": [
{
"identifier": "trigger",
"title": "Update ServiceNow Record",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"table_name": {
"type": "string",
"title": "Table Name",
"description": "Name of the table in ServiceNow"
},
"request_body": {
"type": "object",
"title": "Request Body",
"description": "JSON payload containing the fields and values to update in the record. Must follow the table schema in ServiceNow"
},
"system_id": {
"type": "string",
"title": "System ID",
"description": "Globally Unique ID (GUID) of the record in ServiceNow"
}
},
"required": ["table_name", "request_body", "system_id"],
"order": ["table_name", "system_id", "request_body"]
}
}
},
{
"identifier": "update_record",
"title": "Update record in ServiceNow",
"config": {
"type": "WEBHOOK",
"url": "{{ .secrets.SERVICENOW_INSTANCE_URL }}/api/now/table/{{ .outputs.trigger.table_name }}/{{ .outputs.trigger.system_id }}",
"method": "PATCH",
"synchronized": true,
"headers": {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Basic {{ .secrets.SERVICENOW_API_TOKEN }}"
},
"body": {
"{{ spreadValue() }}": "{{ .outputs.trigger.request_body }}"
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "update_record"
}
]
}

Delete a ServiceNow record

Create a workflow named Delete ServiceNow Record with the JSON below.

Delete a ServiceNow record workflow (click to expand)
{
"identifier": "delete_service_now_record",
"title": "Delete ServiceNow Record",
"icon": "Servicenow",
"description": "Delete a record based on system ID from a specified table in ServiceNow",
"nodes": [
{
"identifier": "trigger",
"title": "Record details",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"table_name": {
"icon": "DefaultProperty",
"type": "string",
"title": "Table Name",
"description": "Name of the table in ServiceNow"
},
"system_id": {
"type": "string",
"title": "System ID",
"description": "Globally Unique ID (GUID) of the record in ServiceNow"
}
},
"required": ["system_id", "table_name"],
"order": ["table_name", "system_id"]
}
}
},
{
"identifier": "delete_record",
"title": "Delete record in ServiceNow",
"config": {
"type": "WEBHOOK",
"url": "{{ .secrets.SERVICENOW_INSTANCE_URL }}/api/now/table/{{ .outputs.trigger.table_name }}/{{ .outputs.trigger.system_id }}",
"method": "DELETE",
"synchronized": true,
"headers": {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Basic {{ .secrets.SERVICENOW_API_TOKEN }}"
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "delete_record"
}
]
}

Trigger a ServiceNow incident

This workflow creates an incident in ServiceNow and then upserts a matching ServiceNow Incident entity in your catalog from the API response, so the two nodes replace the separate action and sync automation.

Create a workflow named Trigger ServiceNow Incident with the JSON below.

Trigger a ServiceNow incident workflow (click to expand)
{
"identifier": "trigger_servicenow_incident",
"title": "Trigger ServiceNow Incident",
"icon": "Service",
"description": "Trigger a new incident in ServiceNow and sync it to Port",
"nodes": [
{
"identifier": "trigger",
"title": "Trigger ServiceNow Incident",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"short_description": {
"icon": "DefaultProperty",
"title": "Short Description",
"description": "Description of the incident",
"type": "string"
},
"assigned_to": {
"icon": "DefaultProperty",
"title": "Assigned To",
"description": "User this incident is assigned to",
"type": "string"
},
"urgency": {
"title": "Urgency",
"icon": "DefaultProperty",
"type": "string",
"default": "2",
"enum": ["1", "2", "3"],
"enumColors": {
"1": "red",
"2": "yellow",
"3": "green"
}
},
"sysparm_display_value": {
"title": "Sysparm Display Value",
"description": "Determines the type of data returned",
"icon": "DefaultProperty",
"type": "string",
"default": "all",
"enum": ["true", "false", "all"]
},
"sysparm_input_display_value": {
"title": "Sysparm Input Display Value",
"description": "Flag that indicates whether to set field values using the display value or the actual value",
"type": "boolean",
"default": false
}
},
"required": ["short_description", "assigned_to"],
"order": ["short_description", "assigned_to", "urgency", "sysparm_display_value", "sysparm_input_display_value"]
}
}
},
{
"identifier": "create_incident",
"title": "Create incident in ServiceNow",
"config": {
"type": "WEBHOOK",
"url": "{{ .secrets.SERVICENOW_INSTANCE_URL }}/api/now/table/incident",
"method": "POST",
"synchronized": true,
"headers": {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Basic {{ .secrets.SERVICENOW_API_TOKEN }}"
},
"body": {
"short_description": "{{ .outputs.trigger.short_description }}",
"assigned_to": "{{ .outputs.trigger.assigned_to }}",
"urgency": "{{ .outputs.trigger.urgency }}",
"sysparm_display_value": "{{ .outputs.trigger.sysparm_display_value }}",
"sysparm_input_display_value": "{{ .outputs.trigger.sysparm_input_display_value }}"
}
}
},
{
"identifier": "sync_incident",
"title": "Sync incident to Port",
"config": {
"type": "UPSERT_ENTITY",
"blueprintIdentifier": "servicenowIncident",
"mapping": {
"identifier": "{{ .outputs.create_incident.response.data.result.number }}",
"title": "{{ .outputs.create_incident.response.data.result.short_description }}",
"properties": {
"category": "{{ .outputs.create_incident.response.data.result.category }}",
"reopenCount": "{{ .outputs.create_incident.response.data.result.reopen_count }}",
"severity": "{{ .outputs.create_incident.response.data.result.severity }}",
"assignedTo": "{{ .outputs.create_incident.response.data.result.assigned_to.link }}",
"urgency": "{{ .outputs.create_incident.response.data.result.urgency }}",
"contactType": "{{ .outputs.create_incident.response.data.result.contact_type }}",
"createdOn": "{{ .outputs.create_incident.response.data.result.sys_created_on | strptime(\"%Y-%m-%d %H:%M:%S\") | strftime(\"%Y-%m-%dT%H:%M:%SZ\") }}",
"createdBy": "{{ .outputs.create_incident.response.data.result.sys_created_by }}",
"isActive": "{{ .outputs.create_incident.response.data.result.active }}",
"priority": "{{ .outputs.create_incident.response.data.result.priority }}",
"sysId": "{{ .outputs.create_incident.response.data.result.sys_id }}"
}
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "create_incident"
},
{
"sourceIdentifier": "create_incident",
"targetIdentifier": "sync_incident"
}
]
}

Delete a ServiceNow incident

This workflow deletes the incident from ServiceNow and then removes the corresponding entity from Port, keeping your catalog clean and consistent.

Create a workflow named Delete ServiceNow Incident with the JSON below.

Delete a ServiceNow incident workflow (click to expand)
{
"identifier": "delete_servicenow_incident",
"title": "Delete ServiceNow Incident",
"icon": "Servicenow",
"description": "Deletes an incident from ServiceNow and removes it from Port",
"nodes": [
{
"identifier": "trigger",
"title": "Delete ServiceNow Incident",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"incident": {
"icon": "Service",
"type": "string",
"format": "entity",
"blueprint": "servicenowIncident",
"title": "Incident",
"description": "The ServiceNow incident to delete"
}
},
"required": ["incident"],
"order": ["incident"]
}
}
},
{
"identifier": "fetch_incident",
"title": "Fetch incident from Port",
"config": {
"type": "WEBHOOK",
"url": "https://api.port.io/v1/blueprints/servicenowIncident/entities/{{ .outputs.trigger.incident }}",
"method": "GET",
"synchronized": true
},
"variables": {
"entity": "{{ .result.response.data.entity }}"
}
},
{
"identifier": "delete_in_servicenow",
"title": "Delete incident in ServiceNow",
"config": {
"type": "WEBHOOK",
"url": "{{ .secrets.SERVICENOW_INSTANCE_URL }}/api/now/table/incident/{{ .outputs.fetch_incident.entity.properties.sysId }}",
"method": "DELETE",
"synchronized": true,
"headers": {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Basic {{ .secrets.SERVICENOW_API_TOKEN }}"
}
}
},
{
"identifier": "delete_in_port",
"title": "Remove incident from Port",
"config": {
"type": "WEBHOOK",
"url": "https://api.port.io/v1/blueprints/servicenowIncident/entities/{{ .outputs.trigger.incident }}",
"method": "DELETE",
"synchronized": true
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "fetch_incident"
},
{
"sourceIdentifier": "fetch_incident",
"targetIdentifier": "delete_in_servicenow"
},
{
"sourceIdentifier": "delete_in_servicenow",
"targetIdentifier": "delete_in_port"
}
]
}
Port API region

If your Port organization is hosted in the US, replace https://api.port.io with https://api.us.port.io in the fetch and delete nodes above. Using the wrong region returns 401 no token provided because automatic Port API authentication only applies to your organization's API host.

Let's test it!

  1. Go to the Self-service page in Port.

  2. Run one of the ServiceNow workflows you created.

  3. Fill in the required fields for the selected workflow.

  4. Click Execute.

  5. Open your ServiceNow instance and verify that the record or incident was created, updated, or deleted as expected.