top of page

Experiencing challenges with ServiceNow support?

IKC provides professional, reliable assistance that covers gaps not supported by ServiceNow

and without the high costs of traditional services.

 

Starting from just $1,000

Streamlining ServiceNow Operations: A Comprehensive Guide to Copying Attachments Between Instances

Updated: Mar 26


In the dynamic landscape of ServiceNow deployments, the necessity to transfer attachments between different instances frequently arises. This could be due to various reasons, such as migrating data during upgrades, synchronizing development and production environments, or integrating data between disparate ServiceNow platforms. Efficiently managing this process is crucial for maintaining data integrity and ensuring smooth operational workflows. This article delves into the primary methods available for copying attachments between ServiceNow instances, providing a detailed understanding of each approach, along with considerations for security and performance.


Understanding the ServiceNow REST Attachment API


The ServiceNow platform offers a robust REST API that enables programmatic interaction with various aspects of the system, including attachments. This API serves as a cornerstone for building integrations and automating tasks across different ServiceNow instances. Specifically, the Attachment API provides a set of endpoints and HTTP methods designed to manage file attachments associated with records. The base URL for the Attachment API is typically structured as /api/now/attachment.


Within this API, several key HTTP methods are fundamental for attachment management. The POST method is used for creating new attachments. There are two primary POST endpoints: /now/attachment/file and /now/attachment/upload. The /now/attachment/file endpoint allows for uploading a binary file by providing query parameters such as creation_time (defaults to the current time), encryption_context (specifying encryption for the attachment), the required file_name, the table_name to which the attachment will be linked, and the table_sys_id of the specific record. The actual binary content of the file is included in the request body. Alternatively, the /now/attachment/upload endpoint facilitates multipart file uploads, where parameters like Content-Type, table_name, table_sys_id, and the file content itself (as uploadFile) are included within the form body of the request.

Conversely, the GET method is used to retrieve information about existing attachments. The endpoint /now/attachment/{sys_id} allows you to fetch the metadata associated with a specific attachment, where {sys_id} represents the unique identifier of the attachment record in the sys_attachment table. To retrieve the actual content of an attachment, the endpoint /now/attachment/{sys_id}/file is used. It's important to note that when retrieving the content, the content-type header plays a crucial role in ensuring the file is handled correctly by the receiving system. The comprehensive nature of the REST Attachment API, with its dedicated methods for both metadata and content management, provides the necessary tools for a reliable cross-instance attachment copying mechanism.


Method 1: Leveraging the REST Attachment API for Cross-Instance Copying


Copying attachments between ServiceNow instances using the REST Attachment API involves a series of well-defined steps to ensure a successful transfer.


Step 1: Authenticate with both instances.

Establishing secure communication is paramount. Both the source instance (from which the attachment is being copied) and the target instance (to which the attachment is being copied) will require authentication. A common method for this is Basic Authentication, which involves providing a username and password for a user with the necessary permissions on each instance. It is crucial to ensure that all API communication occurs over HTTPS to encrypt the transmitted data, including the authentication credentials. While Basic Authentication is relatively straightforward to implement, for more secure production environments, considering OAuth 2.0 is advisable as it uses tokens instead of directly transmitting credentials. The choice of authentication method directly influences the security posture and complexity of the cross-instance interaction.


Step 2: Retrieve the attachment metadata from the source instance.

Once authenticated with the source instance, the next step is to obtain the metadata of the attachment you wish to copy. This is achieved by making a GET request to the /now/attachment/{sys_id} endpoint, replacing {sys_id} with the sys_id of the attachment in the source instance. The response to this request will contain valuable information about the attachment, such as its file_name and content_type.


Step 3: Retrieve the attachment content from the source instance.

After obtaining the metadata, the actual file content needs to be retrieved. This is done by making another GET request, this time to the /now/attachment/{sys_id}/file endpoint on the source instance. When processing the response, it is essential to handle the binary data correctly and to pay close attention to the content-type header provided in the response. Incorrectly handling this header can lead to the file being corrupted or misinterpreted in the target instance.


Step 4: Upload the attachment to the target instance.

With the metadata and content retrieved from the source instance, the final step is to upload the attachment to the desired record in the target instance. This is accomplished using a POST request to the /now/attachment/file endpoint on the target instance. The request requires several query parameters: the table_name of the target record, the table_sys_id of the specific record where the attachment should be associated, and the file_name obtained from the source metadata. The binary content retrieved in Step 3 should be included as the request body. An alternative endpoint, /now/attachment/upload, could also be used for multipart uploads if that aligns better with the specific requirements. The necessity to explicitly specify the table_name and table_sys_id during the upload process underscores the fundamental requirement of ServiceNow to associate every attachment with a specific record within a defined table.

Below is an example of a ServiceNow server-side script that demonstrates this process:


function copyAttachment(sourceAttachmentSysId, targetTableName, targetSysId) {
  var targetInstanceURL = "https://TARGET_INSTANCE.service-now.com/"; // Replace with your target instance URL
  var targetUserID = "TARGET_USERNAME"; // Replace with your target instance username
  var targetUserPassword = "TARGET_PASSWORD"; // Replace with your target instance password
  var sourceInstanceURL = "https://SOURCE_INSTANCE.service-now.com/"; // Replace with your source instance URL
  var sourceUserID = "SOURCE_USERNAME"; // Replace with your source instance username
  var sourceUserPassword = "SOURCE_PASSWORD"; // Replace with your source instance password

  // Step 1: Retrieve attachment metadata from the source instance
  var attachmentMetaRequest = new sn_ws.RESTMessageV2();
  attachmentMetaRequest.setHttpMethod("get");
  attachmentMetaRequest.setBasicAuth(sourceUserID, sourceUserPassword);
  attachmentMetaRequest.setEndpoint(sourceInstanceURL + "api/now/attachment/" + sourceAttachmentSysId);
  attachmentMetaRequest.setRequestHeader("Accept", "application/json");
  var metaResponse = attachmentMetaRequest.execute();
  var metaResponseBody = metaResponse.getBody();
  var metaHttpStatus = metaResponse.getStatusCode();

  if (metaHttpStatus == 200) {
    var parser = new JSONParser();
    var parsedMeta = parser.parse(metaResponseBody);
    var fileName = parsedMeta.result.file_name;
    var contentType = parsedMeta.result.content_type;

    // Step 2: Retrieve attachment content from the source instance
    var attachmentContentRequest = new sn_ws.RESTMessageV2();
    attachmentContentRequest.setHttpMethod("get");
    attachmentContentRequest.setBasicAuth(sourceUserID, sourceUserPassword);
    attachmentContentRequest.setEndpoint(sourceInstanceURL + "api/now/attachment/" + sourceAttachmentSysId + "/file");
    attachmentContentRequest.setRequestHeader("Accept", "application/octet-stream"); // Assuming binary data
    var contentResponse = attachmentContentRequest.execute();
    var contentResponseBody = contentResponse.getBody();
    var contentHttpStatus = contentResponse.getStatusCode();

    if (contentHttpStatus == 200) {
      // Step 3: Upload the attachment to the target instance
      var uploadRequest = new sn_ws.RESTMessageV2();
      uploadRequest.setHttpMethod("post");
      uploadRequest.setBasicAuth(targetUserID, targetUserPassword);
      uploadRequest.setEndpoint(targetInstanceURL + "api/now/attachment/file");
      uploadRequest.setQueryParameter("table_name", targetTableName);
      uploadRequest.setQueryParameter("table_sys_id", targetSysId);
      uploadRequest.setQueryParameter("file_name", fileName);
      uploadRequest.setRequestHeader("Content-Type", contentType);
      uploadRequest.setRequestBody(contentResponseBody);
      var uploadResponse = uploadRequest.execute();
      var uploadHttpStatus = uploadResponse.getStatusCode();

      if (uploadHttpStatus == 201) {
        gs.info("Attachment successfully copied to target instance.");
      } else {
        gs.error("Error uploading attachment to target instance. Status code: " + uploadHttpStatus + ", Body: " + uploadResponse.getBody());
      }
    } else {
      gs.error("Error retrieving attachment content from source instance. Status code: " + contentHttpStatus + ", Body: " + contentResponse.getBody());
    }
  } else {
    gs.error("Error retrieving attachment metadata from source instance. Status code: " + metaHttpStatus + ", Body: " + metaResponse.getBody());
  }
}

// Example usage:
// copyAttachment('SOURCE_ATTACHMENT_SYS_ID', 'TARGET_TABLE_NAME', 'TARGET_SYS_ID');
// Replace 'SOURCE_ATTACHMENT_SYS_ID', 'TARGET_TABLE_NAME', and 'TARGET_SYS_ID' with actual values.

Experiencing challenges with ServiceNow support?

IKC provides professional, reliable assistance that covers gaps not supported by ServiceNow

and without the high costs of traditional services.

 

Starting from just $1,000

CONTACT

New Zealand HQ

Integrated Knowledge Consulting Office

Level 3, 93 Grafton Road

Auckland

South Korea

Integrated Knowledge Consulting Office

BMY역삼타워 6층

서울특별시 강남구 역삼동 678-10번지

 

info@ikconsulting.com

Thanks for submitting!

  • LinkedIn Social Icon

© Copyright 2025 Integrated Knowledge Consulting. All rights reserved.

bottom of page