Introduction
The Where's It Up? API is a REST-ish interface working primarily in JSON that enables you to confirm that your systems are working and globally available.
The general flow is simple: you POST
a request to our server, our system performs the tests, obtains the responses, and bundles it all together into a report, which it returns in JSON.
Entry Point
The base URL for the API is https://staging-api.wheresitup.com/v4
. All endpoints are relative to the base.
Versions
The base URL reflects the current API version (in this case, /v4
indicates
API version 4). The API version will only change when there are
backwards-incompatible modifications to the API resource structure, input
formats, or output formats. Additions of new features and tweaks to existing
features will not affect the API version. For example, adding a new property to
the dig
output summary would not affect the version number. On the
other hand, renaming to existing answer
property to response
or return
would. (If you are familiar with the Semantic Versioning
standard, think of the API version number as a semantic
"major" version.)
Authentication
To authenticate, use this code:
# with curl, pass the auth header with each request
curl -i "https://staging-api.wheresitup.com/v4" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"
<?php
// The API client will set up the header for you
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# The API client will set up the header for you
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
The API will assign you a unique client ID and token as soon as you sign up. You will continue to have access in perpetuity, though your ability to submit new jobs will vanish if you run out of credit.
You must include your client ID and token with every API request in an HTTP Auth
header. It should look like this:
Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN
Checking your credits
To check how many credits you have, use this code:
curl -i "https://staging-api.wheresitup.com/v4/credits" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"
Sample response
{
"current": 300000,
"used": {
"today": 100,
"yesterday": 100,
"week": 200
}
}
As long as you have credits in your account (and you have not exceeded the rate limit), you can send tests through the API. You can use the credits
API endpoint to check how many API credits you have, and how many you have used recently.
Fields
Name | Type | Description |
---|---|---|
current |
integer | Number of credits currently available in your WIU API account |
used |
object | Summary of recent credit usage (see below) |
Usage Data
Name | Type | Description |
---|---|---|
today |
integer | Credits used on the current calendar day |
yesterday |
integer | Credits used on the previous calendar day |
week |
integer | Credits used in the previous 7 days, including today |
Rate Limit
To check your current rate limit status, check the headers from any authenticated request:
curl -i "https://staging-api.wheresitup.com/v4/credits" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"
Sample headers
HTTP/1.1 200 OK
Date: Fri, 28 Apr 2017 09:12:59 GMT
X-RateLimit-Limit: 2500
X-RateLimit-Remaining: 2500
X-RateLimit-Reset: 1493370810
Content-Length: 58
Content-Type: application/json; charset=UTF-8
You may request up to 2,500 tests every two minutes. One test means one of the individual services available in the API run on one server. For example, a job requesting the ping
and http
tests on newyork
, london
, and tokyo
includes six tests: ping
and http
on three servers.
Each response to an authenticated API request will include three headers that describe your current rate limit status:
Header | Description |
---|---|
X-RateLimit-Limit |
The maximum number of tests allowed in a two-minute period |
X-RateLimit-Remaining |
The number of tests you can request in the current rate limit window |
X-RateLimit-Reset |
The time the current rate limit window resets (in epoch time) |
If you request more than 2,500 tests in a two-minute period, the API will respond with HTTP status 429
.
Sources
Sample request
# get all available servers
curl -i "https://staging-api.wheresitup.com/v4/sources" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"
# get servers in Canada and Brazil
curl -i "https://staging-api.wheresitup.com/v4/sources?countries=canada,brazil" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$api->servers();
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
api.servers()
Sample response
{
"sources": [
{
"id": "14",
"name": "boston",
"title": "Boston",
"location": "Somerville",
"state": "Massachusetts",
"country": "United States",
"latitude": "42.3583",
"longitude": "-71.0603",
"continent_name": "North America"
},
{
"id": "15",
"name": "miami",
"title": "Miami",
"location": "Miami",
"state": "Florida",
"country": "United States",
"latitude": "25.7650",
"longitude": "-80.2000",
"continent_name": "North America"
}
]
}
Using sources
, you can retrieve a list of source cities. sources
provides the city's name, detailed location, latitude, longitude, and so on.
The name
field lists the city the server resides in, while the location
field specifies its precise location. This enables us to use more readily identifiable names for our locations, while still providing detailed location information. For example, our server in Amsterdam resides in Haarlemmermeer, a suburb. You probably don't know where Haarlemmermeer is, but can confidently state that Amsterdam is in the Netherlands.
The list of source locations rarely changes: most updates are simple additions to the end of the list, as the network grows. For the convenience of our WonderProxy customers, who access servers directly, we really do seek to minimize change.
You can filter the list of source cities by country with the countries
query parameter.
HTTP Request
GET https://staging-api.wheresitup.com/v4/sources
Query parameters
Parameter | Description |
---|---|
countries | An array or comma-separated list of the countries to include in the results. |
Jobs
Creating jobs
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "http://example.org",
"tests": [ "http", "dig", "trace", "edge" ],
"sources": [ "newyork", "cairo" ],
"options": {
"expire_after": "3 hours",
"timeout": 30,
"http": { "method": "GET" },
"dig": { "timeout": 5 },
"edge": {
"headers": [ "User-Agent: WidgetMaster", "Cache-Control: no-cache" ]
}
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'http://example.org',
[ 'newyork', 'cairo' ],
[ 'http', 'dig', 'trace', 'edge' ],
[
'expire_after' => '3 hours',
'timeout' => 30,
'http' => [ 'method' => 'GET' ],
'dig' => [ 'timeout' => 5 ],
'edge' => [ 'headers' => [ 'User-Agent: WidgetMaster', 'Cache-Control: no-cache' ]]
]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# using the raw API interface:
job_id = api.submit(
'http://example.org',
[ 'newyork', 'cairo' ],
[ 'http', 'dig', 'trace', 'edge' ],
{
'expire_after': '3 hours',
'timeout': 30,
'http': { 'method': 'GET' },
'dig': { 'timeout': 5 },
'edge': { 'headers': [ 'User-Agent: WidgetMaster', 'Cache-Control: no-cache' ]}
}
)
# using the Job wrapper
job = wiuppy.Job(api)
job.uri = 'http://example.org'
job.tests = [ 'http', 'dig', 'trace', 'edge' ]
job.servers = [ 'newyork', 'cairo' ]
job.options = {
'expire_after': '3 hours',
'timeout': 30,
'http': { 'method': 'GET' },
'dig': { 'timeout': 5 },
'edge': { 'headers': [ 'User-Agent: WidgetMaster', 'Cache-Control: no-cache' ]}
}
job_id = job.submit().id
Sample response
HTTP/1.1 201 Created
Date: Sun, 01 Mar 2015 21:12:03 GMT
Server: Apache/2.2.22 (Debian)
X-Frame-Options: SAMEORIGIN
Location: /v4/jobs/54f380a3f8037a3d208b4567
Content-Length: 36
Content-Type: application/json; charset=UTF-8
{ "jobID" : "54f380a3f8037a3d208b4567" }
The API provides nine individual tests. You build a job from any combination of tests run against a single URI on any combination of sources (servers). Once you submit a job, the API will immediately provide a unique identifier for the job results, and start running each test on each server in the background.
You can submit jobs as JSON (with the application/json
content type) or as a form (with the application/x-www-form-urlencoded
content type).
Use the options
parameter to specify job or test settings.
HTTP Request
POST https://staging-api.wheresitup.com/v4/jobs
HTTP Parameters
Parameter | Required | Type | Description | Sample (JSON) |
---|---|---|---|---|
uri |
Yes | string | The URI to query | "https://google.com" |
tests |
Yes | array | One or more of the available test types | ["http", "ping"] |
sources |
Yes | array | One or more of the available city names | ["denver", "london"] |
options |
No | object | Modifiers for the request |
Job options
Specify global job settings as properties of the options
parameter:
{ options: { expire_after: "1 week" }}
Specify test-specific settings under the test "namespace":
{ options: { http: { method: "GET" }}}
The test-specific sections list the individual test options.
Parameter | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|
expire_after |
string | "1 day" |
Relative time the job will be cleared from our system | "3 hours" |
timeout |
number | 180 |
Seconds an individual test may run before it times out and exits | 15 |
Retrieving job results
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs/YOUR_JOB_ID" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$results = $api->retrieve($jobID);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# with the raw API
results = api.retrieve(job_id)
# polling with the Job wrapper
job = wiuppy.Job(api)
job.id = job_id
results = job.retrieve(poll=True).results
Sample response
HTTP/1.1 200 OK
Date: Sun, 01 Mar 2015 21:48:20 GMT
Server: Apache/2.2.22 (Debian)
X-Frame-Options: SAMEORIGIN
Content-Length: 253
Content-Type: application/json; charset=UTF-8
{
"request": {
"easy_time": "Sun, 01 Mar 2015 14:47:55 -0700",
"expiry": {
"sec": 1425332875,
"usec": 0
},
"ip": "127.0.0.1",
"start_time": 1425246475,
"url": "http://example.org"
},
"response": {
"complete": [],
"error": [],
"in_progress": {
"<source>": {
"<test>": "in progress"
}
}
}
}
You can only retrieve reports for jobs that your account submitted. The jobID
returned when the job was submitted identifies the job itself, and the Location
header provides the path to the raw results. The source location and test type affect how long the job will take to perform. A traceroute from South Africa to Vancouver, for example, may take some time.
Job reports include both raw and parsed output, as well as metadata for the job request itself. The report contains two sections: the request
section, containing the job metadata, and the response
section, detailing the results of each test.
When you fetch a job, the API returns as much of the answer as possible at that time. If no information is available, the in_progress
section of the response will contain the pending tests. Depending on the test requested and the server response, some pieces of information (e.g. contentLength
, responseCode
) may not be available.
The error
section of the response lists any failed or timed-out tests.
HTTP Request
GET https://staging-api.wheresitup.com/v4/jobs/{jobid}
URL Parameters
Parameter | Description |
---|---|
jobid |
The hexadecimal job identifier |
Query Parameters
Parameter | Values | Description |
---|---|---|
sources |
Any valid source name | Limit the job details returned to results from specific sources |
tests |
Any valid test | Limit the job details returned to the results of specific tests |
status |
error , in_progress , complete |
Limit the job details returned to results with the specific statuses |
Retrieving the job list
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"
curl -i "https://staging-api.wheresitup.com/v4/jobs?limit=10" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"
Sample response
HTTP/1.1 200 OK
Date: Fri, 03 Apr 2015 16:02:14 GMT
Server: Apache/2.2.22 (Debian)
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"54d108b7f8037aa70d8b4567": {
"easy_time": "Tue, 03 Feb 2015 10:43:19 -0700",
"expiry": {
"sec": 1438620199,
"usec": 0
},
"ip": "127.0.0.1",
"services": [
{
"checks": [ "shot" ],
"city": "columbus",
"server": "columbus"
}
],
"start_time": 1422985399,
"url": "ftp://ftp1.freebsd.org/pub/FreeBSD/"
},
"54d10aa6f8037aa80d8b4568": {
"easy_time": "Tue, 03 Feb 2015 10:51:34 -0700",
"expiry": {
"sec": 1438620694,
"usec": 0
},
"ip": "127.0.0.1",
"services": [
{
"checks": [ "http" ],
"city": "piscataway",
"server": "piscataway"
},
{
"checks": [ "http" ],
"city": "sandiego",
"server": "sandiego"
}
],
"start_time": 1422985894,
"url": "http://wondernetwork.com/geotest"
}
}
Retrieves metadata about the most recent jobs, in descending date order.
HTTP Request
GET https://staging-api.wheresitup.com/v4/jobs
Query Parameters
Parameter | Description |
---|---|
limit | The number of jobs to retrieve |
Tests
The API provides nine individual tests:
Test | Description | Credit cost |
---|---|---|
host |
Perform a DNS host lookup |
1 |
dig |
Perform a DNS dig lookup |
1 |
ping |
Ping a host | 2 |
nametime |
Perform a nametime request and return detailed DNS resolution timing details |
2 |
http |
Perform an HTTP GET or HEAD request with curl and return the HTTP status code and headers |
2 |
fast |
Download all the resources on a page and return detailed pagespeed information | 4 |
trace |
Perform a traceroute lookup |
5 |
edge |
Download a large file and return detailed timing information | 7 |
shot |
Take a screenshot of a URI | 10 |
You can create API jobs with any combination of tests and any combination of sources.
Test timeouts
By default, if one of your tests runs more than 180 seconds, our system considers it to be "timed out". The error
property of the job response lists any timed-out tests. See Retrieving job results for more information.
You can modify the timeout with a global timeout
setting (see Creating jobs), or with a timeout
setting in your individual test options. Test-level timeouts override the global timeout.
host
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://wheresitup.com",
"tests": [ "host" ],
"sources": [ "newyork" ],
"options": {
"host": { "timeout": 10 }
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://wheresitup.com',
[ 'newyork', ],
[ 'host' ],
[ 'host' => [ 'timeout' => 10 ]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['newyork'],
['host'],
{'host': {'timeout': 10}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://wheresitup.com'
job.servers = ['newyork']
job.tests = ['host']
job_id = job.submit().id
Sample response
{
"host": {
"raw": "wheresitup.com has address 69.90.78.103\nwheresitup.com mail is handled by 10 mail.wondernetwork.com.\n",
"summary": {
"aliasCount": 0,
"addressCount": 1,
"mailCount": 1,
"ipv6addressCount": 0,
"ips": ["69.90.78.103"],
"ipv6": [],
"mailServers": [
{
"priority": "10",
"hostname": "mail.wondernetwork.com"
}
]
}
}
}
Performs a host
lookup of the provided domain.
host
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
timeout |
No | integer | Global timeout setting |
Seconds until the test times out and exits. | 30 |
Host Summary Fields
Name | Type | Description |
---|---|---|
aliasCount |
integer | Number of host aliases |
addressCount |
integer | Number of IP addresses |
mailCount |
integer | Number of mail server records |
ipv6addressCount |
integer | Number of IPv6 addresses |
ips |
array | IP addresses associated with the domain |
ipv6 |
array | IPv6 addresses associated with the domain |
mailServers |
object | Details for each mail server |
dig
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://ogi.edu",
"tests": [ "dig" ],
"sources": [ "newyork" ],
"options": {
"dig": { "nameserver": "your.name.server.net" }
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://ogi.edu',
[ 'newyork', ],
[ 'dig' ],
[ 'dig' => [ 'nameserver' => 'your.name.server.net' ]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://ogi.edu',
['newyork'],
['dig'],
{'dig': {'nameserver': 'your.name.server.net'}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://ogi.edu'
job.servers = ['newyork']
job.tests = ['dig']
job.options = {'dig': {'nameserver': 'your.name.server.net'}}
job_id = job.submit().id
Sample response
{
"dig": {
"raw": "\n; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> ogi.edu +time=5\n;; global options: +cmd\n;; Got answer:\n;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55611\n;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2\n\n;; QUESTION SECTION:\n;ogi.edu.\t\t\tIN\tA\n\n;; ANSWER SECTION:\nogi.edu.\t\t86400\tIN\tA\t137.53.244.59\n\n;; AUTHORITY SECTION:\nogi.edu.\t\t86400\tIN\tNS\togidns2.ogi.edu.\nogi.edu.\t\t86400\tIN\tNS\togidns1.ogi.edu.\n\n;; ADDITIONAL SECTION:\nogidns1.ogi.edu.\t86400\tIN\tA\t137.53.221.108\nogidns2.ogi.edu.\t86400\tIN\tA\t137.53.221.107\n\n;; Query time: 166 msec\n;; SERVER: 127.0.0.1#53(127.0.0.1)\n;; WHEN: Fri Jun 17 20:14:13 2016\n;; MSG SIZE rcvd: 117\n\n",
"summary": {
"question": [
{
"domain": "ogi.edu.",
"type": "A"
}
],
"answer": [
{
"domain": "ogi.edu.",
"type": "A",
"ttl": "86400",
"ip": "137.53.244.59"
}
],
"authority": [
{
"domain": "ogi.edu.",
"type": "NS",
"ttl": "86400",
"hostname": "ogidns2.ogi.edu."
},
{
"domain": "ogi.edu.",
"type": "NS",
"ttl": "86400",
"hostname": "ogidns1.ogi.edu."
}
],
"additional": [
{
"domain": "ogidns1.ogi.edu.",
"type": "A",
"ttl": "86400",
"ip": "137.53.221.108"
},
{
"domain": "ogidns2.ogi.edu.",
"type": "A",
"ttl": "86400",
"ip": "137.53.221.107"
}
]
}
}
}
Performs a dig
lookup of the provided domain.
If the target domain is an IP address, dig
will automatically switch to reverse-lookup mode. In that case, the answer
will be a PTR
record with a hostname
property, instead of an A
record with an ip
property.
dig
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
nameserver |
No | string | Local DNS | DNS nameserver to query | "your.name.server.net" |
query-time |
No | integer | 5 | Seconds to wait before the query times out. Corresponds to the +time command-line flag. |
3 |
timeout |
No | integer | Global timeout setting |
Seconds until the test times out and exits. | 30 |
Dig Summary Fields
Name | Type | Description |
---|---|---|
question |
array of objects | domain and type for each QUESTION record. |
answer |
array of objects | domain , type ttl and ip for each ANSWER record, if present. |
authority |
array of objects | domain , type ttl and hostname for each AUTHORITY record, if present. SOA (start-of-authority) records also include a soa property. |
additional |
array of objects | domain , type ttl and ip for each ADDITIONAL record, if present. |
ping
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://wheresitup.com",
"tests": [ "ping" ],
"sources": [ "newyork" ],
"options": {
"ping": { "count": 3 }
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://wheresitup.com',
[ 'newyork', ],
[ 'ping' ],
[ 'ping' => [ 'count' => 15 ]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['newyork'],
['ping'],
{'ping': {'count': 15}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://wheresitup.com'
job.servers = ['newyork']
job.tests = ['ping']
job_id = job.submit().id
Sample response
{
"ping": {
"raw": "PING wheresitup.com (69.90.78.103) 56(84) bytes of data.\n64 bytes from 69.90.78.103: icmp_req=1 ttl=63 time=72.7 ms\n64 bytes from 69.90.78.103: icmp_req=2 ttl=63 time=74.2 ms\n64 bytes from 69.90.78.103: icmp_req=3 ttl=63 time=72.8 ms\n\n--- wheresitup.com ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 1001ms\nrtt min/avg/max/mdev = 72.734/73.252/74.210/0.746 ms\n\nPings requested: 3\n",
"summary": {
"pings": [
{
"raw": "64 bytes from 69.90.78.103: icmp_req=1 ttl=63 time=72.7 ms",
"bytes": "64",
"ip": "69.90.78.103",
"icmp_req": "1",
"ttl": "63",
"ms": "72.7"
},
{
"raw": "64 bytes from 69.90.78.103: icmp_req=2 ttl=63 time=74.2 ms",
"bytes": "64",
"ip": "69.90.78.103",
"icmp_req": "2",
"ttl": "63",
"ms": "74.2"
},
{
"raw": "64 bytes from 69.90.78.103: icmp_req=3 ttl=63 time=72.8 ms",
"bytes": "64",
"ip": "69.90.78.103",
"icmp_req": "3",
"ttl": "63",
"ms": "72.8"
}
],
"summary": {
"transmitted": "3",
"received": "3",
"packetloss": "0%",
"time": "1001ms",
"min": "72.734",
"avg": "73.252",
"max": "74.210",
"mdev": "0.746 ms",
"requested": "3",
"timedout": false
}
}
}
}
Performs a ping
against the provided domain.
ping
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
interval |
No | float | 0.5 | Seconds to wait in between sending packets. Corresponds to the -i command-line flag. |
1.3 |
count |
No | integer | 10 | Number of pings to send. Corresponds to the -c command-line flag. |
30 |
timeout |
No | integer | Global timeout |
Seconds before the test will time out and exit. Corresponds to the -w command-line flag. |
60 |
The ping
test response includes the raw ping
output, as well as a parsed summary.
Ping Summary Fields
Name | Type | Description |
---|---|---|
pings |
array of objects | Parsed details for each ping (see below) |
summary |
object | Summarized ping data (see below) |
Parsed Ping Data
Name | Type | Description |
---|---|---|
raw |
string | One line of raw ping output |
bytes |
string | Bytes sent in ping |
ip |
string | IP address pinged |
icmp_req |
string | Ping sequence |
ttl |
string | Router hop counter |
ms |
string | Round-trip time in milliseconds |
Summarized Ping Data
Name | Type | Description |
---|---|---|
transmitted |
string | Number of pings sent |
received |
string | Number of pings returned |
packetloss |
string | Percentage of pings not returned |
time |
string | Total ping time in milliseconds |
min |
string | Fastest ping time in milliseconds |
avg |
string | Average ping time in milliseconds |
max |
string | Slowest ping time in milliseconds |
mdev |
string | Ping time standard deviation |
requested |
number | Number of pings requested |
timedout |
boolean | true if the test timed out before all the requested pings were transmitted |
nametime
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://wheresitup.com",
"tests": [ "nametime" ],
"sources": [ "newyork" ],
"options": {
"nametime": { "nameserver": "8.8.4.4:53" }
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://wheresitup.com',
[ 'newyork', ],
[ 'nametime' ],
[ 'nametime' => [ 'nameserver' => '8.8.4.4:53' ]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['newyork'],
['nametime'],
{'nametime': {'nameserver': '8.8.4.4:53'}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://wheresitup.com'
job.servers = ['newyork']
job.tests = ['nametime']
job.options = {'nametime': {'nameserver': '8.8.4.4:53'}}
job_id = job.submit().id
Sample response
{
"nametime": {
"raw": {
"Domain": "wheresitup.com",
"DnsServer": "8.8.4.4:53",
"AvgConnTime": 7.196e-5,
"AvgTime": 0.03922356
},
"summary": {
"resolve": 0.03922356,
"connect": 7.196e-5
}
}
}
Measures connection and resolution speed of a DNS nameserver using the provided domain. See the nametime
project for more details.
nametime
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
nameserver |
Yes | string | None | DNS nameserver (IPv4 or hostname) and port to measure | "8.8.4.4:53" |
times-to-check |
No | integer | 25 | Number of lookups on which to base the averages | 100 |
timeout |
No | integer | Global timeout setting |
Seconds until the test times out and exits. | 30 |
Nametime Summary Fields
Name | Type | Description |
---|---|---|
resolve |
float | Average time in seconds to resolve the domain to nameserver . |
connect |
float | Average time in seconds to connect to nameserver . |
http
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "http://example.org",
"tests": [ "http" ],
"sources": [ "newyork" ],
"options": {
"http": { "method": "HEAD" }
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'http://example.org',
[ 'newyork', ],
[ 'http' ],
[ 'http' => [ 'method' => 'HEAD' ]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['newyork'],
['http'],
{'http': {'method': 'HEAD'}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://wheresitup.com'
job.servers = ['newyork']
job.tests = ['http']
job.options = {'http': {'method': 'HEAD'}}
job_id = job.submit().id
Sample response
HTTP/1.1 200 OK
Date: Sun, 01 Mar 2015 22:08:14 GMT
Server: Apache/2.2.22 (Debian)
X-Frame-Options: SAMEORIGIN
Content-Length: 3843
Content-Type: application/json; charset=UTF-8
{
"request": {
"easy_time": "Sun, 01 Mar 2015 15:07:40 -0700",
"expiry": {
"sec": 1425334060,
"usec": 0
},
"ip": "127.0.0.1",
"start_time": 1425247660,
"url": "http://example.org"
},
"response": {
"complete": {
"newyork": {
"http": {
"raw": [
{
"details": {
"ip": "93.184.216.34"
},
"full": [
"15:08:11.490142 * About to connect() to wheresitup.com port 80 (#0)",
"15:08:11.490290 * Trying 64.34.27.91...",
"15:08:11.582327 * connected",
"15:08:11.582427 * Connected to wheresitup.com (64.34.27.91) port 80 (#0)",
"15:08:11.582549 > HEAD /1.1' HTTP/1.1",
"15:08:11.582549 > User-Agent: curl/7.26.0",
"15:08:11.582549 > Host: wheresitup.com",
"15:08:11.582549 > Accept: */*",
"15:08:11.582549 >",
"15:08:11.582625 * additional stuff not fine transfer.c:1037: 0 0",
"15:08:11.666652 * HTTP 1.1 or later with persistent connection, pipelining supported",
"15:08:11.666741 < HTTP/1.1 404 Not Found",
"15:08:11.666809 < Date: Sun, 01 Mar 2015 22:08:06 GMT",
"15:08:11.666843 < Server: Apache",
"15:08:11.666858 < Vary: Accept-Encoding",
"15:08:11.666886 < Content-Type: text/html; charset=iso-8859-1",
"15:08:11.666918 * no chunk, no close, no size. Assume close to signal end",
"15:08:11.666937 <",
"15:08:11.666993 * Closing connection #0",
"15:08:11.744985 * About to connect() to example.org port 80 (#0)",
"15:08:11.745043 * Trying 93.184.216.34...",
"15:08:11.796530 * connected",
"15:08:11.796656 * Connected to example.org (93.184.216.34) port 80 (#0)",
"15:08:11.796782 > HEAD / HTTP/1.1",
"15:08:11.796782 > User-Agent: curl/7.26.0",
"15:08:11.796782 > Host: example.org",
"15:08:11.796782 > Accept: */*",
"15:08:11.796782 >",
"15:08:11.796926 * additional stuff not fine transfer.c:1037: 0 0",
"15:08:11.841079 * HTTP 1.1 or later with persistent connection, pipelining supported",
"15:08:11.841221 < HTTP/1.1 200 OK",
"15:08:11.841238 < Accept-Ranges: bytes",
"15:08:11.841274 < Cache-Control: max-age=604800",
"15:08:11.841299 < Content-Type: text/html",
"15:08:11.841329 < Date: Sun, 01 Mar 2015 22:08:09 GMT",
"15:08:11.841345 < Etag: \"359670651\"",
"15:08:11.841360 < Expires: Sun, 08 Mar 2015 22:08:09 GMT",
"15:08:11.841395 < Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT",
"15:08:11.841411 < Server: ECS (rhv/818F)",
"15:08:11.841425 < X-Cache: HIT",
"15:08:11.841440 < x-ec-custom-error: 1",
"15:08:11.841455 < Content-Length: 1270",
"15:08:11.841470 <",
"15:08:11.841511 * Connection #0 to host example.org left intact",
"15:08:11.841547 * Closing connection #0"
],
"response": {
"Accept-Ranges": "bytes",
"Cache-Control": "max-age=604800",
"Content-Length": "1270",
"Content-Type": [
"text/html; charset=iso-8859-1",
"text/html"
],
"Date": [
"Sun, 01 Mar 2015 22:08:06 GMT",
"Sun, 01 Mar 2015 22:08:09 GMT"
],
"Etag": "\"359670651\"",
"Expires": "Sun, 08 Mar 2015 22:08:09 GMT",
"Last-Modified": "Fri, 09 Aug 2013 23:54:35 GMT",
"Response Code": 200,
"Response Status": "OK",
"Server": [
"Apache",
"ECS (rhv/818F)"
],
"Vary": "Accept-Encoding",
"X-Cache": "HIT",
"X-Ec-Custom-Error": "1"
},
"response_headers": "HTTP/1.1 404 Not Found\nDate: Sun, 01 Mar 2015 22:08:06 GMT\nServer: Apache\nVary: Accept-Encoding\nContent-Type: text/html; charset=iso-8859-1\nHTTP/1.1 200 OK\nAccept-Ranges: bytes\nCache-Control: max-age=604800\nContent-Type: text/html\nDate: Sun, 01 Mar 2015 22:08:09 GMT\nEtag: \"359670651\"\nExpires: Sun, 08 Mar 2015 22:08:09 GMT\nLast-Modified: Fri, 09 Aug 2013 23:54:35 GMT\nServer: ECS (rhv/818F)\nX-Cache: HIT\nx-ec-custom-error: 1\nContent-Length: 1270\n",
"serverName": "newyork",
"timing": {
"close": "15:08:11.841511",
"connected": "15:08:11.796656",
"first": "15:08:11.841221",
"last": "15:08:11.841470",
"sent": "15:08:11.796782",
"start": "15:08:11.744985"
}
}
],
"summary": [
{
"contentLength": "1270",
"responseCode": 200,
"responseStatus": "OK",
"serverIP": "93.184.216.34",
"timingConnected": "0.051671",
"timingRequest": "0.096485",
"timingResponse": "0.096236",
"timingTransfer": "0.096526"
}
]
}
}
},
"error": [],
"in_progress": []
}
}
Performs an HTTP request against the specified URI with curl
:
curl --silent --location --max-redirs 2 --verbose --trace-time
The http
test response includes the full HTTP response headers and the response body. The API follows a maximum of 2 Location
redirects by default, and returns the full request and response headers for each. (You can adjust the number of Location
redirects to follow with the max-redirects
option, below.)
http
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
method |
No | string | "HEAD" |
HTTP method to use (GET or HEAD ) |
"GET" |
headers |
No | array of strings | One or more headers to include with the request | ["X-Custom: Custom header values"] |
|
timeout |
No | integer | Global timeout setting |
Seconds until the request times out and exits. Corresponds to the --max-time command-line flag. |
30 |
max-redirects |
No | integer | 2 | Number of HTTP redirects this request will follow. Maximum of 10. | 5 |
HTTP Timestamps
The timings
property contains a series of UTC timestamps marking specific events in the request.
Name | Description |
---|---|
start |
Request initialized, before the connection is established |
connected |
Connection established |
sent |
Request headers sent |
first |
First response header received |
last |
All response headers received |
close |
Connection complete |
HTTP Summary Fields
The summary
object includes a subset of the following properties.
Name | Type | Description |
---|---|---|
location |
string | Target for redirects |
contentLength |
string | Size of the response in bytes (i.e. the Content-Length header) |
responseCode |
integer | HTTP status code |
responseStatus |
string | Standard description for the HTTP status code |
serverIP |
string | IP address hosting the URI |
timingConnected |
string | Elapsed seconds from start (in the timings section, above) to connected |
timingRequest |
string | Elapsed seconds from start to last |
timingResponse |
string | Elapsed seconds from start to first |
timingTransfer |
string | Elapsed seconds from start to close |
The timing*
properties may be -1
if the request failed.
fast
HAR sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://wheresitup.com",
"tests": [ "fast" ],
"sources": [ "newyork" ],
"options": {
"fast": {
"timeout": 10,
"output-type": "har"
}
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://wheresitup.com',
[ 'newyork', ],
[ 'fast' ],
[ 'fast' => [
'timeout' => 10,
'output-type' => 'har',
]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['newyork'],
['fast'],
{'fast': {'timeout': 10, 'output-type': 'har'}}
)
HAR sample response
{
"fast": {
"raw": {
"status": "success",
"time": 1799,
"har_file": "https://wheresitup-job-data.s3.amazonaws.com/har-newyork-abcdefgh.json"
},
"summary": {
"status": "success",
"time": 1799
}
}
}
Netlog-style sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://wheresitup.com",
"tests": [ "fast" ],
"sources": [ "newyork" ],
"options": {
"fast": { "timeout": 10 }
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://wheresitup.com',
[ 'newyork', ],
[ 'fast' ],
[ 'fast' => [ 'timeout' => 10 ]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['newyork'],
['fast'],
{'fast': {'timeout': 10}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://wheresitup.com'
job.servers = ['newyork']
job.tests = ['fast']
job_id = job.submit().id
Netlog-style sample response
{
"fast": {
"raw": {
"details": [
{
"bodySize": 34236,
"contentType": "text/html; charset=utf-8",
"headers": [
{
"name": "Date",
"value": "Thu, 26 Mar 2015 23:44:56 GMT"
},
{
"name": "Server",
"value": "Apache"
},
{
"name": "Vary",
"value": "Accept-Encoding"
},
{
"name": "Content-Encoding",
"value": "gzip"
},
{
"name": "Keep-Alive",
"value": "timeout=15, max=100"
},
{
"name": "Connection",
"value": "Keep-Alive"
},
{
"name": "Content-Type",
"value": "text/html; charset=utf-8"
}
],
"id": 1,
"redirectURL": null,
"stage": "start",
"status": 200,
"statusText": "OK",
"time": "2015-03-26T23:44:58.323Z",
"tsend": 1427413498323,
"tsstart": 1427413497305,
"url": "https://wheresitup.com/"
},
...
],
"status": "success",
"time": 2468
},
"summary": {
"status": "success",
"time": 2468
}
}
}
fast
uses PhantomJS to load the Job URI. fast
requests return the page load time and detailed information about each requested resource.
By default, fast
builds its page load details using raw PhantomJS data types (using a script similar to netlog.js
). fast
may instead return the URL for an HTTP Archive (HAR) built with the 1.2 specification. fast
returns either netlog
-style output (the default) or a HAR file URL: you cannot request both output types.
fast
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
output-type |
No | string | netlog |
Type of output to return. netlog returns page load details in the raw property of the response (see below). har returns the URL to a HAR file. |
"har" |
timeout |
No | integer | Global timeout setting |
Seconds until the test times out and exits. | 30 |
fast
Summary
The summary
property of the response contains high-level information covering the whole request.
Name | Type | Description |
---|---|---|
status |
string | success or fail , depending on the request result |
time |
integer | Request/response time in milliseconds |
fast
Raw Output
The raw
property of the fast
response contains page load details, as well as the summary
details above.
Name | Type | Description |
---|---|---|
status |
string | success or fail , depending on the request result |
time |
integer | Request/response time in milliseconds |
details |
array of objects | netlog -style output only: Page load details and timing information for each resource on the page. |
har_file |
string | har output only: URL to a HAR file containing HTTP transaction details |
fast
Details
If you requested netlog
-style output, the raw.details
property is an array of objects, each containing low-level information about an individual resource loaded on the target page.
Name | Type | Description |
---|---|---|
id |
integer | Sequence number of the requested resource |
url |
string | URL of the requested resource |
time |
string | ISO 8601 UTC timestamp |
headers |
array of objects | HTTP headers received from the requested resource |
bodySize |
integer | Size in bytes of the received content decompressed (entire content or chunk content). (Note that this value may not be consistent.) |
contentType |
string | Value of the Content-Type header, if specified |
redirectURL |
string | Value of the Location header, if specified |
stage |
string | start or end , for chunked requests |
status |
integer | HTTP status code |
statusText |
string | HTTP status text |
tsend |
integer | Response time as a Unix timestamp |
tsstart |
integer | Request time as a Unix timestamp |
trace
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://wheresitup.com",
"tests": [ "trace" ],
"sources": [ "saltlakecity" ],
"options": {
"trace": { "max-hops": 10 }
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://wheresitup.com',
[ 'saltlakecity', ],
[ 'trace' ],
[ 'trace' => [ 'max-hops' => 10 ]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['saltlakecity'],
['trace'],
{'trace': {'max-hops': 10}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://wheresitup.com'
job.servers = ['saltlakecity']
job.tests = ['trace']
job_id = job.submit().id
Sample response
{
"trace": {
"raw": [
"traceroute to wheresitup.com (64.34.27.91), 50 hops max, 60 byte packets",
" 1 209.236.75.1.static.westdc.net (209.236.75.1) 1.035 ms 0.996 ms 0.977 ms",
" 2 206.130.126.66.west-datacenter.net (206.130.126.66) 0.617 ms * 206.130.126.62.west-datacenter.net (206.130.126.62) 0.540 ms",
" 3 206.130.126.25.west-datacenter.net (206.130.126.25) 0.737 ms 0.856 ms 206.130.126.9.west-datacenter.net (206.130.126.9) 1.103 ms",
" 4 * * *",
" 5 xe-11-0-0.cr0-tor1.ip4.gtt.net (141.136.105.214) 49.903 ms 49.903 ms 49.885 ms",
" 6 peer1-gw.ip4.gtt.net (77.67.68.10) 61.314 ms 61.357 ms 61.325 ms",
" 7 * * *",
" 8 * * *",
" 9 * * *",
"10 * * *"
],
"summary": [
[
"209.236.75.1.static.westdc.net (209.236.75.1)",
"1.035 ms",
"0.996 ms",
"0.977 ms",
0,
1
],
[
"206.130.126.66.west-datacenter.net (206.130.126.66)",
"0.617 ms",
"—",
"—",
1,
2
],
[
"206.130.126.62.west-datacenter.net (206.130.126.62)",
"—",
"—",
"0.540 ms",
1,
2
],
[
"206.130.126.25.west-datacenter.net (206.130.126.25)",
"0.737 ms",
"0.856 ms",
"—",
0,
3
],
[
"206.130.126.9.west-datacenter.net (206.130.126.9)",
"—",
"—",
"1.103 ms",
0,
3
],
[
"*",
"—",
"—",
"—",
1,
4
],
[
"xe-11-0-0.cr0-tor1.ip4.gtt.net (141.136.105.214)",
"49.903 ms",
"49.903 ms",
"49.885 ms",
0,
5
],
[
"peer1-gw.ip4.gtt.net (77.67.68.10)",
"61.314 ms",
"61.357 ms",
"61.325 ms",
1,
6
]
]
}
}
Performs a traceroute
call against the provided domain.
trace
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
max-hops |
No | integer | 50 | Maximum number of hops. Corresponds to the -m command-line flag. |
20 |
wait-time |
No | integer | 5 | Seconds to wait for a response to a probe. Corresponds to the -w command-line flag. |
3 |
timeout |
No | integer | Global timeout setting |
Seconds until the test times out and exits. | 30 |
Trace Summary Fields
The trace
summary is an array of parsed traceroute
output lines. Each line is an array that represents the the response from a single host.
- The first element is the host.
- The following three elements are the round trip times for each probe. Probes that did not receive a response from the host are represented as
—
. - The fifth element is deprecated.
- The sixth element is the TTL.
If a TTL received responses from two or three hosts, that TTL will have two or three entries in the summary
.
If a TTL received no responses, the summary
will include the entry with an asterisk (*
) for the host. Thesummary
will not include no-response TTLs that trail at the end of the output.
edge
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://wheresitup.com",
"tests": [ "edge" ],
"sources": [ "newyork" ],
"options": {
"edge": { "headers": ["X-Custom-1: Value", "X-Custom-2: Value 2"] }
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://wheresitup.com',
[ 'newyork', ],
[ 'edge' ],
[ 'edge' => [ 'headers' => ['X-Custom-1: Value', 'X-Custom-2: Value 2']]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['newyork'],
['edge'],
{'edge': {'headers': ['X-Custom-1: Value', 'X-Custom-2: Value 2']}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://wheresitup.com'
job.servers = ['newyork']
job.tests = ['edge']
job.options = {'edge': {'headers': ['X-Custom-1: Value', 'X-Custom-2: Value 2']}}
job_id = job.submit().id
Sample response
{
"edge": {
"raw": [
{
"full": [
"18:03:09.416207 * getaddrinfo(3) failed for Value':80",
"18:03:09.416340 * Couldn't resolve host 'Value''",
"18:03:09.416360 * Closing connection #0",
"18:03:09.481612 * getaddrinfo(3) failed for Value:80",
"18:03:09.481667 * Couldn't resolve host 'Value'",
"18:03:09.481686 * Closing connection #0",
"18:03:09.565831 * getaddrinfo(3) failed for 2':80",
"18:03:09.565890 * Couldn't resolve host '2''",
"18:03:09.565909 * Closing connection #0",
"18:03:09.785557 * About to connect() to wheresitup.com port 80 (#0)",
"18:03:09.785654 * Trying 69.90.78.103...",
"18:03:09.860632 * connected",
"18:03:09.860772 * Connected to wheresitup.com (69.90.78.103) port 80 (#0)",
"18:03:09.860896 > GET \/1.1' HTTP\/1.1",
"18:03:09.860896 > User-Agent: curl\/7.26.0",
"18:03:09.860896 > Host: wheresitup.com",
"18:03:09.860896 > Accept: *\/*",
"18:03:09.860896 >",
"18:03:09.861015 * additional stuff not fine transfer.c:1037: 0 0",
"18:03:09.939619 * HTTP 1.1 or later with persistent connection, pipelining supported",
"18:03:09.939736 < HTTP\/1.1 301 Moved Permanently",
"18:03:09.939754 < Date: Fri, 27 Mar 2015 00:03:04 GMT",
"18:03:09.939769 < Server: Apache",
"18:03:09.939787 < Location: https:\/\/wheresitup.com\/1.1'",
"18:03:09.939803 < Vary: Accept-Encoding",
"18:03:09.939819 < Content-Length: 235",
"18:03:09.939835 < Content-Type: text\/html; charset=iso-8859-1",
"18:03:09.939856 <",
"18:03:09.939871 * Ignoring the response-body",
"18:03:09.939886 { [data not shown]",
"18:03:09.939930 * Connection #0 to host wheresitup.com left intact"
],
"serverName": "newyork",
"timing": {
"start": "18:03:09.785557",
"connected": "18:03:09.860772",
"sent": "18:03:09.860896",
"first": "18:03:09.939736",
"last": "18:03:09.939856",
"close": "18:03:09.939930"
},
"details": {"ip": "69.90.78.103"},
"response_headers": "HTTP\/1.1 301 Moved Permanently\nDate: Fri, 27 Mar 2015 00:03:04 GMT\nServer: Apache\nLocation: https:\/\/wheresitup.com\/1.1'\nVary: Accept-Encoding\nContent-Length: 235\nContent-Type: text\/html; charset=iso-8859-1\n",
"response": {
"Response Code": 301,
"Response Status": "Moved Permanently",
"Date": "Fri, 27 Mar 2015 00:03:04 GMT",
"Server": "Apache",
"Location": "https:\/\/wheresitup.com\/1.1'",
"Vary": "Accept-Encoding",
"Content-Length": "235",
"Content-Type": "text\/html; charset=iso-8859-1"
}
},
{
"full": [
"18:03:09.939948 * Issue another request to this URL: 'https:\/\/wheresitup.com\/1.1''",
"18:03:10.075054 * About to connect() to wheresitup.com port 443 (#1)",
"18:03:10.075108 * Trying 69.90.78.103...",
"18:03:10.150181 * connected",
"18:03:10.150296 * Connected to wheresitup.com (69.90.78.103) port 443 (#1)",
"18:03:10.150766 * successfully set certificate verify locations:",
"18:03:10.150805 * CAfile: none",
"18:03:10.151026 * SSLv3, TLS handshake, Client hello (1):",
"18:03:10.151044 } [data not shown]",
"18:03:10.232324 * SSLv3, TLS handshake, Server hello (2):",
"18:03:10.232425 { [data not shown]",
"18:03:10.234236 * SSLv3, TLS handshake, CERT (11):",
"18:03:10.234277 { [data not shown]",
"18:03:10.235740 * SSLv3, TLS handshake, Server key exchange (12):",
"18:03:10.235785 { [data not shown]",
"18:03:10.235960 * SSLv3, TLS handshake, Server finished (14):",
"18:03:10.235998 { [data not shown]",
"18:03:10.236765 * SSLv3, TLS handshake, Client key exchange (16):",
"18:03:10.236807 } [data not shown]",
"18:03:10.236832 * SSLv3, TLS change cipher, Client hello (1):",
"18:03:10.236848 } [data not shown]",
"18:03:10.236953 * SSLv3, TLS handshake, Finished (20):",
"18:03:10.236982 } [data not shown]",
"18:03:10.310534 * SSLv3, TLS change cipher, Client hello (1):",
"18:03:10.310587 { [data not shown]",
"18:03:10.310688 * SSLv3, TLS handshake, Finished (20):",
"18:03:10.310704 { [data not shown]",
"18:03:10.310757 * SSL connection using ECDHE-RSA-AES256-GCM-SHA384",
"18:03:10.310788 * Server certificate:",
"18:03:10.310824 * \t subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.wheresitup.com",
"18:03:10.310842 * \t start date: 2015-02-21 00:00:00 GMT",
"18:03:10.310859 * \t expire date: 2020-02-20 23:59:59 GMT",
"18:03:10.310935 * \t subjectAltName: wheresitup.com matched",
"18:03:10.310966 * \t issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Domain Validation Secure Server CA",
"18:03:10.311074 * \t SSL certificate verify ok.",
"18:03:10.311164 > GET \/1.1' HTTP\/1.1",
"18:03:10.311164 > User-Agent: curl\/7.26.0",
"18:03:10.311164 > Host: wheresitup.com",
"18:03:10.311164 > Accept: *\/*",
"18:03:10.311164 >",
"18:03:10.311335 * additional stuff not fine transfer.c:1037: 0 0",
"18:03:10.384931 * HTTP 1.1 or later with persistent connection, pipelining supported",
"18:03:10.384973 < HTTP\/1.1 404 Not Found",
"18:03:10.384990 < Date: Fri, 27 Mar 2015 00:03:04 GMT",
"18:03:10.385007 < Server: Apache",
"18:03:10.385022 < Vary: Accept-Encoding",
"18:03:10.385037 < Content-Length: 202",
"18:03:10.385054 < Content-Type: text\/html; charset=iso-8859-1",
"18:03:10.385069 <",
"18:03:10.385123 { [data not shown]",
"18:03:10.385196 * Connection #1 to host wheresitup.com left intact",
"18:03:10.385398 * Re-using existing connection! (#1) with host (nil)",
"18:03:10.385507 * Connected to (nil) (69.90.78.103) port 443 (#1)",
"18:03:10.385625 > GET \/ HTTP\/1.1",
"18:03:10.385625 > User-Agent: curl\/7.26.0",
"18:03:10.385625 > Host: wheresitup.com",
"18:03:10.385625 > Accept: *\/*",
"18:03:10.385625 >",
"18:03:10.385737 * additional stuff not fine transfer.c:1037: 0 0",
"18:03:10.464174 * HTTP 1.1 or later with persistent connection, pipelining supported",
"18:03:10.464275 < HTTP\/1.1 200 OK",
"18:03:10.464296 < Date: Fri, 27 Mar 2015 00:03:04 GMT",
"18:03:10.464311 < Server: Apache",
"18:03:10.464326 < Vary: Accept-Encoding",
"18:03:10.464354 < Transfer-Encoding: chunked",
"18:03:10.464371 < Content-Type: text\/html; charset=utf-8",
"18:03:10.464387 <",
"18:03:10.464438 { [data not shown]",
"18:03:10.617644 * Connection #1 to host (nil) left intact",
"18:03:10.617699 * Closing connection #0",
"18:03:10.617794 * Closing connection #1",
"18:03:10.618032 * SSLv3, TLS alert, Client hello (1):",
"18:03:10.618067 } [data not shown]",
"d41d8cd98f00b204e9800998ecf8427e \/tmp\/tmp.BVtV94ybXc"
],
"serverName": "newyork",
"timing": {
"start": "18:03:10.075054",
"connected": "18:03:10.385507",
"sent": "18:03:10.385625",
"first": "18:03:10.464275",
"last": "18:03:10.464387"
},
"details": {
"ip": "69.90.78.103",
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"response_headers": "HTTP\/1.1 404 Not Found\nDate: Fri, 27 Mar 2015 00:03:04 GMT\nServer: Apache\nVary: Accept-Encoding\nContent-Length: 202\nContent-Type: text\/html; charset=iso-8859-1\nHTTP\/1.1 200 OK\nDate: Fri, 27 Mar 2015 00:03:04 GMT\nServer: Apache\nVary: Accept-Encoding\nTransfer-Encoding: chunked\nContent-Type: text\/html; charset=utf-8\n",
"response": {
"Response Code": 200,
"Response Status": "OK",
"Date": [
"Fri, 27 Mar 2015 00:03:04 GMT",
"Fri, 27 Mar 2015 00:03:04 GMT"
],
"Server": [
"Apache",
"Apache"
],
"Vary": [
"Accept-Encoding",
"Accept-Encoding"
],
"Content-Length": "202",
"Content-Type": [
"text\/html; charset=iso-8859-1",
"text\/html; charset=utf-8"
],
"Transfer-Encoding": "chunked"
}
}
],
"summary": [
{
"responseCode": 301,
"responseStatus": "Moved Permanently",
"location": "https:\/\/wheresitup.com\/1.1'",
"contentLength": "235",
"serverIP": "69.90.78.103",
"timingConnected": "0.075215",
"timingResponse": "0.154179",
"timingRequest": "0.154299",
"timingTransfer": "0.154373"
},
{
"responseCode": 200,
"responseStatus": "OK",
"contentLength": "202",
"serverIP": "69.90.78.103",
"md5": "d41d8cd98f00b204e9800998ecf8427e",
"timingConnected": "0.310453",
"timingResponse": "0.389221",
"timingRequest": "0.389333",
"timingTransfer": -1
}
]
}
}
Downloads a file from a remote server and returns the timing details, as well as the hash of downloaded file.
edge
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
headers |
No | array of strings | One or more headers to include with the request | ["X-Custom: Custom header values"] |
|
timeout |
No | integer | Global timeout setting |
Seconds until the request times out and exits. Corresponds to the --max-time command-line flag. |
30 |
Edge Summary Fields
The edge
output summary is nearly identical to the http
output summary, with the addition of an md5
property for the content hash of the downloaded file.
shot
Sample request
curl -i "https://staging-api.wheresitup.com/v4/jobs" \
-H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d \
'{
"uri": "https://wheresitup.com",
"tests": [ "shot" ],
"sources": [ "newyork" ],
"options": {
"shot": {
"size": { "width": 400, "height": 300 },
"resize": "33%"
}
}
}'
<?php
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
$jobID = $api->submit(
'https://wheresitup.com',
[ 'newyork', ],
[ 'shot' ],
[ 'shot' => [
'size' => ['width' => 400, 'height' => 300],
'resize' => '33%'
]]
);
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
# raw API
job_id = api.submit(
'https://wheresitup.com',
['newyork'],
['shot'],
{'shot': {
'size': {'width': 400, 'height': 300},
'resize': '33%'
}}
)
# Job wrapper
job = wiuppy.Job(api)
job.uri = 'https://wheresitup.com'
job.servers = ['newyork']
job.tests = ['shot']
job.options = {'shot': {
'size': {'width': 400, 'height': 300},
'resize': '33%'
}}
job_id = job.submit().id
Sample response
{
"shot": {
"raw": [
"worker-out-full: https://shothack.s3.amazonaws.com/shot-newyork-job_id-wiu.png",
"worker-out-thumb: https://shothack.s3.amazonaws.com/shot-newyork-job_id-thumb-wiu.png"
],
"summary": {
"full": "https://shothack.s3.amazonaws.com/shot-newyork-job_id-wiu.png",
"thumb": "https://shothack.s3.amazonaws.com/shot-newyork-job_id-thumb-wiu.png"
}
}
}
Takes a screenshot of the specified URL and returns a URL to access the screenshot and an optional thumbnail.
shot
options
Option | Required | Type | Default | Description | Sample (JSON) |
---|---|---|---|---|---|
size |
No | object | { "width": 800, "height": 600 } |
Width and height (in pixels) of the viewport (i.e. the browser window size) for the screenshot. | { "width": 1024, "height": 768 } |
resize |
No | string | None | Scaling percentage for the optional thumbnail. For example, a screenshot width of 1000 and a resize of 20% would result in a 200px-wide thumbnail. If resize is not specified, the API will not create a thumbnail. |
"33%" |
timeout |
No | integer | Global timeout setting |
Seconds until the test times out and exits. | 30 |
Shot Summary Fields
Name | Type | Description |
---|---|---|
full |
string (URL) | URL for the full-resolution screenshot |
thumb |
string (URL) | URL for the resized screenshot |
Errors
Sample invalid request
curl -i "https://staging-api.wheresitup.com/v4/sources" \
-h "Auth: Bearer cats dogs"
Sample error response
HTTP/1.1 403 Forbidden
Date: Mon, 21 Apr 2014 05:27:40 GMT
Server: Apache/2.2.22 (Debian)
Content-Length: 39
Content-Type: application/json; charset=UTF-8
{ "message": "Request not authenticated" }
When the API encounters a problem, it returns one of the HTTP status codes listed below. In general, status codes in the 400
range indicate a problem with your request, while codes in the 500
range indicate a problem with the API.
If there is an error message, it will be in the message
property of the response.
Status code | Name | Description |
---|---|---|
400 | Bad Request | The API did not understand your request. |
402 | Payment Required | You do not have enough API credits for your request. |
403 | Forbidden | Your credentials are not authorized. |
404 | Not Found | The resource could not be found. |
405 | Method Not Allowed | The HTTP method you used (e.g. PUT , POST ) is not valid for the resource you requested. |
429 | Too Many Requests | You have exceeded the rate limit. |
500 | Internal Server Error | There was a problem on the API side. |
503 | Service Unavailable | The API is down for maintenance. |
Clients and Examples
The API has clients for PHP, Python and Go:
Language | Location |
---|---|
PHP | Github, Packagist |
Python | Github |
Go | Github |
<?php
use wondernetwork\wiuphp;
require_once __DIR__.'/vendor/autoload.php';
/*
* set up the API with your client ID and token
*/
$api = new wiuphp\API('YOUR_CLIENT_ID', 'YOUR_TOKEN');
/*
* if you're using Memcached, you can cache results to avoid duplicate API
* calls using the MemcachedAPI decorator:
*/
$api = new wiuphp\MemcachedAPI($api, new \Memcached());
/*
* submit a new request to ping http://google.com from Denver and London
*/
$jobID = $api->submit('google.com', ['denver', 'london'], ['ping']);
/*
* poll the job results for 30 seconds or until the results are complete
*/
$seconds = 0; $maxSeconds = 30;
do {
sleep(1);
$job = $api->retrieve($jobID);
} while ($job['response']['in_progress'] && $seconds++ < $maxSeconds);
/*
* report the average ping time on both servers
*/
foreach ($job['response']['complete'] as $server => $tests) {
$average_time = $tests['ping']['summary']['summary']['avg'];
echo "The average ping time from $server is $average_time milliseconds\n";
}
import wiuppy
# set up the API with your client ID and token
api = wiuppy.WIU('YOUR_CLIENT_ID', 'YOUR_TOKEN');
job = wiuppy.Job(api)
# create a new request to ping https://google.com from Denver and London
job.uri = 'https://google.com'
job.servers = ['denver', 'london']
job.tests = ['ping']
# submit the request and wait for the tests to finish
job.submit().retrieve(poll=True)
# report the average ping time on both servers
for server, average_time in [
(server, tests['ping']['summary']['summary']['avg'])
for (server, tests)
in job.results['response']['complete'].items()
]:
print('The average ping time from ' + server + ' is ' + average_time + ' milliseconds')
This example code creates a ping
test on the denver
and london
servers, waits for it to complete, and prints out the summaries.
Changelog
April 2017
General
- We added rate limiting for tests, to help communicate the capabilities of our system and ensure consistent test behavior for all our users.
March 2017
trace
- The
summary
includes the TTL for each line. - TTLs with no reponse or partial responses are no longer excluded from the
summary
.
http
- A new
max-redirects
option controls how manyLocation
header redirects thehttp
test can follow.
August 2016
dig
dig
learned to automatically perform reverse lookups for IP addresses.
June 2016
fast
- A new
output-type
option controls the output format forfast
results. fast
can now format its results using the HTTP Archive 1.2 specification.
dig
- Results include
AUTHORITY
andADDITIONAL
sections. - Test error handling is more consistent.
nametime
- Hostnames (e.g.
ns1.my-name-server.com:53
) are acceptable as thenameserver
.
April 2016
General
- We changed how test timeouts work in an attempt to make test behavior more predictable. Tests no longer terminate after 30 seconds of "silence" (i.e. 30 seconds of producing no output). Instead, a new
timeout
option controls the maximum time an individual test may run.timeout
defaults to 180 seconds, and may be set both globally and on a per-test basis.
dig
- A new
query-time
option controls the timeout for individual DNS queries.
ping
- A new
interval
option sets the time to wait in between sending packets. - A new
count
option controls how many pings to send. - The summarized
ping
data includes two new properties:requested
is the number of pings requestedtimedout
is true if theping
test timed out before therequested
pings were transmitted
nametime
- A new
times-to-check
option controls the number of lookups to use for the average values.
http
- Instead of timing out after 10 seconds,
http
uses thetimeout
option to setcurl
's--max-time
flag.
trace
- A new
max-hops
option sets the maximum number of hops thattraceroute
will probe. - A new
wait-time
options sets the maximum timetraceroute
will wait for a response to a probe.
December 2015
General
- We added a new
/credits
endpoint, to let you check your API credit balance and recent usage.
June 2015
dig
- A new
nameserver
option sets the DNS nameserver thatdig
will query.