- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-23-2020 07:13 AM
Hi All,
I need to download files attached to any incident using REST API.
I will be sending incident detail from my postman.
Already Referred to attachment api reference docs but could'nt find a solution.
NOTE: I don't have the option to use ui action
Is this doable?
Thanks in Advance!
Solved! Go to Solution.
- Labels:
-
Scripting and Coding

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-29-2020 02:32 AM
I'm executing python script from the command line.
I may be missing some steps below but the general way to install python is as follows.
1. Install python
https://phoenixnap.com/kb/how-to-install-python-3-windows
2. Create subdirectory
mkdir servicenowapis
3. Move to the subdirectory
cd servicenowapis
4. Create a virtualenv
python-m venv venv
5. Activate venv
venv\Scripts\activate.bat
6. Install request module
pip install requests
7. Copy the script I've provided to the directory
8. Copy and paste content of Constants.py over import statements
9. Edit username, password
9. Edit table_api.py to use Incident number
e.g.
get_file_attachment('INC0000002')
10. Execute command
python test_api.py
import requests
SERVICENOW_URL = 'https://<instance>.service-now.com'
SERVICENOW_USER = '<username>'
SERVICENOW_PWD = '<password>'
DOWNLOAD_DIR = './downloads/'
REQUEST_HEADER = {"json": {"Content-Type": "application/xml", "Accept": "application/json"},
"png": {"Content-Type": "application/xml", "Accept": "application/png"},
"xml": {"Content-Type": "application/xml", "Accept": "application/xml"},
}
ATTACHMENT_API = '/api/now/attachment'
TABLE_API = '/api/now/table'
# TABLE_NAME = 'kb_knowledge'
TABLE_NAME = 'incident'
def get_table_data(table_name, param):
url = SERVICENOW_URL + TABLE_API + '/' + table_name + '?' + param
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
return response.json()
def get_attachment_info(sys_id):
url = SERVICENOW_URL + ATTACHMENT_API + '/' + sys_id
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print(f'Status: {response.status_code}, Headers:{response.headers}')
exit()
return response.json()
def get_attachment(att_sys_id, file_type, download_dir):
url = SERVICENOW_URL + '/' + ATTACHMENT_API + '/' + att_sys_id + '/file'
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get(file_type))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
with open(download_dir, 'wb') as f:
for chunk in response:
f.write(chunk)
def get_file_attachment(record_number):
param = 'sysparm_query=number=' + record_number + '&sysparam_limit=1'
file_info = get_table_data(TABLE_NAME, param).get('result')
if len(file_info) < 1:
print(f'There is no attachment to sys_id:{record_number}')
return
attachment_sys_id = file_info[0].get('sys_id')
param = 'sysparm_query=table_sys_id=' + attachment_sys_id + '&sysparam_limit=1'
kb_attachments = get_table_data('sys_attachment', param)
result = kb_attachments.get('result')
for attach_file in result:
attach_sys_id = attach_file.get('sys_id')
content_type = attach_file.get('content_type').split('/')
file_ext = content_type[1]
file_name = attach_file.get('file_name')
get_attachment(attach_sys_id, file_ext, DOWNLOAD_DIR + file_name)
if __name__ == '__main__':
# get_file_attachment('KB0010062') # knowledge base number
get_file_attachment('INC0000002')
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2020 01:19 AM
Hi Hozawa,
Thanks for the link. Checking the same.
Do let me know if it works for you.
Thanks!

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-23-2020 05:47 PM
Hi RJ,
I tried below CURL command through POST man and I am able to download the file directly on my machine.
Details below.
https://developer.servicenow.com/dev.do#!/reference/api/orlando/rest/c_AttachmentAPI
curl "https://instance.service-now.com/api/now/attachment/615ea769c0a80166001cf5f2367302f5/file" \
--request GET \
--header "Accept:*/*" \
--user 'admin':'admin'
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2020 01:24 AM
Hi Pradeep,
Thanks for the response.
In the curl command above, is this the sys id of the attachment? If yes, then it's not feasible to give sys id i guess if we consider from end user's perspective.
Also, there's a possibility there can be multiple attachments in a single incident . So it's i guess giving sys id everytime will not work.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-24-2020 02:09 AM
Other API calls are required to fetch the sys_id before this. There isn't a single API to fetch the attachments.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-25-2020 12:49 AM
Following is a python3 script to download attachments of a Knowledge Base article given a knowledge article number
import requests
from servicenowapis.constants import ATTACHMENT_API, DOWNLOAD_DIR, REQUEST_HEADER,\
SERVICENOW_PWD, SERVICENOW_URL,SERVICENOW_USER, TABLE_API
def get_table_data(table_name, param):
url = SERVICENOW_URL + '/' + TABLE_API + '/' + table_name + '?' + param
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
return response.json()
def get_attachment_info(sys_id):
url = SERVICENOW_URL + ATTACHMENT_API + '/' + sys_id
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get('json'))
if response.status_code != 200: # if error, then exit
print(f'Status: {response.status_code}, Headers:{response.headers}')
exit()
return response.json()
def get_attachment(att_sys_id, file_type, download_dir):
url = SERVICENOW_URL + '/' + ATTACHMENT_API + '/' + att_sys_id + '/file'
response = requests.get(url, auth=(SERVICENOW_USER, SERVICENOW_PWD), headers=REQUEST_HEADER.get(file_type))
if response.status_code != 200: # if error, then exit
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
exit()
with open(download_dir, 'wb') as f:
for chunk in response:
f.write(chunk)
def get_kb_attachment(kb_number):
param = 'sysparm_query=number=' + kb_number + '&sysparam_limit=1'
kb_info = get_table_data('kb_knowledge', param)
kb_sys_id = kb_info.get('result')[0].get('sys_id')
param = 'sysparm_query=table_sys_id=' + kb_sys_id + '&sysparam_limit=1'
kb_attachments = get_table_data('sys_attachment', param)
result = kb_attachments.get('result')
for attach_file in result:
attach_sys_id = attach_file.get('sys_id')
content_type = attach_file.get('content_type').split('/')
file_ext = content_type[1]
file_name = attach_file.get('file_name')
get_attachment(attach_sys_id, file_ext, DOWNLOAD_DIR + file_name)
if __name__ == '__main__':
get_kb_attachment('<kb article number>') # knowledge base number e.g.KB0010062
constants.py
SERVICENOW_URL = 'https://<instance>.service-now.com'
SERVICENOW_USER = 'username'
SERVICENOW_PWD = 'password'
DOWNLOAD_DIR = 'C:/Users/hozawa/downloads/'
REQUEST_HEADER = {"json": {"Content-Type": "application/xml", "Accept": "application/json"},
"png": {"Content-Type": "application/xml", "Accept": "application/png"},
"xml": {"Content-Type": "application/xml", "Accept": "application/xml"},
}
ATTACHMENT_API = '/api/now/attachment'
TABLE_API = '/api/now/table'