.wpb_animate_when_almost_visible { opacity: 1; }

Content Delivery Boost

Use Orange's global IP network and CDN to exceed standards. Access metrics via APIs.

API deprecated Contact us

Table of Contents

Introduction

Two main APIs are provided for the Orange Wholesale CDN service :

  1. CDN Metrics: this API provides metrics about your cdn service such as delivery throughput, delivery volume, ingest volume, hit ratio, errors code count...

  2. CDN Configurations: This API provides several endpoints to get, create or modify your CDN service configurations. AT present time, this API provide 2 endpoints:

    • Resources: to retrieve the list of resources.
    • Purges: to send a purge content order for a specific resource or for all.

Authentication prerequisite

Access to this API is secured by the OAuth 2.0 framework with the Client Credentials grant type, which means that you will have to present an OAuth 2.0 access_token whenever you want to request this API.

It's easy to negotiate this access_token: just send a request to the proper token negotiation endpoint, with a Basic Authentication header valued with your own client_id and client_secret.

For this API, the token negotiation endpoint is:

https://api.orange.com/oauth/v3/token

A technical guide is available to learn how to negotiate and manage these access_token.

SDK to manage token lifecycle could help you to implement cache token.

Base URL

The Base URL is the first part of the full invocation URL, just before the resource paths defined in the API reference.

The Base URL is comprised of the scheme ('https'), the authority (i.e. the Fully Qualified Domain Name) and the API base path.

Whenever you request this API and encounter a 404 NOT FOUND HTTP error response, please check first that the Base URL is correct.

The Base URL for this API is:

https://api.orange.com/intl-cdn/v2/

The documentation below assumes that, whenever you make requests on this API, you are prepending the Base URL to the resource paths defined for this API.

Prerequisites to use the APIs

The two provided APIs are specific to an organization (i.e. a client). So, an organizationId will be provided to you during the exchanges with PreSales/Sales teams.

So, you will be only able to use this APIs if:

  • the organizationId (RCE code) have been provided to you
  • you have subscribed to the APIs and your applicationId have been associated to your organization.

Resources

API Metrics

The API Metrics is organized around 2 main endpoints corresponding to the 2 main functional domain of a CDN:

  • Delivery: the associated endpoint will provide you with metrics about the delivery of contents by the CDN to end users of the service.
  • Ingest: the associated endpoint will provide you with metrics about the ingest of contents from your Origin Server(s) by the CDN to end users of the service.

CDN domains

Delivery

This resource will provide you with several information about delivery of your contents through the Orange Wholesale CDN, such as:

  • bytes (delivered)
  • offloadRatio
  • cacheHitBytes- ...

Detailed information about all metrics provided by this API: check the API reference

Some filters are available and can be used to have more accurate informations :

  • startTime
  • endTime
  • interval
  • countries
  • resourceIds

Usage example

The story: As a client I want to have the delivery metrics for my resource stream.mycompagny.com for the country France for the last week for each days.

The steps:

  1. Request the API Configurations to get the list of your resources (optional and if not known by your client backend): /organizations/{organizationId}/configurations/services/cdn/resources
  2. Prepare the request to /metrics/media/delivery with the following parameters:
    • startTime="2023-11-15T00:00:00.000Z"
    • endTime="2023-11-22T23:59:59.999Z"
    • interval=86400
    • countries="FR"
    • resourceIds="stream.mycompagny.com"
  3. Do the GET request: GET https://api.orange.com/intl-cdn/v2/organizations/{organizationId}/metrics/media/delivery?interval=86400&countries=FR&resourceIds=stream.mycompagny.com&startTime=2023-11-15T00:00:00.000Z&endTime=2023-11-22T23:59:59.999Z

The sequence can be sum up as into this diagram

enter image description here

Step 1: Request
curl --location 'https://api.orange.com/intl-cdn/v2/organizations/{organizationId}/configurations/services/cdn/resources'
--header 'Accept: application/json;charset=utf-8'
--header 'Authorization: Bearer eyJ2ZXIiOiIx[...]'
Response

Headers

HTTP/1.1 200 OK
Content-Type: application/json
X-Total-Count: 2
X-Result-Count: 2

Body

[
    {
        "resourceId": "static.mycompgagny.com",
        "description": "New domain for test",
        "type": "light",
        "status": "active",
        "enabled": true
    },
    {
        "resourceId": "stream.mycompagny.com",
        "description": "",
        "type": "light",
        "status": "active",
        "enabled": true
    }
]
Step 3: Request
curl --location 'https://api.orange.com/intl-cdn/v2/organizations/{organizationId}/metrics/media/delivery?interval=86400&countries=FR&resourceIds=stream.mycompagny.com&startTime=2023-11-15T00%3A00%3A00.000Z&endTime=2023-11-22T23%3A59%3A59.999Z'
--header 'Accept: application/json;charset=utf-8'
--header 'Authorization: Bearer eyJ2ZXIiOiIx[...]'
Response

Headers

HTTP/1.1 200 OK

Body

{
    "organizationId": "xxxxxxxxxx",
    "metrics": [
        {
            "resourceId": "stream.mycompagny.com",
            "data": [
                {
                    "country": "FR",
                    "values": [
                        {
                            "timestamp": "2023-11-15T00:00:00Z",
                            "dataRecord": {
                                "offloadRatio": 0.0,
                                "throughput": 0.0,
                                "bytes": 0,
                                "cacheHitBytes": 0,
                                "uniqueVisitors": null,
                                "httpCodes": [
                                    {
                                        "statusCode": "2xx",
                                        "count": 0
                                    },
                                    {
                                        "statusCode": "3xx",
                                        "count": 0
                                    },
                                    {
                                        "statusCode": "4xx",
                                        "count": 0
                                    },
                                    {
                                        "statusCode": "5xx",
                                        "count": 0
                                    }
                                ],
                                "responseStartTime": null,
                                "responseTime": null
                            }
                        },
                        {
                            "timestamp": "2023-11-16T00:00:00Z",
                            "dataRecord": {
                                "offloadRatio": 0.013952502273574918,
                                "throughput": 179.49787037037038,
                                "bytes": 1938577,
                                "cacheHitBytes": 27048,
                                "uniqueVisitors": null,
                                "httpCodes": [
                                    {
                                        "statusCode": "2xx",
                                        "count": 46
                                    },
                                    {
                                        "statusCode": "3xx",
                                        "count": 14
                                    },
                                    {
                                        "statusCode": "4xx",
                                        "count": 37
                                    },
                                    {
                                        "statusCode": "5xx",
                                        "count": 0
                                    }
                                ],
                                "responseStartTime": null,
                                "responseTime": null
                            }
                        },
...]

You received several informations.

To use them to generate a webui graphic for ex, you will have to use the informations under "values" which contains information by timestamp. The step of the timestamps corresponds of the interval requested.

Important remarks:

  • If you use a too small interval for a wide time range:

    • The processing of the request, so the answer, will be long
    • The maximum allowed size of a HTTP message could be reach then a HTTP error will be raised by Orange Developer.
  • the field uniqueVisitors is deprecated and the value will be null all the time. It is conserved in this version for retrocompatibility purpose.

Detailed information about all metrics provided by this API: check the API reference

Ingest

This resource, as the Delivery resource, will provide you with information about the ingest metrics of your contents from your(s) origin server(s) by the Orange Wholesale CDN, such as:

  • bytes (ingested)
  • HTTP error status code
  • ...

To use this endpoint, follow the same process than for the delivery resource but request the ingest resource.

Usage example

The story: As a client I want to have the ingest metrics for my resource stream.mycompagny.com for the country France for the last week for each days.

The steps:

  1. Request the API Configurations to get the list of resources (optional and if not known by the client backend): /organizations/{organizationId}/configurations/services/cdn/resources
  2. Prepare the request to /metrics/media/ingest with the following parameters:
    • startTime="2023-11-15T00:00:00.000Z"
    • endTime="2023-11-22T23:59:59.999Z"
    • interval=86400
    • countries="FR"
    • resourceIds="stream.mycompagny.com"
  3. Do the HTTP GET request: GET https://api.orange.com/intl-cdn/v2/organizations/{organizationId}/metrics/media/ingest?interval=86400&countries=FR&resourceIds=stream.mycompagny.com&startTime=2023-11-15T00:00:00.000Z&endTime=2023-11-22T23:59:59.999Z

API Configurations

This API will provide you with different resources to create,get,update,delete the configuration(s) parameters of your CDN service resources or to launch some actions. At present time, only the creation of purge orders is possible in this version of the API. A purge order permits you to purge some contents from the Orange Wholesale CDN.

A purge order can:

  • be immediate or scheduled
  • concern a specific resource, a list of resources or all resources of your CDN service into the Orange Wholesale CDN.
  • concern a specific content, all contents, a type of content (ex: all jpeg files)....

Detailed information about all options provided by this API: check the API reference

Important: A purge could take 15 to 30 minutes to be effective depending of the number of contents to purge.

For scheduled purges, the supported format are:

Several cron format exist and depends of the operating system, librairies... hereafter some details of the format supported by this API

CRON Format

 * * * * * * *    Field              Allowed values    Special symbols
 | | | | | | |    -----------------  ---------------   ---------------
 `-|-|-|-|-|-|->  Second (optional)  0-59              * / , -
   `-|-|-|-|-|->  Minute             0-59              * / , -
     `-|-|-|-|->  Hour               0-23              * / , -
       `-|-|-|->  Day of Month       1-31              * / , - ? L W
         `-|-|->  Month              1-12 or JAN-DEC   * / , -
           `-|->  Day of Week        0-7 or SUN-SAT    * / , - ? L #
             `->  Year (optional)    1970-2099         * / , -

Details:

* : Asterisks indicate that the cron expression matches for all values of the field. For example, "*" in the minute field means every minute

? : Question marks are used to specify 'no specific value' and is allowed for the day-of-month and day-of-week fields. It is used instead of the asterisk (*) for leaving either day-of-month or day-of-week blank.

- : Hyphens are used to define ranges. For example, "10-12" in the hour field means the hours of 10, 11, and 12.

, : Commas are used to separate items of a list. For example, "MON,WED,FRI" in the day-of-week field means the days Monday, Wednesday, and Friday.

/ : Forward slash are used to indicate increments. For example. "0/15" in the seconds field means the seconds 0, 15, 30, and 45. Additionally, "1/3" in the day-of-month field means every 3 days starting on the first day of the month.

L : Short-hand for "last" and is allowed for the day-of-month and day-of-week fields. The "L" character has a different meaning in each of the two fields. For example, "L" in the day-of-month field means the last day of the month. If used in the day-of-week field, it means 7 or SAT. However, if used in the day-of-week field after another value, it means the last xxx day of the month. For example, "6L" in the day-of-week field means the last Friday of the month.

W : Short-hand for "weekday" and is allowed for the day-of-month field. The "W" character is used to specify the weekday nearest the given day. For example, "15W" in the day-of-month field means the nearest weekday to the 15th of the month. Therefore, if the 15th is a Saturday, the job runs on Friday the 14th. The "L" and "W" characters can be combined in the day-of-month field. For example, "LW" means the last weekday of the month.

# : Hash marks specify constructs. For example, "6#3' in the day-of-week field means the third Friday of the month.

Examples:

* * * * * * Every Second
0 * * * * * Every minute
0 */10 * * * * Every 10 minutes
0 */20 1 * * * Every 20 minutes, between 01:00 AM and 01:59 AM
0 15,30,45 * * * * At 15, 30, and 45 minutes past the hour
0 0 12 * * * Every day at noon - 12pm
0 0 2 29 FEB * 2020/4 At 02:00 AM, on day 29 of February (leap years)
0 0 7 * * MON#1 * At 07:00 AM, on the first Monday of the month
0 0 12 * JAN,FEB,MAR,APR * Every day at noon in January, February, March and April
* * 1W * * Every minute, on the first weekday of the month
0 12 * * MONL At 12:00 PM, on the last Monday of the month

You can use some online cron expression generator to prepare or verify your expressions:

Usage examples

1. Create a scheduled purge

The story: As a client I want to purge all contents of /images directory from my resource static.mycompagny.com at 2 AM everyday.

The steps:

  1. Prepare the Post request with the following body parameters :
{
    "paths": [
        "/images/*",
    ],
    "resourceIds": [
        "static.mycompagny.com "
    ],
    "scheduleExpression": "0 0 2 * * *"
}
  1. Add the correct headers: Content-Type: application/json
  2. Send the HTTP POST request: POST https://api.orange.com/intl-cdn/v2/organizations/{organizationId}/configurations/services/cdn/purges/schedules
Step 3: Request
curl --location 'https://api.orange.com/intl-cdn/v2/organizations/{organizationId}/configurations/services/cdn/purges/schedules'
--header 'Accept: application/json;charset=utf-8'
--header 'Content-Type: application/json'
--header 'Authorization: Bearer eyJ2ZXIiOiIx[...]'
--data '{
    "paths": [
        "/images/*"
    ],
    "resourceIds": [
        "static.mycompagny.com"
    ],
    "scheduleExpression": "0 0 2 * * *"
}'
Step 3: Response

Headers

HTTP/1.1 202 Accepted

Body

{
    "paths": [
        "/images/*"
    ],
    "resourceIds": [
        "static.mycompagny.com"
    ],
    "scheduleExpression": "0 0 2 * * *",
    "status": "created",
    "organizationId": "xxxxxxx",
    "scheduleCreationDate": "2023-11-26T17:17:52.487Z",
    "scheduleLastUpdate": "2023-11-26T17:17:52.487Z",
    "purgeId": "",
    "scheduleId": "NDnMCtz9KM"
}
2. Delete a scheduled purge

The story: As a client I want to delete a recurring scheduled purge on my resource static.mycompagny.com.

The steps:

  1. List my scheduled purge for this resource (optional).
  2. Identify the schedule you want to delete with the json response.
  3. Prepare the delete request
  4. Send the HTTP DELETE request.
Step 1: Request
curl --location 'https://api.orange.com/intl-cdn/v2/organizations/{organizationId}/configurations/services/cdn/purges/schedules'
--header 'Accept: application/json;charset=utf-8'
--header 'Authorization: Bearer eyJ2ZXIiOiIx[...]'
Step 1: Response

Headers

HTTP/1.1 200 OK

Body

[
    {
        "paths": [
            "/images/*",
            "/app/12JKHKJ.js",
            "*.png",
            "/sites/*/demo.gif"
        ],
        "resourceIds": [
            "static.mycompagny.com"
        ],
        "scheduleExpression": "2023-12-30T15:22:33.000Z",
        "status": "created",
        "scheduleCreationDate": "2023-11-16T16:59:34.950Z",
        "scheduleLastUpdate": "2023-11-16T16:59:34.950Z",
        "purgeId": "",
        "scheduleId": "rcTqqMzKrh"
    },
    {
        "paths": [
            "/images/*",
            "/app/12JKHKJ.js"
        ],
        "resourceIds": [],
        "scheduleExpression": "0 0 0 7,19 * *",
        "status": "created",
        "scheduleCreationDate": "2023-11-16T17:07:41.184Z",
        "scheduleLastUpdate": "2023-11-16T17:11:29.166Z",
        "purgeId": "",
        "scheduleId": "RGjw9kzNLL"
    },
    {
        "paths": [],
        "resourceIds": [
            "stream.mycompagny.com"
        ],
        "scheduleExpression": "0 0 11 20/5 * *",
        "status": "created",
        "scheduleCreationDate": "2023-11-20T11:04:37.284Z",
        "scheduleLastUpdate": "2023-11-20T11:04:37.284Z",
        "purgeId": "",
        "scheduleId": "BpWbDhjGKH"
    },
    {
        "paths": [],
        "resourceIds": [
            "stream.mycompagny.com",
            "static.mycompagny.com"
        ],
        "scheduleExpression": "0 27 15 * * MON",
        "status": "executed",
        "scheduleCreationDate": "2023-11-06T15:25:17.834Z",
        "scheduleLastUpdate": "2023-11-20T15:27:00.750Z",
        "purgeId": 115,
        "scheduleId": "ptRbLfwjJF"
    },
    {
        "paths": [
            "/images/*"
        ],
        "resourceIds": [
            "stream.mycompagny.com"
        ],
        "scheduleExpression": "0 0 2 * * *",
        "status": "created",
        "scheduleCreationDate": "2023-11-26T17:57:51.943Z",
        "scheduleLastUpdate": "2023-11-26T17:57:51.943Z",
        "purgeId": "",
        "scheduleId": "tMJTzmnc7G"
    }
]
Step 4: Request
curl --location --request DELETE 'https://api.orange.com/intl-cdn/v2/organizations/{organizationId}/configurations/services/cdn/purges/schedules/tMJTzmnc7G'
--header 'Accept: application/json;charset=utf-8'
--header 'Authorization: Bearer eyJ2ZXIiOiIx[...]'
Step 4: Response

Headers

HTTP/1.1 204 No Content

Errors

Important

Failure to code a proper management of the error responses in your application may affect its resilience. Access to the API may be revoked if your application generates too many mishandled errors.

Your application must parse the returned HTTP response to check if an error is returned instead of a 200 OK. Orange APIs use appropriate HTTP status codes to indicate any request processing error, providing detailed information about the underlying fault. This helps you provide better feedback to your users and implement failure recovery mechanisms in your application.

For details on the main error codes, response format, tips and troubleshooting, see our Handling API errors guide

Errors 401

If you get a status code 401 with the error code 42 (such as below), then request a new access token.

HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
  "code": 42,
  "message": "Expired credentials",
  "description": "The requested service needs credentials, and the ones provided 
  were out-of-date."
}

Important

  • Each access_token has a lifetime validity period. This validity period may change overtime to comply with security rules.
  • The token server has a maximum hourly quota per client application to prevent from misuse.
    Therefore,
    DON'T request an access_token each time you invoke the service API.
    DON'T hard-code a validity duration in your application.
    Instead, your application must parse the returned status code and error code to check if it needs to request a new access token.

For other 401 errors: check that you provide the right Autorization header with the right Bearer

Errors 400

In case of invalid request to the API, you will receive a 400 error code with detailed information in the body message, such as:

HTTP/1.1 400 Bad Request 
{
  "code": 25,
  "description": "Missing header",
  "message": "...."
}

Consult the other errors Consult all generic errors