Neustar Security Services is updating the WPM API end point for querying performance metrics in order to improve the security of our services and protection of customer data.
We are asking WPM Users who utilize the WPM API end point to leverage the new end point by April 30th, 2022 before the legacy API endpoint (https://api.sec.neustar.biz) is deprecated. In order to leverage the new end point, WPM Users should update the end point queried to the following: https://wpm-api.security.biz/.
Please reach out to support at wpm.support@neustarsecurityservices.com if you have any questions.
Most programming languages provide some version of an md5() function, which should be used to generate the signature. The following example illustrates how to generate a valid signature with PHP:
$apikey = 'epuc35nesxv4bj9ww9k372rj'; $secret = 's2Q3Cx6P'; $timestamp = gmdate('U'); // 1200603038 $sig = md5($apikey . $secret . $timestamp);
The following example URL illustrates a request to the Neustar WPM API, based on an API key of ‘epuc35nesxv4bj9ww9k372rj,’ a timestamp of ‘1200603038’ (Thu, 17 Jan 2008 20:50:38 +0000), and a shared secret of ‘s2Q3Cx6P’:
https://wpm-api.security.biz/performance/monitor/1.0?apikey=epuc35nesxv4bj9ww9k372rj&sig=65a08176826fa4621116997e1dd775fa
NOTE: Errors during the creation of the digital signature are often the reason when requests fail to authenticate and yield 403 errors. When creating the signature, be sure to:
You can send REST requests in any programming language. The following are samples of the code for several popular languages (PHP, Python, Java, Ruby, Perl, C#, and node.js). Each example retrieves the list of all monitoring locations available for an account, uses the hosted service at wpm-api.security.biz, and passes query parameters for an API key (apikey) and the digital signature (sig). The response is in JSON, and does not change from language to language of the request.
NOTE: This is sample code to illustrate the syntax and is not suitable for production environments. Best practices dictate that using these samples in a production environment requires error handling to catch situations where the request fails at the HTTP level.
// initiate curl and set options $ch = curl_init(); $apikey = 'epuc35nesxv4bj9ww9k372rj'; $secret = 's2Q3Cx6P'; $timestamp = gmdate('U'); // 1200603038 // echo $timestamp; $sig = md5($apikey . $secret . $timestamp); $base_url = 'https://wpm-api.security.biz/performance'; $service = '/monitor'; $ver = '/1.0'; $method = '/locations'; curl_setopt($ch, CURLOPT_URL, $base_url . $service . $ver. $method. '?apikey=' . $apikey . '&sig='.$sig); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($ch); $headers = curl_getinfo($ch); // close curl curl_close($ch); // return XML data if ($headers['http_code'] != '200') { echo "An error has occurred"; return false; } else { echo $data; return($data); }
import urllib2
import hashlib
import time
base_url = 'https://wpm-api.security.biz/performance'
service = '/monitor'
version = '/1.0'
method = '/locations'
apikey = 'epuc35nesxv4bj9ww9k372rj'
secret = 's2Q3Cx6P'
# seconds since GMT Epoch
timestamp = str(int(time.time()))
# print timestamp
sig_unencoded = apikey + secret + timestamp
sig = hashlib.md5(sig_unencoded.encode()).hexdigest()
url = base_url + service + version + method + '?apikey=' + apikey + '&sig=' + sig
# print url
json = urllib2.urlopen(url).read()
print json
import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class RestfulCallExample {
public static String baseUrl = "https://wpm-api.security.biz/performance";
public static String service = "/monitor";
public static String version = "/1.0";
public static String method = "/locations";
public static String apikey = "epuc35nesxv4bj9ww9k372rj";
public static String secret = "s2Q3Cx6P";
public static void main(String[] args) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
long timeInSeconds = (long)(System.currentTimeMillis()/1000);
String input = apikey + secret + timeInSeconds;
md.update(input.getBytes());
String sig = String.format("%032x", new BigInteger(1, md.digest()));
String url = baseUrl + service + version + method + "?apikey=" + apikey + "&sig=" + sig;
System.out.println("URL=" + url);
DefaultHttpClient httpclient = new DefaultHttpClient();
// Create an HTTP GET request
HttpGet httpget = new HttpGet(url);
// Execute the request
httpget.getRequestLine();
HttpResponse response = null;
response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
// Print the response
System.out.println(response.getStatusLine());
if (entity != null) {
InputStream inputStream = entity.getContent();
// Process the response
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
}
// shut down the connection manager to ensure
// immediate deallocation of all system resources.
httpclient.getConnectionManager().shutdown();
}
}
require 'net/http'
require 'digest/md5'
# API location
PRODUCTION_ENDPOINT = 'https://wpm-api.security.biz/performance'
SERVICE = '/monitor'
API_VERSION = '/1.0'
METHOD = '/locations'
# Your credentials
API_KEY = 'epuc35nesxv4bj9ww9k372rj'
SHARED_SECRET = 's2Q3Cx6P'
current_time = Time.now
timestamp = Time.now.to_i.to_s
sig = Digest::MD5.hexdigest( API_KEY+SHARED_SECRET+timestamp )
request_url = URI.parse("#{PRODUCTION_ENDPOINT}#{SERVICE}#{API_VERSION}#{METHOD}?apikey=#{API_KEY}&sig=#{sig}")
req = Net::HTTP::Get.new(request_url.to_s)
res = Net::HTTP.start(request_url.host, request_url.port) do |http|
http.request(req)
end
print res.body
# perl
use strict;
use LWP::UserAgent;
use Digest::MD5 qw(md5 md5_hex);
my $baseUrl = 'https://wpm-api.security.biz/performance';
my $service = '/monitor';
my $version = '/1.0';
my $method = '/locations';
# key and shared secret obtained from registering application
my $apikey = 'epuc35nesxv4bj9ww9k372rj';
my $secret = 's2Q3Cx6P';
my $timestamp = time;
# above timestamp needs to be created in PERL !!! Placeholder
my $sig = md5_hex($apikey . $secret . $timestamp);
# print $timestamp," ", $sig, "\n";
my $ua = new LWP::UserAgent;
$ua->timeout(120);
my $url = $baseUrl . $service . $version . $method . '?apikey=' . $apikey . '&sig=' . $sig ;
# print $url, "\n";
my $request = new HTTP::Request('GET', $url);
my $response = $ua->request($request);
my $json = $response->content();
print $json,"\n";
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Security.Cryptography;
namespace WPMAPIRESTSample
{
class Program
{
static void Main(string[] args)
{
string baseUrl = "https://wpm-api.security.biz/performance";
string service = "/monitor";
string version = "/1.0";
string method = "/locations";
string apikey = "epuc35nesxv4bj9ww9k372rj";
string secret = "s2Q3Cx6P";
string sig = MD5GenerateHash(apikey + secret + (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds);
string fullURL = baseUrl + service + version + method + "?apikey=" + apikey + "&sig=" + sig;
// Create the web request
HttpWebRequest request = WebRequest.Create(fullURL) as HttpWebRequest;
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
|
// Write response to the console
Console.WriteLine(reader.ReadToEnd());
}
}
private static string MD5GenerateHash(string strInput)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5 md5Hasher = MD5.Create();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(strInput));
// Create a new Stringbuilder to collect the bytes and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data and format each one as a hexadecimal string.
for (int nIndex = 0; nIndex < data.Length; ++nIndex)
{
sBuilder.Append(data[nIndex].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
}
}
var http = require('http'),
crypto = require('crypto');
var options = {
host: 'wpm-api.security.biz',
path: '/performance',
port: 80,
};
var service = '/monitor';
var version = '/1.0';
var method = '/locations';
var apikey = 'epuc35nesxv4bj9ww9k372rj';
var secret = 's2Q3Cx6P';
var currTimeStamp = Math.round((new Date().getTime()) / 1000);
var sig = crypto.createHash('md5').update(apikey + secret + currTimeStamp).digest("hex");
options.path += service + version + method +'?apikey=' + apikey + '&sig=' + sig;
var response = '';
var req = http.get(options, function(res) {
res.on('data', function (chunk) {
response += chunk;
});
res.on('end', function () {
if (res.statusCode !== 200) {
console.log('Request failed: HTTP status response = ' + res.statusCode);
}
console.log(response);
});
});
{ "data": { "items": [{"status": 'SUCCESS', "bytesReceived": 594936, "errorLineNumber": 0, "location": 'portland', "startTime": '2012-05-31T15:27:05', "duration": 6765, "id": 'bf5565f0ab6f11e1afe1984be166ac54' }, {...}, ... {...} ], "count": 2000, "more": true, "total": 2268, "offset": 0 } }
{ "data": { "items": [{"alertPolicy": null, "locations": ["sanfranciscoca", "washingtondc", "portlandor"], "script": {"version": "mPHIo4TJ5nAonnZhz_16wyB5lTLC7.MX", "id": "69cc4faaac5a4bb7b880380926b08998", "name": "Grid" }, "description": "My Monitor Description", "interval": 5, "name": "API Name", "lastSampleAt", null "inMaintenanceWindow": false, "active": false, "type": "full", "id": "8725440e931711e1b459000c299f6329", "browser": "chrome" }, {...}, ... {...} ] } }
{ "errors": [{ "message": "The item could not be found", //A string providing details on what the error was. "code": "NAMESPACE-40", //Identifies which error occurred. "param": "FAILED_PARAMETER" //Optional - A string indicating which field(s) had the failure, if it was a field error. // other optional }] }
Error Code | Description |
---|---|
MON_0000 | Resource :resource not available |
MON_0001 | Item with Id :itemid not found |
MON_0002 | Duplicate name :name found. |
MON_0003 | :missingfield is/are required fields |
MON_0004 | :value is an invalid value. |
MON_0005 | :value is an invalid value type. Type :valuetype expected |
MON_0006 | :field is an invalid field |
MON_0007 | Valid :field id not supplied |
MON_0008 | Empty body received in POST |
MON_0009 | Empty body received in PUT |
MON_0010 | System cannot complete the request |
MON_0011 | User does not have permission to perform the action |
MON_9999 | An internal error has occured |
Error Code | Description |
---|---|
RUM_000 | Request has been throttled |
RUM_001 | Database internal error |
RUM_002 | Generic internal error |
RUM_003 | Database found data inconsistencies |
RUM_004 | Generic Forbidden error |
RUM_005 | Mandatory parameter is missing |
RUM_006 | Parameter is not valid |