.wpb_animate_when_almost_visible { opacity: 1; }

OAuth M2M in a nutshell

Published: October 7, 2024

Before you can use Orange APIs, there are various steps that are needed to get you started on the Orange Developer portal. These steps are described in: How to start with Orange Developer.

The OAuth M2M in a nutshell guide presents the OAuth 2.0 Machine-To-Machine authentication process in a simplified way. It dynamically provides various sample codes. The stepper below shows the various steps, which are clickable:

Step 1 - Before starting

At the end of the registration process (step 4 of the How to start with Orange Developer – Orange Developer), you are provided with a client_id,client_secret and the HTTP Authorization header. They are available in your client space MyApps > tab Credentials and are applicable to one application.

Be cautious to the following notions on Orange Developer:

  • only one client space can be associated with one email address
  • in this client space, you can have one or several applications
  • with one application are associated:
    • one or several APIs
    • only one set of credentials

The figure below illustrates the various calls and processes to obtain and use an access token:

OAuth 2.0 M2M interactions

OAuth2 2-legged Process

Caution to the URL you use to retrieve your token. For more information, refer to the Introduction to the OAuth 2.0 protocol, paragraph API URL endpoints.

Step 2 - Request the OAuth access token

The access token is mandatory for API calls to access protected resources. To get this token, a POST request must be sent to the token endpoint as in the following example:

Replace YourAuthorizationHeader by the authorization header provided in your MyApps client space.

curl -X POST \
-H "Authorization: Basic YourAuthorizationHeader" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d "grant_type=client_credentials" \
https://api.orange.com/oauth/v3/token

Example cURL

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.orange.com/oauth/v3/token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==',
    'Content-Type: application/x-www-form-urlencoded',
    'Accept: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
$response = curl_exec($ch);
curl_close($ch);

Example Guzzle

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client();

$response = $client->post('https://api.orange.com/oauth/v3/token', [
  'headers' => [
     'Authorization' => 'Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==',
     'Content-Type' => 'application/x-www-form-urlencoded',
     'Accept' => 'application/json'
  ],
  'form_params' => [
      'grant_type' => 'client_credentials'
  ]
]);
using System.Net.Http;

using System.Net.Http.Headers;

HttpClient client = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://api.orange.com/oauth/v3/token");

request.Headers.Add("Authorization", "Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==");

request.Headers.Add("Accept", "application/json");

request.Content = new StringContent("grant_type=client_credentials");

request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

HttpResponseMessage response = await client.SendAsync(request);

response.EnsureSuccessStatusCode();

string responseBody = await response.Content.ReadAsStringAsync();
import java.io.IOException
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request

val client = OkHttpClient()

val formBody = FormBody.Builder()
  .add("grant_type", "client_credentials")
  .build()

val request = Request.Builder()
  .url("https://api.orange.com/oauth/v3/token")
  .post(formBody)
  .header("Authorization", "Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==")
  .header("Content-Type", "application/x-www-form-urlencoded")
  .header("Accept", "application/json")
  .build()

client.newCall(request).execute().use { response ->
  if (!response.isSuccessful) throw IOException("Unexpected code $response")
  response.body!!.string()
}
extern crate reqwest;
use reqwest::header;

fn main() -> Result<(), Box<dyn std::error::Error>> {
  let mut headers = header::HeaderMap::new();
  headers.insert("Authorization", "Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==".parse().unwrap());
  headers.insert("Content-Type", "application/x-www-form-urlencoded".parse().unwrap());
  headers.insert("Accept", "application/json".parse().unwrap());

  let client = reqwest::blocking::Client::builder()
     .redirect(reqwest::redirect::Policy::none())
     .build()
     .unwrap();
  let res = client.post("https://api.orange.com/oauth/v3/token")
     .headers(headers)
     .body("grant_type=client_credentials")
     .send()?
     .text()?;
  println!("{}", res);

  Ok(())
}

Example fetch

fetch('https://api.orange.com/oauth/v3/token', {
  method: 'POST',
  headers: { 
     'Authorization': 'Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==',
     'Accept': 'application/json'
  },
  body: new URLSearchParams({
     'grant_type': 'client_credentials'
  })
});

Example jQuery

$.ajax({
  url: 'https://api.orange.com/oauth/v3/token',
  crossDomain: true,
  method: 'post',
  headers: {
     'Authorization': 'Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==',
     'Accept': 'application/json'
  },
  contentType: 'application/x-www-form-urlencoded',
  data: {
     'grant_type': 'client_credentials'
  }
}).done(function(response) {
  console.log(response);
});

Example XHR

const data = new URLSearchParams({
  'grant_type': 'client_credentials'
});
let xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open('POST', 'https://api.orange.com/oauth/v3/token');
xhr.setRequestHeader('Authorization', 'Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Accept', 'application/json');

xhr.onload = function() {
  console.log(xhr.response);
};

xhr.send(data);

Example HttpClient

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
  .uri(URI.create("https://api.orange.com/oauth/v3/token"))
  .POST(BodyPublishers.ofString("grant_type=client_credentials"))
  .setHeader("Authorization", "Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==")
  .setHeader("Content-Type", "application/x-www-form-urlencoded")
  .setHeader("Accept", "application/json")
  .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

Example HttpURLConnection

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {
  public static void main(String[] args) throws IOException {
     URL url = new URL("https://api.orange.com/oauth/v3/token");
     HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
     httpConn.setRequestMethod("POST");

     httpConn.setRequestProperty("Authorization", "Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==");
     httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
     httpConn.setRequestProperty("Accept", "application/json");

     httpConn.setDoOutput(true);
     OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
     writer.write("grant_type=client_credentials");
     writer.flush();
     writer.close();
     httpConn.getOutputStream().close();

     InputStream responseStream = httpConn.getResponseCode() / 100 == 2
        ? httpConn.getInputStream()
        : httpConn.getErrorStream();
     Scanner s = new Scanner(responseStream).useDelimiter("\\A");
     String response = s.hasNext() ? s.next() : "";
     System.out.println(response);
  }
}

Example jsop

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
  .uri(URI.create("https://api.orange.com/oauth/v3/token"))
  .POST(BodyPublishers.ofString("grant_type=client_credentials"))
  .setHeader("Authorization", "Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==")
  .setHeader("Content-Type", "application/x-www-form-urlencoded")
  .setHeader("Accept", "application/json")
  .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

Example okHttp

import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

OkHttpClient client = new OkHttpClient();

RequestBody formBody = new FormBody.Builder()
  .add("grant_type", "client_credentials")
  .build();

Request request = new Request.Builder()
  .url("https://api.orange.com/oauth/v3/token")
  .post(formBody)
  .header("Authorization", "Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==")
  .header("Content-Type", "application/x-www-form-urlencoded")
  .header("Accept", "application/json")
  .build();

try (Response response = client.newCall(request).execute()) {
  if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
  response.body().string();
}

Example node-fetch

import fetch from 'node-fetch';
fetch('https://api.orange.com/oauth/v3/token', {
  method: 'POST',
  headers: {
     'Authorization': 'Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==',
     'Accept': 'application/json'
  },
  body: new URLSearchParams({
     'grant_type': 'client_credentials'
  })
});

Example http

import https from 'https';
const options = {
  hostname: 'api.orange.com',
  path: '/oauth/v3/token',
  method: 'POST',
  headers: {
     'Authorization': 'Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==',
     'Content-Type': 'application/x-www-form-urlencoded',
     'Accept': 'application/json'
  }
};

const req = https.request(options, function (res) {
  const chunks = [];

  res.on('data', function (chunk) {
     chunks.push(chunk);
  });

  res.on('end', function () {
     const body = Buffer.concat(chunks);
     console.log(body.toString());
  });
});

req.write(new URLSearchParams({
  'grant_type': 'client_credentials'
  }).toString());
req.end();

Example requests

import requests

headers = {
  'Authorization': 'Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==',
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json',
}

data = {
  'grant_type': 'client_credentials',
}

response = requests.post('https://api.orange.com/oauth/v3/token', headers=headers, data=data)

Example http.client

import http.client

conn = http.client.HTTPSConnection('api.orange.com')
headers = {
  'Authorization': 'Basic NktSSHljksdj7P...Jjndb6UdnlrT2lOaA==',
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json',
}
conn.request('POST', '/oauth/v3/token', 'grant_type=client_credentials', headers)
response = conn.getresponse()

Following this request, you will receive a response, which can be either successful or in error:

Example of a successful response:
HTTP/1.1 200 OK
Content-Type: application/json
{
   "token_type": "Bearer",
   "access_token": "i6m2iIcY0SodWSe...L3ojAXXrH",
   "expires_in": 3600
}
Example of an error response:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate : Basic realm="Authorization Required"
{
   "error": "invalid_client",
   "error_description": "The requested service needs credentials, but the ones provided were invalid."
}
  • When you perform POST requests with curl or wget, parameters are specified as application/x-www-form-urlencoded using the -d flag.
  • Token requests are limited to 50 requests per minute. When the rate limit is exceeded, you will receive a 429 error.
  • A token is valid for 60 minutes. Do not make more token requests than one per hour for an application.
  • Header Accept: application/json is now required. When it is omitted you will receive a 406 error.
  • The Authorization Header is now forbidden when providing the client_id/client_secret in the body. A 400 error “Duplicate credentials” is generated.

Step 3 - Access the protected resources using the OAuth access token

To call our API, the access token is mandatory. The bearer token must be provided in the request using HTTP Authorization header. For example:

curl -X GET \
-H "Authorization: Bearer i6m2iIcY0SodWSe...L3ojAXXrH" \
https://api.orange.com/poi/v1/shops?postalCode=35000

Example cURL

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.orange.com/poi/v1/shops?postalCode=35000');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer i6m2iIcY0SodWSe...L3ojAXXrH',
]);

$response = curl_exec($ch);

curl_close($ch);

Example Guzzle

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client();

$response = $client->get('https://api.orange.com/poi/v1/shops', [
   'query' => [
      'postalCode' => '35000'
   ],
   'headers' => [
      'Authorization' => 'Bearer i6m2iIcY0SodWSe...L3ojAXXrH'
   ]
]);
using System.Net.Http;

HttpClient client = new HttpClient();

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://api.orange.com/poi/v1/shops?postalCode=35000");

request.Headers.Add("Authorization", "Bearer i6m2iIcY0SodWSe...L3ojAXXrH");

HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
import java.io.IOException
import okhttp3.OkHttpClient
import okhttp3.Request

val client = OkHttpClient()

val request = Request.Builder()
   .url("https://api.orange.com/poi/v1/shops?postalCode=35000")
   .header("Authorization", "Bearer i6m2iIcY0SodWSe...L3ojAXXrH")
   .build()

client.newCall(request).execute().use { response ->
   if (!response.isSuccessful) throw IOException("Unexpected code $response")
   response.body!!.string()
}
extern crate reqwest;
use reqwest::header;

fn main() -> Result<(), Box<dyn std::error::Error>> {
   let mut headers = header::HeaderMap::new();
   headers.insert("Authorization", "Bearer i6m2iIcY0SodWSe...L3ojAXXrH".parse().unwrap());

   let client = reqwest::blocking::Client::builder()
      .redirect(reqwest::redirect::Policy::none())
      .build()
      .unwrap();
   let res = client.get("https://api.orange.com/poi/v1/shops?postalCode=35000")
      .headers(headers)
      .send()?
      .text()?;
   println!("{}", res);

   Ok(())
}

Example fetch

fetch('https://api.orange.com/poi/v1/shops?postalCode=35000', {
   headers: {
      'Authorization': 'Bearer i6m2iIcY0SodWSe...L3ojAXXrH'
   }
});

Example jQuery

$.ajax({
   url: 'https://api.orange.com/poi/v1/shops',
   crossDomain: true,
   headers: {
      'Authorization': 'Bearer i6m2iIcY0SodWSe...L3ojAXXrH'
   },
   data: {
      'postalCode': '35000'
   }
}).done(function(response) {
   console.log(response);
});

Example XHR

let xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open('GET', 'https://api.orange.com/poi/v1/shops?postalCode=35000');
xhr.setRequestHeader('Authorization', 'Bearer i6m2iIcY0SodWSe...L3ojAXXrH');

xhr.onload = function() {
   console.log(xhr.response);
};

xhr.send();

Example HttpClient

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
   .uri(URI.create("https://api.orange.com/poi/v1/shops?postalCode=35000"))
   .GET()
   .setHeader("Authorization", "Bearer i6m2iIcY0SodWSe...L3ojAXXrH")
   .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

Example HttpURLConnection

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {
   public static void main(String[] args) throws IOException {
      URL url = new URL("https://api.orange.com/poi/v1/shops?postalCode=35000");
      HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
      httpConn.setRequestMethod("GET");

      httpConn.setRequestProperty("Authorization", "Bearer i6m2iIcY0SodWSe...L3ojAXXrH");

      InputStream responseStream = httpConn.getResponseCode() / 100 == 2
         ? httpConn.getInputStream()
         : httpConn.getErrorStream();
      Scanner s = new Scanner(responseStream).useDelimiter("\\A");
      String response = s.hasNext() ? s.next() : "";
      System.out.println(response);
   }
}

Example jsoup

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.jsoup.Connection;
import org.jsoup.Jsoup;

class Main {
   public static void main(String[] args) throws IOException {
      Connection.Response response = Jsoup.connect("https://api.orange.com/poi/v1/shops?postalCode=35000")
         .header("Authorization", "Bearer i6m2iIcY0SodWSe...L3ojAXXrH")
         .method(org.jsoup.Connection.Method.GET)
         .ignoreContentType(true)
         .execute();
      System.out.println(response.parse());
   }
}

Example okHttp

import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
   .url("https://api.orange.com/poi/v1/shops?postalCode=35000")
   .header("Authorization", "Bearer i6m2iIcY0SodWSe...L3ojAXXrH")
   .build();

try (Response response = client.newCall(request).execute()) {
   if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
   response.body().string();
}

Example node-fetch

import fetch from 'node-fetch';

fetch('https://api.orange.com/poi/v1/shops?postalCode=35000', {
   headers: {
      'Authorization': 'Bearer i6m2iIcY0SodWSe...L3ojAXXrH'
   }
});

Example http

import https from 'https';

const options = {
   hostname: 'api.orange.com',
   path: '/poi/v1/shops?postalCode=35000',
   headers: {
      'Authorization': 'Bearer i6m2iIcY0SodWSe...L3ojAXXrH'
   }
};

const req = https.get(options, function (res) {
   const chunks = [];

   res.on('data', function (chunk) {
      chunks.push(chunk);
   });

   res.on('end', function () {
      const body = Buffer.concat(chunks);
      console.log(body.toString());
   });
});

Example requests

import requests

headers = {
   'Authorization': 'Bearer i6m2iIcY0SodWSe...L3ojAXXrH',
}

params = {
   'postalCode': '35000',
}

response = requests.get('https://api.orange.com/poi/v1/shops', params=params, headers=headers)

Example http.client

import http.client

conn = http.client.HTTPSConnection('api.orange.com')
headers = {
   'Authorization': 'Bearer i6m2iIcY0SodWSe...L3ojAXXrH',
}
conn.request('GET', '/poi/v1/shops?postalCode=35000', headers=headers)
response = conn.getresponse()

If your client application attempts to use an expired or revoked access token, an invalid token error is returned.

Your application is now ready to consume the Orange API’s resources protected by the OAuth 2.0 M2M protocol.

Learn more

provides you with a step-by-step guide with screen shots to help you get started on Orange Developer

provides you with a complete list of possible errors on Orange Developer APIs and how to troubleshoot them

tool that automatically generates code in various formats