Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

Creating Synthetics monitor via REST API (Python) 400 Bad Request


#1
#!/usr/bin/python
import urllib2, urllib

proxy = "proxy.com:1000"
proxies = {"https":"https://{0}".format(proxy)}
url = "https://synthetics.newrelic.com/synthetics/api/v1/monitors"
headers = {'Content-Type': 'application/json', 'X-Api-Key': '123456789'}
values = { "name" : "monitor1", "frequency" : 15, "locations" : [ "LINODE_EU_WEST_1" ], "type" : "SCRIPT_API", "status": "ENABLED"}
data = urllib.urlencode(values)
proxy_support = urllib2.ProxyHandler(proxies)
opener = urllib2.build_opener(proxy_support)
urllib2.install_opener(opener)
req = urllib2.Request(url, data, headers)
html = urllib2.urlopen(req).read()
print html

Hi,

I want to use the Python script above to create a Synthetics monitor. I receive HTTP 400 error and I cannot see why.

Could anyone help me out?

Thank you!


#2

@Mykolas.Padolskis have you attempted to use the API first via a curl request? https://docs.newrelic.com/docs/apis/synthetics-rest-api/monitor-examples/manage-synthetics-monitors-via-rest-api

Looking at your snippet it’s hard to tell where the issue lies, other than the fact you’re making an invalid request. This could be because of a bad API key, incorrect proxy configurations, or with your usage of urllib2/urllib.

I would start off attempting a curl request to verify you have a valid API key and payload, then proceed to make the request without the proxy before attempting it all at once.


#3

Keep in mind that the API key must be an Admin User’s API key, not the standard account wide API key.

I can be activated using the instructions in or documentation at “API keys


#4

did you figure this out?


#5

This is a pretty situational issue from what I understand, @mike.andrewjeski. Will you describe a bit more about the troubleshooting steps you have taken? What can you see that differs from what you expect to see?

Thanks for the context!


#6

Mine is a little different to Mykolas’ in that I’m using python3 and the requests and json modules.

I did attempt to replicate Mykolas’ script with the same result.

with my script, I get this as output:
{“code”:500,“message”:“There was an error processing your request. It has been logged (ID 7e46c4a249647eea).”}

Perhaps there is more useful output in the logs in the NR side. Dunno if it is possible to search by the ID in the output.


#7

Hi Mike,

I was able to able to use the following to make this work with python 3.6.6 (I hope this is not considered thread-hijacking! :slight_smile:)

import urllib.request
import json

url = "https://synthetics.newrelic.com/synthetics/api/v3/monitors"
values = { "name" : "monitor1", "frequency" : 15, "locations" : [ "AWS_US_EAST_1" ], "type" : "SCRIPT_API", "status": "ENABLED"}
req = urllib.request.Request(url)
req.add_header('Content-Type', 'application/json')
req.add_header('X-Api-Key', 'YOUR_ADMIN_API_KEY')
jsonbody = json.dumps(values)
jsonbodybytes = jsonbody.encode('utf-8')
response = urllib.request.urlopen(req, jsonbodybytes)

Urlopen will use your environment variable http_proxy to make the request by default. I’m still working on figuring out how to add the proxy in because I’m not too familiar with Python… :stuck_out_tongue:


#8

thanks mate, not hijacking at all! If it worked for you then I doubt the http_proxy is needed.
I’ll give this a go.
thanks again!


#9

works well for Script_API, not at all for Simple…
working on it…


#10

Sorry - just saw this response so you may have already figured it out. You should be able to just update the parameters you are sending for ping & simple browser monitors (their request is slightly different - see docs).

Try -

import urllib.request import json url = "https://synthetics.newrelic.com/synthetics/api/v3/monitors" values = { "name" : "monitor_name", "frequency" : 15, "locations" : [ "AWS_US_EAST_1" ], "type" : "SIMPLE", "uri":"https://YOUR-URL-HERE.com", "status": "ENABLED"} req = urllib.request.Request(url) req.add_header('Content-Type', 'application/json') req.add_header('X-Api-Key', 'YOUR-ADMIN-API-KEY') jsonbody = json.dumps(values) jsonbodybytes = jsonbody.encode('utf-8') response = urllib.request.urlopen(req, jsonbodybytes)


#12

This is what I’ve put in github. We’re using it via jenkins now:

#!/usr/bin/env python3

“”" Creates a New Relic Synthetic monitor.
reads user input for the Monitor name (label) & URL
Works with API v3.
Change locations and policy id as needed
add your API Key in these places:
to do:
1) use a real function
“”"
import json
import re
import requests
import sys

#NAME = str(input('Enter the Name: '))
#SITE = str(input('Enter the URL: '))
NAME = sys.argv[1]
SITE = sys.argv[2]

def main():
“”" Grab user input & post the json to New Relic
Synthetics API.
Read the output (combination of headers & json)
match the value from “Location” key (it’s a json list)
slice the list to strip brackets & single quotes
and assign that value to a variable used in the second
request. The output should give two 201 status codes
and the URL of the newly created monitor. Pay attention
to the status codes. A 40X error will give you a lot
of noise, and represents an attempt to create a monitor
using the same name (label) as an existing monitor.
A 50x status means something is way wrong.
Only runs in python 3.
“”"
url = “https://synthetics.newrelic.com/synthetics/api/v3/monitors
values = {“name” : NAME, “type” : “SIMPLE”, “frequency” : 15, “uri” : SITE,
“locations” : [“AWS_EU_CENTRAL_1”, “AWS_US_WEST_1”,
“AWS_US_EAST_1”], “status”: “ENABLED”
}

headers = {'Content-Type': 'application/json', 'X-Api-Key': '<Your API Key here>'}

first_post = requests.post(url, data=json.dumps(values), headers=headers)
print(first_post.status_code)
#x = r.headers
#print(x)
#print(site)
result = first_post.headers['Location']
# grab the value from the Location key
newresult = re.findall(r'\w+-\w+-\w+-\w+-\w+$', result)
print(result)
#print(newresult)
# newresult is returned as a list, strip the brackets and single quotes
monid = newresult[0]
#print("monid", monid)

url2 = "https://api.newrelic.com/v2/alerts_synthetics_conditions/policies/<Your Policy ID here>.json"
values = {"synthetics_condition": {"name": "Check Failure", "monitor_id": monid,
                                   "runbook_url": "string", "enabled": "true"}}

headers = {'Content-Type': 'application/json', 'X-Api-Key': '<Your API Key here>'}
second_post = requests.post(url2, data=json.dumps(values), headers=headers)
print(second_post.status_code)
#print(second_post.headers)

main()