NAV
Shell Python

Getting started

Welcome to the System73 Multi-CDN API documentation! You can use our API to configure most on our platform. You can create, update and delete properties and also retrieve data usage detail and invalidate content.

We have language examples in Shell, and Python. You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.

Our API uses an API token or your login session from our management portal. You can find your System73 Multi-CDN API key at our portal.

In the python examples we use the requests library client to set up a session with the API.

Glossary

Keyword Definition
CDN A Content Delivery Network. We use multiple to guarantee 100% uptime
vhost /
property
An entry in our multi-cdn solution for a domain name. E.g.: example.c.s73cdn.net
origin The url that contains files that will be pulled & cached by CDN’s. E.g. http://o.example.com
domain name The url which you can use to pull your files through the multi-cdn solution. E.g. http://cdn.example.com
flush API representation of a flush/purge request to connected CDN providers to clear cache for an object
purge See flush
invalidation See flush

Formatting

API formatting can be manipulated through the format query parameter.

Our API supports multiple formatting types:

Parameter Value Default Description
format json true Response will be in JSON format
format api false Response will be in HTML format
format xml false Response will be in XML format

Errors

System73 Multi-CDN uses conventional HTTP response codes to indicate success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that resulted from the provided information (e.g. a required parameter was missing), and codes in the 5xx range indicate an error with System73 Multi-CDN’s servers.

The System73 Multi-CDN API has the following error codes:

Error Code Meaning
400 - Bad Request Often missing a parameter
401 - Unauthorized No valid API key provided
403 - Forbidden The resource requested is unavailable for the API key provided
404 - Not Found The specified resource doesn’t exist
405 - Method Not Allowed Check the HTTP method
406 - Not Acceptable The requested format isn’t supported
500 - Internal Server Error We had a problem with our server
503 - Service Unavailable We’re temporarily offline for maintenance

Authentication

Authentication works by supplying a API token in the request header. You can obtain a token in the portal. If you’re logged in on our management portal, you can browse our API using a cookie session.

We recommend using an API token for authorisation by systems.

The key should be prefixed by the string literal “Token”, with whitespace separating the two strings.

import requests

API_TOKEN = 'YOUR_API_TOKEN'
API_BASE = 'https://my.s73cdn.net/api/v1/'
# WARNING!! Some endpoints use API v2. So, API_BASE would be: '/api/v2/'                                                                                                            
# Please, read the description of each endpoint carefully.
   
api = requests.session()
api.headers['Authorization'] = 'Token {0}'.format(API_TOKEN)

index = api.get(API_BASE).json()
print(index)
# That's easy!
curl -X GET -H 'Authorization: Token YOUR_API_TOKEN' \
    https://my.s73cdn.net/api/v1/

Make sure to replace YOUR_API_TOKEN with the token generated in the portal

Vhosts

This endpoint allows you to list, create and update information about vhosts.

LIST

""" Assuming we keep our api and api_base
variables from the authentication example: """

url = API_BASE + 'vhosts/'
vhosts = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/vhosts/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

[ 
    {
      "id": 1,
      "name" : "example",
      "domain_name" : "example.c.s73cdn.net",
      "origin_shield": false,
      "origin_url" : "https://o.example.com",
      "properties" : [
        { 
          "id": 11,
          "cname" : "example.c.s73cdn.net",
          "ttl" : 3600,
          "gzip" : true,
          "querystring": true,
          "ssl" : true,
          "override_hostheader" : false,
          "host_header" : "",
          "content_protection": false,
          "cors": false
        }
      ],
      "aliases": [],
      "profile" : { 
        "id" : 2,
        "name" : "Standard"
      },
      "url" : "https://my.s73cdn.net/api/v1/vhosts/1/",
      "product": "singlecdn",
      "frontend_locked": false
    }
]

Returns a list of with vhost data objects.

GET https://my.s73cdn.net/api/v1/vhosts/

GET

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

vhost_id = 1
url = API_BASE + 'vhost/' + vhost_id + '/'
vhost = api.get(url).json()
# With shell, you can just pass the token in a header with each request
curl "https://my.s73cdn.net/api/v1/vhosts/1/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

{
  "id": 1,
  "name" : "example",
  "domain_name" : "example.c.s73cdn.net",
  "origin_shield": false,
  "origin_url" : "https://o.example.com",
  "properties" : [
    { 
      "id": 11,
      "cname" : "example.c.s73cdn.net",
      "ttl" : 3600,
      "gzip" : true,
      "querystring": true,
      "ssl" : true,
      "override_hostheader" : false,
      "host_header" : "",
      "content_protection": false,
      "cors": false
    }
  ],
  "aliases": [],
  "profile" : { 
    "id" : 2,
    "name" : "Standard"
  },
  "url" : "https://my.s73cdn.net/api/v1/vhosts/1/",
  "product": "singlecdn",
  "frontend_locked": false
}

Returns a single vhost object.

GET https://my.s73cdn.net/api/v1/vhosts/1/

POST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

import json

url = API_BASE + 'vhosts/'
data = {
    'domain_name': 'another.example.com',
    'origin_url': 'http://o.example.com/',
    'monitor_url': '/favicon.ico',
    'name': 'another'
}
headers = {
    'Content-Type': 'application/json'
}

new_vhost = api.post(url, data=json.dumps(data), headers=headers).json()
curl -X POST "https://my.s73cdn.net/api/v1/vhosts/" \                                                                                                                
  -H "Authorization: Token YOUR_API_TOKEN" \                                                                                                                                        
  -H "Content-Type: application/json" \                                                                                                                                              
  -d '{"domain_name": "another.example.com", "origin_url": "http://o.example.com", "monitor_url": "/favicon.ico", "name": "another"}'    

Example response:

{
  "id": 1,
  "name" : "example",
  "domain_name" : "example.c.s73cdn.net",
  "origin_shield": false,
  "origin_url" : "https://o.example.com",
  "properties" : [
    { 
      "id": 11,
      "cname" : "example.c.s73cdn.net",
      "ttl" : 3600,
      "gzip" : true,
      "querystring": true,
      "ssl" : true,
      "override_hostheader" : false,
      "host_header" : "",
      "content_protection": false,
      "cors": false
    }
  ],
  "aliases": [],
  "profile" : { 
    "id" : 2,
    "name" : "Standard"
  },
  "url" : "https://my.s73cdn.net/api/v1/vhosts/1/",
  "product": "singlecdn",
  "cdn_selection": [
    "CDN_1",
    "CDN_2"
  ],
  "frontend_locked": false
}

This method allows you to create vhosts.

POST https://my.s73cdn.net/api/v1/vhosts/

Post Parameters

Parameter Required Description
domain_name false Alias / domain name the vhost will use. This is the hostname the user would browse to to retrieve files
name true Nice name by which user can identify the vhost (no functional purpose)
origin_url true URL that references the origin. Where the CDN will get the content fromContains protocol, domain name (fqdn), port (optional) and the full path
monitor_url false A path relative to the origin that we can test to know the state of the cdns in your mix
product false defaults to singlecdn, can be either multicdn or singlecdn

VhostProperties

LIST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

url = API_BASE + 'vhostproperties/'
vhost_properties = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/vhostproperties/" \
  -H "Authorization: Token YOUR_API_TOKEN" \

Example response:

[
    {
        "id": 1,
        "cname": "example.c.s73cdn.net",
        "ttl": 300,
        "gzip": false,
        "querystring": false,
        "ssl": false,
        "override_hostheader": false,
        "host_header": "",
        "origin_shield": false,
        "content_protection": false,
        "cors": false
    },
    {
        "id": 2,
        "cname": "api.c.s73cdn.net",
        "ttl": 300,
        "gzip": true,
        "querystring": true,
        "ssl": false,
        "override_hostheader": false,
        "host_header": "",
        "origin_shield": false,
        "content_protection": false,
        "cors": false
    }
]

List of all vhost property objects.

GET https://my.s73cdn.net/api/v1/vhostproperties/

GET

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

vhost_property_id = 1
url = API_BASE + 'vhostproperties/' + vhost_property_id + '/'
vhost_property = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/vhostproperties/1/" \
  -H "Authorization: Token YOUR_API_TOKEN" 

Example response:

{
    "id": 1,
    "cname": "example.c.s73cdn.net",
    "ttl": 300,
    "gzip": true,
    "querystring": true,
    "ssl": false,
    "override_hostheader": false,
    "host_header": "",
    "origin_shield": false,
    "content_protection": false,
    "cors": false
}

Show vhost property object for vhost id id.

GET https://my.s73cdn.net/api/v1/vhostproperties/ id /

PATCH

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

vhost_property_id = 1
data = {
    'ttl': '300',
    'gzip': True
}
headers = {
    'Content-Type': 'application/json'
}
url = API_BASE + 'vhostproperties/' + vhost_property_id + '/'

vhost_property = api.patch(url, data=data, headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X PATCH "https://my.s73cdn.net/api/v1/vhostproperties/1/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \                                                                                                                                              
  -d '{"ttl": "300", "gzip": true}'

Example response:

{
    "id": 1,
    "cname": "example.c.s73cdn.net",
    "ttl": 300,
    "gzip": true,
    "querystring": true,
    "ssl": false,
    "override_hostheader": false,
    "host_header": "",
    "origin_shield": false,
    "content_protection": false,
    "cors": false
}

This method allows you to update vhosts properties.

PATCH https://my.s73cdn.net/api/v1/vhostproperty/ id /

Data

Parameter Required Read only Description
cname false x The hostname to which you link your domain e.g. foo.c.s73cdn.net
gzip false Boolean. If enabled, the CDNs will be set to compress objects
querystring false When enabled the CDN will use the query string as part of the cache key
ssl false Indicates whether a vhost is also available on SSL
secure content false Secure your content with access tokens, only a limited amount of cdn’s support this feature
large_files false Optimises CDN selection for the delivery of files larger than 100kb
override_hostheader false By default the Host header used to retrieve objects from origin is the origin hostname. Set to TRUE to use the name of the vhost in requests to origin
host_header false Allows you to specify the Host header to be used in requests to origin

VhostAlias

LIST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

url = API_BASE + 'vhostalias/'
aliases = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/vhostalias/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

[
  {
    "name": "my.newdomain.com",
    "vhost": 1
  }
]

Returns all vhost alias.

GET https://my.s73cdn.net/api/v1/vhostalias/

POST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

import json

data = {
    'name': "my.newdomain.com",
    'vhost': 1
}
headers = {
    'Content-Type': 'application/json'
}
url = API_BASE + 'vhostalias/'

new_alias = api.post(url, data=json.dumps(data), headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X POST "https://my.s73cdn.net/api/v1/vhostalias/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \                               
  -d '{"name": "my.newdomain.com", "vhost": 1}'

Example response:

{
  "name": "my.newdomain.com",
  "vhost": 1
}

Create a new vhost alias for the vhost id.

POST https://my.s73cdn.net/api/v1/vhostalias/

Post Parameters

Parameter Required Description
name true Name of the new alias
vhost true Vhost id in which we want to create a new alias

VhostProfiles

LIST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

url = API_BASE + 'vhostprofiles/'
vhost_profiles = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/vhostprofiles/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

[
  {
    "profile": 3,
    "vhost": "my_vhost_name"
  }
]

Returns all vhosts profiles.

GET https://my.s73cdn.net/api/v1/vhostprofiles/

POST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

import json

data = {
    'profile': 4,
    'vhost': "my_vhost_name"
}
headers = {
    'Content-Type': 'application/json'
}
url = API_BASE + 'vhostprofiles/'

new_profile = api.post(url, data=json.dumps(data), headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X POST "https://my.s73cdn.net/api/v1/vhostprofiles/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \                               
  -d '{"profile": 4, "vhost": "my_vhost_name"}'

Example response:

{
  "profile": 4,
  "vhost": "my_vhost_name"
}

Update the current vhost profile.

POST https://my.s73cdn.net/api/v1/vhostprofiles/

Post Parameters

Parameter Required Description
profile true Profile identifier
vhost true Vhost name

Profiles

LIST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

url = API_BASE + 'profiles/'
profiles = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/profiles/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

[
  {
    "id": 1,
    "name": "Standard"
  }
]

Returns all profiles.

GET https://my.s73cdn.net/api/v1/profiles/

Flush

With this endpoint you can create a request to flush / purge / invalidate an object from all connected cdn’s.

Property Value
Domain name cdn.example.com
Origin url http://o.example.com
Label example
Cname example.c.s73cdn.net

Will let you flush on the domain name http://cdn.example.com/

LIST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

url = API_BASE + 'flush/'
flushes = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/flush/" \
  -H "Authorization: Token YOUR_API_TOKEN" 

Example response:

{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 2,
      "flushes": [
        2
      ],
      "urls": [
        "http://cdn.example.com/selfie.jpg",
        "http://cdn.example.com/team_photo.jpg"
      ],
      "owner": 1
    },
    {
      "id": 1,
      "flushes": [
        1
      ],
      "urls": [
        "http://cdn.example.com/selfie.jpg"
      ],
      "owner": 1
    }
  ]
}

List of all flushes from your organization.

GET https://my.s73cdn.net/api/v1/flush/

GET

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

flush_id = 1
url = API_BASE + 'flush/' + flush_id + '/'
flush = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/flush/1/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

{
  "id": 1,
  "flushes": [
    1
  ],
  "urls": [
    "http://example.c.s73cdn.net/api.txt"
  ],
  "owner": 1
}

Returns a single flush object.

GET https://my.s73cdn.net/api/v1/flush/ id /

POST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

import json

data = {
    'urls': ["http://example.c.s73cdn.net/test.txt"]
}
headers = {
    'Content-Type': 'application/json'
}
url = API_BASE + 'flush/'

new_flush = api.post(url, data=json.dumps(data), headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X POST "https://my.s73cdn.net/api/v1/flush/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \                               
  -d '{"urls": ["http://example.c.s73cdn.net/test.txt"]}'

Example response:

{
  "id": 1,
  "flushes": [
    1
  ],
  "urls": [
    "http://example.c.s73cdn.net/api.txt"
  ],
  "owner": 1
}

This method allows you to create a flush request.

POST https://my.s73cdn.net/api/v1/flush/

Post Parameters

Parameter Required Description
urls true The URL of the object you want to flush

FlushAll

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

import json

data = {
    'urls': [
        "http://example.c.s73cdn.net"
    ]
}
headers = {
    'Content-Type': 'application/json'
}
url = API_BASE + 'flushall/'

flushes = api.post(url, data=json.dumps(data), headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X POST "my.s73cdn.net/api/v1/flushall/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \ 
  -d '{"urls": ["example.c.s73cdn.net"]}'

Example response:

{
  "id": 1,
  "flushes": [
    1
  ],
  "urls": [
    "http://example.c.s73cdn.net"
  ],
  "owner": 1
}

To flush all objects on all enabled cdns you can call the /flushall/ endpoint.

POST https://my.s73cdn.net/api/v1/flushall/

Flushstatus

Use this to retrieve the status of your flushes.

LIST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

url = API_BASE + 'flushstatus/'
flush_statuses = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/flushstatus/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

[
  {
    "url": "https://my.s73cdn.net/api/v1/flush/2/",
    "id": "https://my.s73cdn.net/api/v1/flushstatus/2/",
    "flushrequest": 2,
    "error": "one or more cdns have failed to flush",
    "result": {
      "ready": true,
      "total": 2,
      "done": 2,
      "results": [
        [
          "CDN Provider",
          "flushed"
        ],
        [
          "CDN Provider 2",
          "flushed"
        ]
      ]
    },
    "state": "failed",
    "filenames": "[u'/test.txt', '/api.txt']",
    "created": "2015-07-13T08:49:03Z",
    "updated": "2015-07-13T08:49:04Z",
    "vhost": "https://my.s73cdn.net/api/v1/vhosts/1/"
  },
  {
    "url": "https://my.s73cdn.net/api/v1/flush/1/",
    "id": "https://my.s73cdn.net/api/v1/flushstatus/1/",
    "flushrequest": 1,
    "error": "",
    "result": {
      "ready": true,
      "total": 1,
      "done": 2,
      "results": [
        [
          "CDN Provider",
          "flushed"
        ],
        [
          "CDN Provider 2",
          "flushed"
        ]
      ]
    },
    "state": "finished",
    "filenames": "[u'/test.txt']",
    "created": "2015-07-13T08:50:45Z",
    "updated": "2015-07-13T08:50:46Z",
    "vhost": "https://my.s73cdn.net/api/v1/vhosts/1/"
  }
]

Retrieves a list of status/details for a flush request.

GET https://my.s73cdn.net/api/v1/flushstatus/

GET

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

flush_request_id = 2
url = API_BASE + 'flushstatus/' + flush_request_id + '/'
flush_status = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/flushstatus/2/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

{
  "url": "https://my.s73cdn.net/api/v1/flush/2/",
  "id": "https://my.s73cdn.net/api/v1/flushstatus/2/",
  "flushrequest": 2,
  "error": "one or more cdns have failed to flush",
  "result": {
    "ready": true,
    "total": 2,
    "done": 2,
    "results": [
      [
        "CDN Provider",
        "flushed"
      ],
      [
        "CDN Provider 2",
        "flushed"
      ]
    ]
  },
  "state": "failed",
  "filenames": "[u'/test.txt', '/api.txt']",
  "created": "2015-07-13T08:49:03Z",
  "updated": "2015-07-13T08:49:04Z",
  "vhost": "https://my.s73cdn.net/api/v1/vhosts/1/"
}

Retrieves a single status/detail report for a flush request.

GET https://my.s73cdn.net/api/v1/flushstatus/ id /

Traffic

Get information on traffic usage.

LIST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

url = API_BASE + 'traffic/'
traffic = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/traffic/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

[
    {
        "detail": "https://my.s73cdn.net/api/v1/traffic/1/",
        "traffic_text": "68.76 GB",
        "vhost": "https://my.s73cdn.net/api/v1/vhosts/1/",
        "range": {
          "start_date": "2020-04-01",
          "end_date": "2020-04-30"
        },
        "traffic": {
          "amount": 68.76,
          "quantity": "gb"
        }
    }, 
    {
        "detail": "https://my.s73cdn.net/api/v1/traffic/2/",
        "traffic_text": "0.00 B",
        "vhost": "https://my.s73cdn.net/api/v1/vhosts/2/",
        "range": {
          "start_date": "2020-04-01",
          "end_date": "2020-04-30"
        },
        "traffic": {
          "amount": 0,
          "quantity": "gb"
        }
    }
]

Lists all usage for all vhosts.

GET https://my.s73cdn.net/api/v1/traffic/

GET

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

vhost_id = 1 
url = API_BASE + 'traffic/' + vhost_id + '/'
traffic = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/traffic/1/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response:

{
    "detail": "https://my.s73cdn.net/api/v1/traffic/1/",
    "traffic_text": "68.76 GB",
    "vhost": "https://my.s73cdn.net/api/v1/vhosts/1/",
    "range": {
      "start_date": "2020-04-01",
      "end_date": "2020-04-30"
    },
    "traffic": {
      "amount": 68.76,
      "quantity": "gb"
    }
}

Retrieve usage for one vhost.

GET https://my.s73cdn.net/api/v1/traffic/ id /

Query Parameters

Parameter Required Default Description
start_date false First day of the current month Start date for fetching traffic usage. Format: dd-mm-yyyy
end_date false Today End date for fetching traffic usage. Format: dd-mm-yyyy

Certificates

TLS certificate and key can be provided to secure your vhosts.

GET

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

url = API_BASE + 'certificates/'
certificates = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/certificates/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response

[
    {
        "serial": "4",
        "fingerprint": "f9d7282557dc3af01b7624271dde7d3eeb3ed5b738364613f0fbeee784ab4ed0",
        "issuer": "C=NL,ST=Holland,L=Amsterdam,O=Warpcache,CN=Warpcache RSA Dummy CA",
        "subject": "OU=Domain Control Validated,OU=DummySSL,CN=cdn.example.com",
        "not_before": "2019-04-12T00:00:00Z",
        "not_after": "2021-04-12T23:59:59Z",
        "domains": [
            "*.cdn.example.com",
            "vod.example.com",
            "assets.example.com"
        ]
    }
]

List all your certificates.

GET https://my.s73cdn.net/api/v1/certificates/

POST

""" Assuming we keep our api and API_BASE
variables from the authentication example: """
import json

data = {
        'certificate': '''-----BEGIN CERTIFICATE-----
.. DUMMY ..
------END CERTIFICATE------''',
        'private_key': '''-----BEGIN PRIVATE KEY------
.. DUMMY ..
------END PRIVATE KET------'''
}
headers = {
    'Content-Type': 'application/json'
}
url = API_BASE + 'certificates/'

new_certificate = api.post(url, data=json.dumps(data), headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X POST "my.s73cdn.net/api/v1/certificates/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \ 
  -d '{"certificate": "", "private_key": ""}'

Example response

{
}

Upload a certificate.

POST https://my.s73cdn.net/api/v1/certificates/

Post Parameters

Parameter Required Description
certificate true PEM encoded certificate
private_key true PEM encoded private key

UpgradeProduct

""" Assuming we keep our api and API_BASE (using v2)
variables from the authentication example: """

import json

API_BASE = "https://my.s73cdn.net/api/v2/"

url = API_BASE + 'vhosts/' + vhost_id + '/upgrade-product/'
data = {
   "add_default_cdns": True,
}
headers = {
    'Content-Type': 'application/json'
}

vhost = api.post(url, data=json.dumps(data), headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X POST "/api/v2/vhosts/1/upgrade-product/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"add_default_cdns": true}'

Example response:

{
  "id": 1,
  "name" : "example",
  "domain_name" : "example.c.s73cdn.net",
  "origin_shield": false,
  "origin_url" : "https://o.example.com",
  "properties" : [
    { 
      "id": 11,
      "cname" : "example.c.s73cdn.net",
      "ttl" : 3600,
      "gzip" : true,
      "querystring": true,
      "ssl" : true,
      "override_hostheader" : false,
      "host_header" : "",
      "content_protection": false,
      "cors": false
    }
  ],
  "aliases": [],
  "profile" : { 
    "id" : 2,
    "name" : "Standard"
  },
  "url" : "https://my.s73cdn.net/api/v2/vhosts/1/",
  "product": "multicdn",
  "frontend_locked": false
}

Upgrade the vhost product from SingleCDN to MultiCDN.

POST https://my.s73cdn.net/api/v2/vhosts/ vhost_id /upgrade-product/

The body request accepts only one field: add_default_cdns. It’s a boolean field. If it is set to True, your default CDNs will be activated (keeping the CDN in use). If it is set to False (or you don’t send the body in the POST request), your product will be update to MultiCDN and continue to use your current CDN.

Post Parameters

Parameter Required Description
add_default_cdns false If False, you will only upgrade your product. If True, you will deploy your default CDNs.

DowngradeProduct

GET

List the available CDNs to downgrade for a Vhost:

""" Assuming we keep our api and API_BASE (using v2)
variables from the authentication example: """

import json

API_BASE = "https://my.s73cdn.net/api/v2/"

url = API_BASE + 'vhosts/' + vhost_id + '/downgrade-product/'
headers = {
    'Content-Type': 'application/json'
}

vhost = api.get(url, headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X GET "/api/v2/vhosts/1/downgrade-product/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json"

GET https://my.s73cdn.net/api/v2/vhosts/ vhost_id /downgrade-product/

Example response:

["HighWinds", "AkamaiApi", "EdgeCast"]

POST

Downgrade the vhost product from MultiCDN to SingleCDN.

""" Assuming we keep our api and API_BASE (using v2)
variables from the authentication example: """

import json

API_BASE = "https://my.s73cdn.net/api/v2/"

url = API_BASE + 'vhosts/' + vhost_id + '/downgrade-product/'
data = {
   "cdn": "HighWinds",
}
headers = {
    'Content-Type': 'application/json'
}

vhost = api.post(url, data=json.dumps(data), headers=headers).json()
# With shell, you can just pass the correct header with each request
curl -X POST "/api/v2/vhosts/1/downgrade-product/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cdn": "HighWinds"}'

Example response:

{
  "id": 1,
  "name" : "example",
  "domain_name" : "example.c.s73cdn.net",
  "origin_shield": false,
  "origin_url" : "https://o.example.com",
  "properties" : [
    { 
      "id": 11,
      "cname" : "example.c.s73cdn.net",
      "ttl" : 3600,
      "gzip" : true,
      "querystring": true,
      "ssl" : true,
      "override_hostheader" : false,
      "host_header" : "",
      "content_protection": false,
      "cors": false
    }
  ],
  "aliases": [],
  "profile" : {
    "id" : 2,
    "name" : "Standard"
  },
  "url" : "https://my.s73cdn.net/api/v2/vhosts/1/",
  "product": "singlecdn",
  "frontend_locked": false
}

POST https://my.s73cdn.net/api/v2/vhosts/ vhost_id /downgrade-product/

The body request accepts only one field: cdn. It’s a string value containing the name of your desired primary CDN after downgrade. If the CDN is not supported for your vhost will return 400 Use the list from GET endpoint to know the supported CDNs to downgrade.

Post Parameters

Parameter Required Description
cdn true Set primary CDN for downgrade. Use the GET method to know the list of available CDNs.

Stats

HitMiss

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

vhost_id = 1
url = API_BASE + 'reports/hitmiss/' + vhost_id + '/'
report = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/reports/hitmiss/1/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response

{
  "dates": [
     {
        "date": "2020-01-01",
        "request": {
              "hit": 100,
              "miss": 2
        },
        "providers": {
              "CDN_1": {
                    "hit": 75,
                    "miss": 1
              },
              "CDN_2": {
                    "hit": 25,
                    "miss": 1
              }
        }
     },

     ...

  ],
  "range": {
    "start_date": "2020-01-01",
    "end_date": "2020-01-31"
  },
  "requests": {
    "hits": 8129174949,
    "miss": 240141266
  },
  "vhost": "https://my.s73cdn.net/api/v1/vhosts/1/"
}

Get all hit-miss stats from a particular vhost per CDN in a range of dates. If the date range is not provided, the default range is the current month.

GET https://my.s73cdn.net/api/v1/reports/hitmiss/ id /

Get Parameters

Parameter Required Description
start_date false First day of the date range (%Y-%m-%d)
end_date false Last day of the date range (%Y-%m-%d)

StatusCodes

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

vhost_id = 1
url = API_BASE + 'reports/status_codes/' + vhost_id + '/'
report = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/reports/status_codes/1/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response

{
  "query": {
    "range": {
      "start_date": "2020-01-01",
      "end_date": "2020-01-31"
    }
  },
  "datetime": {
    "2020-01-01": {
         "CDN_1": {
               "breakdown": {
                   "200": 100,
                   "204": 8,           
                   "304": 3,
                   "404": 43
               },
               "grouped": {
                   "2xx": 108,
                   "3xx": 3,
                   "4xx": 43
              }
         }
    },
     
    ...

  },
  "vhost": "https://my.s73cdn.net/api/v1/vhosts/1/"
}

Get all status codes stats from a particular vhost per CDN in a range of dates. If the date range is not provided, the default range is the current month.

GET https://my.s73cdn.net/api/v1/reports/status_codes/ id /

Get Parameters

Parameter Required Description
start_date false First day of the date range (%Y-%m-%d)
end_date false Last day of the date range (%Y-%m-%d)
granularity false Level of detail of the report (e.g.: “1h”, “1d”). Default granularity, one day

Locations (Countries)

""" Assuming we keep our api and API_BASE
variables from the authentication example: """

vhost_id = 1
url = API_BASE + 'reports/countries/' + vhost_id + '/'
report = api.get(url).json()
# With shell, you can just pass the correct header with each request
curl "https://my.s73cdn.net/api/v1/reports/countries/1/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Example response

{
  "query": {
    "range": {
      "start_date": "2020-01-01",
      "end_date": "2020-01-31"
    }
  },
  "datetime": {
    "2020-01-01": {
         "CDN_1": {
              "requests": {
                    "AE": 4474,
                    "GB": 11,
                    "US": 11
               },
               "bytes": {
                    "AE": 25568002.24,
                    "GB": 11743.87,
                    "US": 7027.79
               }
         }
    },
     
    ...

  },
  "vhost": "https://my.s73cdn.net/api/v1/vhosts/1/"
}

Get all countries stats (number of requests and bytes sent) from a particular vhost in a range of dates. If the param aggregateResults is False or it is not present, the results are also aggregated by CDN. If the date range is not provided, the default range is the current month.

GET https://my.s73cdn.net/api/v1/reports/countries/ id /

Get Parameters

Parameter Required Description
start_date false First day of the date range (%Y-%m-%d)
end_date false Last day of the date range (%Y-%m-%d)
aggregateResults false If false, the stats are aggregated per CDN, if not, they are aggregated only by country
granularity false Level of detail of the report (e.g.: “1h”, “1d”). Default granularity, one day