KYC Tenure

The "Know Your Customer Tenure" API checks whether the lifetime tenure of a given phone number exceeds the date provided by the customer.

Anti-Fraud
Network API
Camara
Playground

Introduction

The CAMARA KYC Tenure API provides a standardized mechanism to customer to verify the period of time (i.e. "tenure") for which the end user allocated to a network subscription identifier has been associated with it by the current network operator. Additionally to this information the API retrieved the contract type (prepaid contract, postpaid contract, business contract)

API Scope

The current API implementation is applicable to any mass-market masOrange, jazztel customers.

Subscribe to the API

You get the Authorization header credentials when you register your application on the Orange Developer Console.

API Authentication

HTTPS requests to the REST API are protected with CIBA 3-Legged OAuth.

In short, the API Invoker (e.g. Application Backend or Aggregator) before to request Kyc Tenure check, needs to request a Three-Legged Access Token from Orange Authorization Server. The process follows the OpenID Connect Client-Initiated Backchannel Authentication (CIBA) flow.

Step 1: request the OAuth authorization code from the user device

The API Invoker provides in the authorization request (/bc_authorize) a login_hint with a valid User identifier together with the application credentials (client_assertion & client_assertion_type) and indicates the Purpose for processing Personal Data. The Orange implementation follows the CAMARA scope definition. The scope must be set to: opendid dpv: . dpv stands for Data Privacy Vocabulary.

Note on JWT usage via client assertion: client_assertion is a JWT used by a client to authenticate itself to an authorization server, while client_assertion_type specifies the type of assertion being used, typically indicating it is a JWT. Together, they facilitate secure client authentication in OAuth 2.0 and OpenID Connect protocols. API consumer as to define JWK keystore in settings tab of the application in Orange Developer

Current supported DPV value is:

FraudPreventionAndDetection

Example: to check the KYC Tenure, in a context of fraud prevention and detection, the scope in the bc-authorize must be set to openid dpv:FraudPreventionAndDetection kyc-age-verification:verify

Orange Authorization Server will check if the owner of the phone number did not opted-out to authorize access to this data. If this is not the case a response 200 is sent back with a authorization request identifier (auth_req_id). If the resource owner or OpenID Provider denied the request an error 403 Forbidden is sent back.

Request:

curl  -X POST \
  'https://api.orange.com/es/openapi/oauth/v2/bc-authorize' \
  --header 'Accept: */*' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'login_hint=tel:+34654654654' \
  --data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
  --data-urlencode 'client_assertion=eyJhbGciOiJSUz...1jjGg' \
  --data-urlencode 'scope=openid dpv:FraudPreventionAndDetection kyc-tenure:check-tenure'

Response:

200 
Content-Type: application/json
{
  "auth_req_id": "y_azuw2HT4fWYPb0-0w2DBhaEq8",
  "expires_in": 120,
  "interval": 2
}

Step 2: Request the OAuth access token

Once the client application gets the authorization code, the API Invoker polls the token endpoint by making an "HTTP POST" request by sending the grant_type (urn:openid:params:grant-type:ciba), auth_req_id (OperatorAuthReqId) and the the application credentials (client_assertion & client_assertion_type) parameters

If the transaction succeeds, in the POST response, the acccess_token is provided.

Request:

curl  -X POST \
  'https://api.orange.com/es/openapi/oauth/v2/token' \
  --header 'Accept: */*' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
  --data-urlencode 'client_assertion=eyJhbGciOi....iuT111jjGg' \
  --data-urlencode 'auth_req_id=y_azuw2HT4fWYPb0-0w2DBhaEq8' \
  --data-urlencode 'grant_type=urn:openid:params:grant-type:ciba'

Response:

200 
Content-Type: application/json
{
  "token_type": "Bearer",
  "access_token": "xxxx",
  "expires_in": 179
}

Step 3: Access protected resources using OAuth access token

In order to call our API, the access_token is mandatory.

Specific documentation about match resource is provided below.

API Description

Summary of resources

This API has one resource check-tenure.

Summary of methods and URL

Use case of operationURL method
I want to verify the period of time (i.e. "tenure") for which the phone number has been associated with it by the current network operator.POST "https://api.orange.com/camara/oes/kyc-age-verification/v0.2/check-tenure"

Summary of request body parameters

NameTypeDescriptionMandatory
phoneNumberstringSubscriber number in E.164 format (starting with country code). Must not be passed as deducted from the token.No
tenureDatedateThe date, in RFC 3339 / ISO 8601 compliant format "YYYY-MM-DD", from which continuous tenure of the identified network subscriber is required to be confirmed. For privacy reason the depth of the tenure checked is limited to 30 days.Yes

Summary of response parameters

NameTypeDescriptionMandatory
tenureDateCheckbooleantrue when the identified mobile subscription has had valid tenure since tenureDate, otherwise falseYes
contractTypeStringThe network subscription account type, if known: Prepaid(PAYG), prepaid (PAYM) or business line (Business)No

Request

curl -X POST "https://api.orange.com/camara/oes/kyc-tenure/v0.2/check-tenure"
-H "Authorization: Bearer {your access token}"
-H "Cache-Control: no-cache"  
-H 'accept: application/json'
-H 'Content-Type: application/json'
-d  '{
       "tenureDate": "2024-01-01"
  }'

Response

200 Match successful
Content-Type: application/json
{
    "contractType": "Business",
    "tenureDateCheck ": true
}

Fields description

Most frequent errors

If invalid input are provided in particular for the device identifier a 400 error is triggered.

HTTP/1.1 400 Invalid input
Content-Type: application/json
{
  "code": "INVALID_ARGUMENT",
  "status": 400,
  "message": "Invalid input"
}

If the service is not up and running, a 503 error is sent.

HTTP/1.1 503 Service unavailable
Content-Type: application/json
{
  "code": "UNAVAILABLE",
  "status": 503,
  "message": "Service unavailable"
}

If the phoneNumber is provided in the payload, an error 422 is sent.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
  "status": 422,
  "code": "UNNECESSARY_IDENTIFIER",
  "message": "The device is already identified by the access token"
}

There are some cases where your client application will no longer gain access to API resources, and get an error back.

Please check the following points:

  • Here, you attempt to use an expired or revoked access_token and you get an invalid token error. You will have to request a new access_token. As an example:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
  "code": "UNAUTHENTICATED",
  "status": 401,
  "message": "Authorization failed: ..."
}
  • Here, you removed your subscription to the API so that the capability to generate an access_token is not allowed anymore. As an example:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
  "code": "PERMISSION_DENIED",
  "status": 403,
  "message": "Operation not allowed: ..."
}