.wpb_animate_when_almost_visible { opacity: 1; }

2-Legged OAuth in a nutshell

Published: April 25, 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 2-Legged OAuth in a nutshell guide presents the OAuth2 authentication process in a simplified way. It is divided into various tabs: the guide, the most common errors and various sample codes.

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:

2-legged OAuth2 process

Caution to the URL you use to retrieve your token. For more information, refer to the FQDN guide.

Get an 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:

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

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

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.

Use the OAuth access token to access protected Orange API resources

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

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

Learn more

This tab presents a non exhaustive list of errors that your application can get when calling the Orange Authorization Server. This list of errors fully complies with OAuth 2.0 specification.

HTTP Status Error (mandatory) Error description (optional)
400 invalid_grant The parameter grant_type is not valid.
400 invalid_request The URI does not support the requested method.
400 invalid_request The requested URI or the requested resource does not exist.
400 invalid_request One or more required query-string parameters are missing.
400 unauthorized_client The application that makes the request is not authorized to access this endpoint (ex: not a subscribed service).
401 invalid_client The requested service needs credentials, but none were provided.
401 invalid_client The requested service needs credentials, but the ones provided were invalid.
401 invalid_client The requested service needs credentials, and the ones provided were out-of-date.

More information

For a description of all errors related to APIs, of how to handle and troubleshoot them, refer to: Best Practices for API error handling and troubleshooting 

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()

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

provides you with a complete explanation on the Oauth2 protocol and how to use it on Orange Developer

explains the URLs to be taken into account when requesting an access token

tool that automatically generates code in various formats