- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-24-2021 12:43 PM
I have created a Scripted REST API call with HTTP PUT Method. I am calling the endpoint from a python script in order to update an incident in SNOW from my external application.
When I make the PUT request from Postman, it is working fine and is updating the Incident. Hence I know my script is working fine and also the user has the required roles to update the incident.
However when I make the same call using my Python script, I get HTTP 200 but an empty response body and the incident is not updated. What am I possibly doing wrong? I tried playing around with header in my python script.
If I mention incorrect username / password in auth argument in my python script or if I mention incorrect content type in header, I do get a HTTP 401 response with proper error in the response body. However everything is correct and HTTP code is 200, I get empty response body with no updates happening.
Below is my Python requests snippet.
req_header = {"Content-Length": "230",
"Accept-Encoding": "identity, deflate, compress, gzip",
"Connection": "keep-alive",
"Accept": "*/*",
"User-Agent": "python-requests/0.11.1",
"Content-Type": "application/json"
}
API_ENDPOINT = "https://office_snow_instance.com/api/org/hear_clear_incoming_rest_api/updateincident"
data_json = {"SnowID": "IN21003453511",
"Incident_short_description": "Updated incoming REST call for jotinderl",
"assigned_to": "Jotinder Singh",
"sys_id": "be66f8587bd03850198c42eddc4bcb5f"
}
r = requests.put(url=API_ENDPOINT, data=data_json, auth=('POCuser ', 'XXXXXXXX'), headers=req_header)
print(r)
print(r.content)
return r.content
Note: masked some of the data in above code to maintain corporate security.
Solved! Go to Solution.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-24-2021 03:01 PM
Hi Jotinder
It's a little hard (at least for me) to troubleshoot this with the information/snippets you've provided. I have questions such as why the endpoint isn't the table API, but a customer table (hear_clear_incoming_rest_api) as well as why you're using port 8080 (and in the one screenshot a reply from local 127.0.0.1)
Below is a snippet from my Personal Dev instance that works fine with Python using the standard ServiceNow Incident Table. Could it simply be that you didn't import the request handler package into Python? (line 2 - I don't see that in your snippet)
#Need to install requests package for python import requests # Set the request parameters - The last parameter is the SYSID of the incident url = 'https://devXXXXX.service-now.com/api/now/table/incident/ed92e8d173d023002728660c4cf6a7bc' user = 'admin' pwd = 'xxxxxxxx' # Set proper headers headers = {"Content-Type":"application/json","Accept":"application/json"} # Do the HTTP request response = requests.put(url, auth=(user, pwd), headers=headers ,data="{\"short_description\":\"Updated incoming REST call for jotinderl\",\"assigned_to\":\"77ad8176731313005754660c4cf6a7de\"}") # Check for HTTP codes other than 200 if response.status_code != 200: print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:',response.json()) exit() # Decode the JSON response into a dictionary and use the data data = response.json() print(data)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-24-2021 02:43 PM
I fetched the request header and body in Python before it is sent out and this is how it looks.
{'Content-Type': 'application/json', 'Host': 'XX.XX.XX.XX:8080', 'Content-Length': '155'}
SnowID=IN21003453511&Incident_short_description=Updated+incoming+REST+call+for+jotinderl&assigned_to=Jotinder+Singh&sys_id=be66f6201bd03850198c42eddc4bcb5f
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-24-2021 02:20 PM
I even removed the authentication all together to see if it works.
I removed all the unnecessary headers even from postman and I was able to update the incident and receive response body using below.
I believe the requests package in Python would be populating the "Content-Length" and "Host" on its own, without explicitly defining them in code. Hence I used below header as well.
I think Host and Content-Length are mandatory header requirements for SNOW since without those, I get HTTP 400 even in Postman.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-24-2021 02:44 PM
I checked and yes Python does indeed append "Content-Length" and "Host" header parameters on its own, even if I do not mention them explicitly.
I fetched the request header and body in Python before it is sent out and this is how it looks.
{'Content-Type': 'application/json', 'Host': 'XX.XX.XX.XX:8080', 'Content-Length': '155'}
SnowID=IN21003453511&Incident_short_description=Updated+incoming+REST+call+for+jotinderl&assigned_to=Jotinder+Singh&sys_id=be66f6201bd03850198c42eddc4bcb5f

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-24-2021 03:01 PM
Hi Jotinder
It's a little hard (at least for me) to troubleshoot this with the information/snippets you've provided. I have questions such as why the endpoint isn't the table API, but a customer table (hear_clear_incoming_rest_api) as well as why you're using port 8080 (and in the one screenshot a reply from local 127.0.0.1)
Below is a snippet from my Personal Dev instance that works fine with Python using the standard ServiceNow Incident Table. Could it simply be that you didn't import the request handler package into Python? (line 2 - I don't see that in your snippet)
#Need to install requests package for python import requests # Set the request parameters - The last parameter is the SYSID of the incident url = 'https://devXXXXX.service-now.com/api/now/table/incident/ed92e8d173d023002728660c4cf6a7bc' user = 'admin' pwd = 'xxxxxxxx' # Set proper headers headers = {"Content-Type":"application/json","Accept":"application/json"} # Do the HTTP request response = requests.put(url, auth=(user, pwd), headers=headers ,data="{\"short_description\":\"Updated incoming REST call for jotinderl\",\"assigned_to\":\"77ad8176731313005754660c4cf6a7de\"}") # Check for HTTP codes other than 200 if response.status_code != 200: print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:',response.json()) exit() # Decode the JSON response into a dictionary and use the data data = response.json() print(data)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-24-2021 08:24 PM
Hello Roy,
First and foremost a big thank you for your tremendous help. This worked for me!
Honestly this was the first day that I ever did some SNOW development / integration as part of a hackathon at my organization and while everything else worked, I was really struggling with this.
I basically did some google search and referred a few YouTube videos to make an inbound integration with SNOW using REST API and found that it can be done with Scripted REST APIs. However I was not aware that you can simply update the incident table using built in API, as mentioned in your solution.
To answer a few of your questions.
1) Yes, I actually did had the import requests line in my code.
2) The reason for 127.0.0.1 in my code is because am also doing an outbound integration from SNOW to my Python based solution where am running a flask REST API to listen to the incoming request. However since port forwarding is not allowed in my corporate network, I used ngrok tunnel as a workaround. So SNOW basically send request to ngrok's server and port which is then forwarded to my localhost (127.0.0.1) port, hence bypassing the need for forwarding a port on my office laptop.
You have been real kind and helpful.
I had a small but unrelated query, not sure if this is the appropriate way to digress from the main question and ask it here, but I will try my luck.
Does SNOW have a way to generate Desktop notifications whenever a new incident comes? I found that desktop notifications can be sent for chats and incident update notifications can be sent on mobile app. But I did not find a way to send notifications from SNOW for an incident update / creation directly to the desktop.
Is that something which is natively possible in SNOW?
Once again thank you so much for your help so far!
Regards,
Jotinder