NAV
php python shell

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://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://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://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, 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

Sources

Sample request

# get all available servers
curl -i "https://api.wheresitup.com/v4/sources" \
  -H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"

# get servers in Canada and Brazil
curl -i "https://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://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://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://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://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://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://api.wheresitup.com/v4/jobs" \
    -H "Auth: Bearer YOUR_CLIENT_ID YOUR_TOKEN"

curl -i "https://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://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://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://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://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://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://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://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://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. fastrequests 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://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",
        "&mdash;",
        "&mdash;",
        1,
        2
      ],
      [
        "206.130.126.62.west-datacenter.net (206.130.126.62)",
        "&mdash;",
        "&mdash;",
        "0.540 ms",
        1,
        2
      ],
      [
        "206.130.126.25.west-datacenter.net (206.130.126.25)",
        "0.737 ms",
        "0.856 ms",
        "&mdash;",
        0,
        3
      ],
      [
        "206.130.126.9.west-datacenter.net (206.130.126.9)",
        "&mdash;",
        "&mdash;",
        "1.103 ms",
        0,
        3
      ],
      [
        "*",
        "&mdash;",
        "&mdash;",
        "&mdash;",
        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.

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://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://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://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.
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

March 2017

trace

http

August 2016

dig

June 2016

fast

dig

nametime

April 2016

General

dig

ping

nametime

http

trace

December 2015

General

June 2015

dig