You are here: Home > Analyse > Internet Measurements > RIPE Atlas > Documentation > Creating Measurements with the RIPE Atlas Restful API

Creating Measurements with the RIPE Atlas Restful API

This is still very much alpha code, so if you find an issue, please contact us with a bug report and be as detailed as possible. The more information we have, the more we can improve.

Measurement creation is managed based on the premise of having to submit as little information as possible while still obtaining something useful. With that said, even the simplest measurement requires a rather large amount of information to initiate things. We need the type, the af, the description, the target, and a specification telling us which probes you want to use for the measurement. If you omit the start_time, we assume you want it started right away; if you don't set the is_oneoff flag, we assume it must be a regular measurement, and so on.

Structure

Our REST API uses JSON to post data. If you haven't already, it's best to familarise yourself with how this is done before continuing. To get you started, we'll be providing all of the examples using a common *nix utility called curl.

Simple Example

Let's begin with an example. Assume we want to create a simple ping measurement from 50 probes anywhere in the world to ripe.net. Here's how to do this in curl:

$ curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{ "definitions": [ { "target": "ripe.net", "description": "My First Measurement", "type": "ping", "af": 4 } ], "probes": [ { "requested": 50, "type": "area", "value": "WW" } ] }' https://atlas.ripe.net/api/v1/measurement/?key=YOUR_API_KEY

Response

{
    "measurements": [
        123456
    ]
}

Let's break it down to make it more readable.

-H "Content-Type: application/json"

This tells the server to expect POST data in JSON format.

-H "Accept: application/json"

This tells the server we're expecting JSON back.

-X POST

By default, curl sends GET requests. This just tells curl that we want to send a POST request instead.

-d '{...}'

Our POST request contains a lot of data, and as we specified with the Content-Type header, we'll be sending this data in JSON format. This -d flag tells curl to send the following string as the POST argument.

The actual POST Data

Let's take another look at what we're sending, but format it for humans:

{
    "definitions": [
        {
            "target": "ripe.net",
            "description": "My First Measurement",
            "type": "ping",
            "af": 4
        }
    ],
    "probes": [
        {
            "requested": 50,
            "type": "area",
            "value": "WW"
        }
    ]
}

?key=YOUR_API_KEY

You can't just create a measurement and assign it to anyone; that wouldn't be fair. Instead, we make use of our API keys to identify the request as being authorised to create a measurement. You can create and manage your keys by visiting the API Keys page.

Basically, each request has three sections: definitions, probes and a third section we'll cover later in this document: times.

definitions

This is a list of measurement specifications, and it's probably the most complex section. This is where you specify parameters such as whether it's a one-off (is_oneoff) measurement, or that you want 10 packets instead of the default. However, each measurement requires a few simple things by default:

  • target: The target of the measurement. Note that this is not required for dns measurements.
  • description: An arbitrary string you will use to refer to this measurement.
  • type: One of ping,traceroute,dns, sslcert or ntp
  • af: The address family. It must be either 4 or 6.

probes

This section is a little simpler - it's essentially a list of probe requests by region. For our basic case, there's only one request: 50 probes located anywhere in the world.

  • requested: The number of probes you want from the given region.
  • type: The type of request. It can be one of area, country, prefix, asn, probes or msm.
  • value: The lookup used against the given type. This is explained in more detail below, but for our reasons, let's just work with the fact that WW means world-wide.

Based on the above, our API will create a ping measurement hitting the first IPv4 address found at ripe.net, using 50 probes from various points all over the globe.

Definitions

A measurement definition contains a few core properties, and a myriad of type-specific options. For example, while all definitions have an af property, only traceroute measurements have a paris property. Given this, this section is broken up accordingly.

Core properties

These properties are available to all measurement types:

Name Description Default Required? Price Modifier
description The name you give this measurement. This field is entirely arbitrary.   YES  
af The address family. Must be either 4 or 6.   YES  
type The type of measurement you're attempting to create. Must be one of: ping, traceroute, dns, sslcert or ntp.   YES  
resolve_on_probe Set to 'true' if you want the probe to resolve your target instead of the RIPE Atlas servers. false    
is_oneoff Set this to 'true' to make this measurement a one-off. false    
is_public Set this measurement to be public, so that other people can see the results. true    
interval In normal (not one-off) measurements, this value represents the number of seconds between measurements by a single probe. Note that while interval is defined for each measurement type, the default varies, so check the appropriate section below for the default for your specified type. changes with type    

Ping-Specific Properties

Ping requests may use any of those mentioned in the Core Properties section, as well as the following:

Name Description Default Required? Price Modifier
target The target of your measurement. It can be an IP address or a (resolveable) hostname.   YES  
interval In normal (not one-off) measurements, this value represents the number of seconds between measurements by a single probe. 240    
packets The number of packets sent in the ping request. Value must be between 1 and 16 3   × packets ÷ 3
size The size of the packets. Value must be between 1 and 2048     × size ÷ 1500
packet_interval Time between packets (ms). Value must be between 2 and 30000 1000    

Traceroute-Specific Properties

Traceroute requests may use any of those mentioned in the Core Properties section, as well as the following:

Name Description Default Required? Price Modifier
target The target of your measurement. It can be an IP address or a (resolveable) hostname.   YES  
interval In normal (not one-off) measurements, this value represents the number of seconds between measurements by a single probe. 900    
protocol Must be one of ICMP, UDP or TCP. ICMP YES  
dontfrag Don't fragment the packet. false    
paris Use Paris. Value must be between 0 and 64. If 0, a standard traceroute will be performed. 0 NO  
firsthop Value must be between 1 and 255      
maxhops Value must be between 1 and 255      
timeout Value (in milliseconds) must be between 1 and 60000 4000    
size The size of the packets. Value must be between 1 and 2048     × size ÷ 40
port Destination port, valid for TCP only. 80    
destination_option_size IPv6 destination option header      
hop_by_hop_option_size IPv6 hop by hop option header      

DNS-Specific Properties

DNS requests may use any of those mentioned in the Core Properties section, as well as the following:

Name Description Default Required? Price Modifier
target A hostname.      
interval In normal (not one-off) measurements, this value represents the number of seconds between measurements by a single probe. 300    
do Set the DNSSEC OK flag (RFC3225) false    
cd Set the DNSSEC Checking Disabled flag (RFC4035) false    
use_probe_resolver   false    
use_NSID   false    
query_class Must be either "IN" or "CHAOS".   YES  
query_type

Valid types vary by class:

IN: A AAAA ANY CNAME DNSKEY DS MX NS NSEC PTR RRSIG SOA TLSA TXT SRV NAPTR

CHAOS: TXT

  YES  
query_argument     YES  
recursion_desired NOTE: For privacy reasons, when use_probe_resolver is true, this property is silently set to true. false NO  
protocol Must be either "TCP" or "UDP" UDP NO × 2
udp_payload_size May be any integer between 512 and 4096 inclusive. 512 NO  
retry Number of times to retry 0 NO  

SSL Certificate-Specific Properties

SSL certificate requests may use any of those mentioned in the Core Properties section, as well as the following:

Name Description Default Required? Price Modifier
target The target of your measurement. It can be an IP address or a (resolveable) hostname.   YES  
interval In normal (not one-off) measurements, this value represents the number of seconds between measurements by a single probe. 1800    
port   443    

HTTP-Specific Properties

HTTP measurements may use any of those mentioned in the Core Properties section, as well as the following:

Name Description Default Required? Price Modifier
target The target of your measurement. It can be an IP address or a (resolveable) hostname.   YES  
interval In normal (not one-off) measurements, this value represents the number of seconds between measurements by a single probe. 1800    
header_bytes The maximum number of bytes to retrieve from the header. 80    
version The HTTP version to use 1.1    
method The HTTP method to use GET    
port   443    
path   /    
query_string        
user_agent The user-agent used when performing the requrest RIPE Atlas: https://atlas.ripe.net/    
max_bytes_read        
extended_timing A boolean value. Time to Read, Time to Connect, Time to First Byte      
more_extended_timing A boolean value.      

NTP-Specific Properties

NTP requests may use any of those mentioned in the Core Properties section, as well as the following:

Name Description Default Required? Price Modifier
target The target of your measurement. It can be an IP address or a (resolveable) hostname.   YES  
interval In normal (not one-off) measurements, this value represents the number of seconds between measurements by a single probe. 900    
packets Number of requests to send 3    
timeout Time to wait for a response in milliseconds 4000    

Probes

probes, like definitions, is a list with nested sets of key/value pairs.

Basically, there are six types of requests: area, country, prefix, asn, probes and msm. In each case you'll be stating how many probes of that type you'd like to use, (requested) and what subsection of that type you're looking at (value). In addition, you can optionally further restrict each request using probe tags. We'll go over the request types one by one.

Area

For our purposes, the world is broken up into five arbitrary geographical areas:

  • WW (Worldwide)
  • West
  • North-Central
  • South-Central
  • North-East
  • South-East

Country

If you want to request probes by country, specify the ISO two-letter country code here. For Canada for example, you would use CA, for the Netherlands NL, and for South Korea KR.

Prefix

This is an IP prefix. For example:

"probes": [
    {
        "requested": 5,
        "type": "prefix",
        "value": "193.3.6.0/8"
    }
]

ASN

For ASNs, just the number is sufficient. For example:

"probes": [
    {
        "requested": 5,
        "type": "asn",
        "value": 3333
    }
]

Probes

Probes can be explicitly requested by requesting type: "probe", and specifying a comma-separated list of integers as the value:

"probes": [
    {
        "requested": 3,
        "type": "probes",
        "value": "1,2,3"
    }
]

Measurement (msm)

Finally, if you want to use the same probes used in a past measurement, you can employ this option. Simpley specify a measurement ID in the value field:

"probes": [
    {
        "requested": 1,
        "type": "msm",
        "value": 1000002
    }
]

Additional: Probe tags

Any of the above request types can be further restricted based on probe tags. This is achieved by specifying an optional "tags" item which may contain one or both of "include" — a list of tags to require — and "exclude" — a list of tags to prohibit.

e.g. to request 10 probes from anywhere in the world which are in a datacentre, and do have working IPv4 but do not have working IPv6:

"probes": [
    {
        "requested": 10,
        "type": "area",
        "value": "WW"
        "tags": {
            "include": ["datacentre", "system-ipv4-works"],
            "exclude": ["system-ipv6-works"]
        }
    }
]

The Response

Not exactly RESTful - but probably more useful - the response to any successful POST request will render a key/value pairing, (presently with only one key: measurements). It will also render a list of values for that key: measurement IDs created from your POST, in the order they were specified in the definitions list.

Times

As we mentioned earlier, the API supports a third argument: times. As you might have guessed, this is a set of values dictating the start and end times for all measurements you're specifying in the request. In other words, if you send a single request to create two ping measurements targetting ripe.net, you can use times to specify when you'd like both measurements to start and finish. If you want to have two or more measurements start or stop at different times, you must define them in separate API calls.

An Example Request

We'll use our previous simple example, and attach times data to it:

{
    "definitions": [
        {
            "target": "ripe.net",
            "description": "My First Measurement",
            "type": "ping",
            "af": 4
        }
    ],
    "probes": [
        {
            "requested": 50,
            "type": "area",
            "value": "WW"
        }
    ],
    "start_time": 1388534400,
    "stop_time": 1401580800
}

Note that times are always defined as Unix timestamps. In the example above, start_time is defined as 1 January 2014, and stop_time is set to 1 June 2014.

Note that you cannot set a start_time or stop_time in the past. Nor can you set a stop_time earlier than your start_time. Lastly, due to system limitations, you cannot have your start_time and stop_time less than five minutes apart. If you really need this kind of behaviour, you may be better served by a one-off measurement.

A Complex Measurement Request

The following code sample is provided as an example of how complicated this API can get, and is not meant to be executed.

{
    "definitions": [
        {
            "target": "www.ripe.net",
            "description": "My Complex Measurement",
            "type": "traceroute",
            "af": 6,
            "resolve_on_probe": true,
            "is_public": true,
            "packets": 16,
            "protocol": "ICMP",
            "paris": 99,
            "firsthop": 30,
            "interval": 1800,
            "is_oneoff": true
        },
        {
            "target": "www.ripe.net",
            "description": "My Complex Measurement",
            "type": "ping",
            "af": 4,
            "resolve_on_probe": false,
            "is_public": false,
            "is_oneoff": false
        }
    ],
    "probes": [
        {
            "requested": 10,
            "type": "area",
            "value": "WW"
        },
        {
            "requested": 5,
            "type": "country",
            "value": "GR"
        },
        {
            "requested": 5,
            "type": "country",
            "value": "CA"
        },
        {
            "requested": 3,
            "type": "probes",
            "value": [55,19,252]
        },
        {
            "requested": 1,
            "type": "udm",
            "value": 1000002
        }
    ],
    "start_time": 1461807395,
    "stop_time": 1462807395
}

The Response

{
    "measurements": [
        123456789,
        123456790
    ]
}

Error Messages

As with all RESTful servers, you should write your code to act based on the HTTP error codes (404,401, etc.), but in the event that you receive an error, we have added some further explanations here to help you figure out what went wrong.

Code Message Explanation
100 This server only accepts application/JSON content types. The REST server is only capable of reading JSON data from your requests.
101 Your JSON POST request appears to be mal-formed. Make sure your JSON data is properly formatted. Use an online parser if necessary.
102 Invalid input. Please check the documentation. This error presents itself when some of the basic elements of a POST are missing. Make sure that you've supplied a value for definitions and probes, as well as values for description, type, and af in each definition and requested, type and value in each probe request.
103 You are not permitted to run more than %s concurrent measurements. Users are limited to a finite number of measurements they can execute. Attempts to exceed this limit will result in this message.
104 (Variable) This is a blanket error code assigned to any error message that prevents your measurement from running (over and above the others stated here). The message changes based on what's gone wrong, but examples include exceeding the limit of measurements targetting a particular domain, or specifying an excessive number of packets in a ping request.
200 That measurement cannot be stopped. This error is raised when you try to stop a measurement that has already been stopped.