API menu

Mobile Service Management Documentation

Mobile Service Management API is only available for clients with a KPN Business Market contract.

Introduction

The Mobile Service Management API allows you to manage your corporate fleet of mobile devices and subscription with KPN Mobile. This API consists of a set of tools to order, provision, maintain and configure mobile phones from KPN.

API specification

Test the API on SwaggerHub

Base URL

https://api-prd.kpn.com/mobile/kpn/mobileservices

Features

This API allows you a.o. to:

  • order mobile devices and subscriptions for your company,
  • track and trace orders,
  • create and maintain contracts,
  • manage users and addresses,
  • SIM card management including blocking and replacement.

Getting started

Make sure you've read the page What's in it for you for more info on how to register and start testing APIs.

Authentication

The API follows the KPN Store API Authentication Standard to secure the API. It includes the use of OAuth 2.0 client_id and client_secret to receive an access token.

Please note that the authentication URL to retrieve a token, is different for this specific API. The URL for this Mobile Service Management API is: https://api-prd.kpn.com/oauth/grip/msm/accesstoken?grant_type=client_credentials

Go to the Authentication tab on top of this page to find out how to:

  • Authenticate to an API using cURL.
  • Authenticate to an API on Swaggerhub.
  • Import Open API Specifications (OAS), also called Swagger files into Postman.

How to...

Change user data

The goal of this procedure is to change some data of user.

First we are going to get an access token so we can provide that (bearer)token to our API requests. Use your Client ID/Client Secret from the project you use the MSM API in. Send your request to _https://api-prd.kpn.com/oauth/grip/msm/accesstoken?grant_type=client_credentials_and fetch the value of access_token from the json response.

For each request to the API, we have to add a header key called Authorization with the value Bearer <your_access_token_here> (leave out the < and > chars.).

Next step is to get all subscribers who are managed by you. After the base URL (shown on top of this page) you add: /hierarchy/subscribers That's it. Submit the GET request you have created. You can expect a response json result similar to this:

Response example
{ "result": [ { "id": 1234567, "firstName": "Julia", "prefix": "", "lastName": "Roberta", "path": [ { "id": 2345678, "name": "COMPANY X", "type": "CUSTOMER", "email": null }, { "id": 3456789, "name": "COMPANY X BV", "type": "DEBTOR", "email": null } ], "contracts": { "firstPhoneNumber": null, "amount": 0 }, "fixedNumber": null, "employeeNumber": "CRAWLER8000", "user": false, "gripUser": false }, { "id": 1234568, "firstName": "Joshua", "prefix": "", "lastName": "Martino", "path": [ { "id": 2345678, "name": "COMPANY X", "type": "CUSTOMER", "email": null }, { "id": 3456789, "name": "COMPANY X BV", "type": "DEBTOR", "email": null }, { "id": 4567890, "name": "123", "type": "COST_CENTER", "email": null } ], "contracts": { "firstPhoneNumber": "31611111111", "amount": 1 }, "fixedNumber": null, "employeeNumber": "CRAWLER9000", "user": false, "gripUser": false } ], "total": 2 }

So here we have 2 subscribers, of which only 1 of them has a contract attached to it. Let's zoom in on that user Joshua with id=1234568. Re-use the GET request /hierarchy/subscribers but now specify the subscriber we want to know more about by providing its id in the path: basepath + /hierarchy/subscribers/:id We use id 1234568 and send the request. The response is as follows:

Response example
{ "path": [ { "id": 2345678, "name": "COMPANY X", "type": "CUSTOMER", "email": null }, { "id": 3456789, "name": "COMPANY X BV", "type": "DEBTOR", "email": null }, { "id": 4567890, "name": "123", "type": "COST_CENTER", "email": null } ], "id": 1234568, "location": [ "Company X", "Company X BV", "123", "Martino, Joshua" ], "firstName": "Joshua", "surnamePrefix": "", "surname": "Martino", "email": "joshua.martino@companyx.nl", "vip": false, "employeeNumber": "CRAWLER9000", "gender": "MALE", "preferredLanguage": "NL", "comments": "CRAWLER9000", "mobileNumber": "", "fixedNumber": null, "user": false, "gripUser": false }

To update the user, the minimum set of data submitted is:

  • firstName,
  • surname
  • and gender.

Handle with care, as leaving out other fields, will reset them to their default values, like empty string, false of null

For this example, we are going to change the surnamePrefix and emailaddress of the user. Make the changes in the body payload and submit the request. Note that we leave out the fields vip, mobilenumber, fixedNumber, user, gripUser because they already have a default value. To update, issue a PUT request to basepath + /hierarchy/subscribers/:id

Request example
{ "referenceNumber": "1234568", "subscriber": { "firstName": "Joshua", "surnamePrefix": "di", "surname" : "Martino", "email": "joshua.di.martino@companyx.nl", "employeeNumber": "CRAWLER9000", "gender" : "MALE", "preferredLanguage": "NL", "comments": "CRAWLER9000" } }

Result will look like this:

Response example
{ "contextName": "Martino, Joshua", "operation": "changeUserData", "status": "Initialized", "referenceNumber": "1234568 [FSR9]", "id": 7654321, "creationDate": "2022-02-25T11:01:03.100+00:00" }

Change Subscriber contract

The scenario is that for a specific subscriber, we would like to make changes to the contract. First we are going to lookup the contracts of all subscribers. Submit a GET request to the basepath added with /contract/all

Response example
{ "result": [ { "id": 9876543, "firstName": "Maxim", "namePrefix": "van", "lastName": "Aanholt", "mobileNumber": "31680000000", "fixedNumber": null, "product": { "en": "Mobile Voice and Data", "nl": "Mobiel Bellen en Internet" }, "productCategory": "Network Services", "state": "ACTIVE", "simCardNumber": "1234567890123456789", "extension": null, "sipAccount": null, "imei": null, "category": "MOBILE" } ], "total": 1 }

Great, let's get the contract details of this subscriber's contract. Again send a GET request with the contract id (9876543) of this subscriber with basepath added with /contract/id/9876543/items The response json is very lengthy so we take a subset out of this.

Response example
{ "id": 2419028783, "citemBsId": 202293970, "contractId": 1623106407, "productBsId": 3098, "tariffPlanVariantBsId": 60972, "name": { "en": "Mobile Voice and Data", "nl": "Mobiel Bellen en Internet" }, "children": [ { "id": 2419028773, "citemBsId": 202293984, "contractId": 1623106407, "productBsId": 1555, "tariffPlanVariantBsId": 60972, "name": { "en": "Data Roaming EU", "nl": "Data Roaming EU" }, "children": [] }, { "id": 2419028781, "citemBsId": 202293972, "contractId": 1623106407, "productBsId": 4394, "tariffPlanVariantBsId": 60972, "name": { "en": "Data Usage Notification", "nl": "Dataverbruik Melding" }, "children": [ { "id": 2419512359, "citemBsId": 202341166, "contractId": 1623106407, "productBsId": 4399, "tariffPlanVariantBsId": 60972, "name": { "en": "Data Usage Notification 5000 MB", "nl": "Dataverbruik Melding 5000 MB" }, "children": [] } ] } ] }

As we would like to make changes to the contract, we first have to initialise the basket for this contract. We do that by creating a POST request to basepath added with /contracting/basket In the body we add a json payload with the contractid:

Request example
{ "contractId": 9876543 }

As a result, we'll receive a sessionId, that we need in our subsequent requests.

Response example
{ "sessionId": "334caa-1122-3344-5566-aabb34567" }

To see all products and prices, we can issue a GET request with the sessionId (334caa-1122-3344-5566-aabb34567) we just got: basepath + /contracting/basket?sessionId=334caa-1122-3344-5566-aabb34567 This is a lengthy result, so we only show a subset of the json response.

Response example
{ "productTree": [ { "id": "TreeNode_12345_1234567890", "name": { "en": "Mobile Voice and Data", "nl": "Mobiel Bellen en Internet" }, "selected": true, "disabled": true, "visible": true, "contracted": true, "amount": 1, "canOrderMoreThanOne": false, "childrenSelectionStrategy": "SELECT_MANY", "error": null, "children": [ { "id": "TreeNode_12345_1234567891", "name": { "en": "Sim Only Voice and Data", "nl": "Sim Only Bellen en Internet" }, "selected": true, "disabled": true, "visible": true, "contracted": true, "amount": 1, "canOrderMoreThanOne": false, "childrenSelectionStrategy": "NONE", "error": null, "children": [], "price": { "oneTime": { "activationFeeInCents": 0, "hardwareFeeInCents": 0, "privateCopyingLevyInCents": 0 }, "recurring": { "monthlyFeeInCents": 1000 } } }, { "id": "TreeNode_213112_1646139052421", "name": { "en": "VoiceMail", "nl": "VoiceMail" }, "selected": true, "disabled": false, "visible": true, "contracted": true, "amount": 1, "canOrderMoreThanOne": false, "childrenSelectionStrategy": "NONE", "error": null, "children": [], "price": { "oneTime": { "activationFeeInCents": 0, "hardwareFeeInCents": 0, "privateCopyingLevyInCents": 0 }, "recurring": { "monthlyFeeInCents": 0 } } } ], "price": { "oneTime": { "activationFeeInCents": 0, "hardwareFeeInCents": 0, "privateCopyingLevyInCents": 0 }, "recurring": { "monthlyFeeInCents": 0 } } } ], "characteristics": {}, "oldPrice": { "oneTime": { "activationFeeInCents": 0, "hardwareFeeInCents": 0, "privateCopyingLevyInCents": 0 }, "recurring": { "monthlyFeeInCents": 2000 } }, "totalPrice": { "oneTime": { "activationFeeInCents": 0, "hardwareFeeInCents": 0, "privateCopyingLevyInCents": 0 }, "recurring": { "monthlyFeeInCents": 2000 } } }

Great, we now know the specifics of the contract and can decide what to change. Let's change something by issueing a POST request to basepath + /contracting/basket In the body payload, enter the desired change:

Request example
{ "accountGroupId": 0, "characteristicActions": [ { "name": "string", "value": "string" } ], "contractId": 0, "fixedContractId": 0, "mobileContractId": 0, "orderId": 0, "productActions": [ { "amount": 0, "productId": "string", "type": "PUT" } ], "simCardNumber": "string", "templateId": "string", "templateIdToModify": 0 }

When you issued all changes to the basket, it's time to commit this. Issue a POST request to basepath + /contracting/basket/order In the body payload, enter the address:

Response example
{ "address": { "addressName": "string", "attention": "string", "city": "string", "companyName": "string", "country": "string", "floor": "string", "houseNumber": "string", "location": "string", "postalCode": "1234AB", "room": "string", "street": "string" }, "addressId": 0, "referenceNumber": "string", "wishDate": "2022-03-02T10:49:00.005Z" }

Order products

To order a product, we will have to fill the basket, make changes and submit the changes. To fill the basket, we will need an id to fill the basket with. First, let's get the id by issuing a GET request to basepath + */hierarchy/children It will consider your context and return the company data.

Response example
{ "result": [ { "path": [ { "id": 4567890, "name": "COMPANY X", "type": "CUSTOMER", "email": null } ], "id": 5678901, "name": "Company X BV", "type": "DEBTOR", "email": null } ], "total": 1 }

As we would like to make changes to the contract, we first have to initialise the basket for this contract. We do that by create a POST request to basepath added with /contracting/basket In the body we add a json payload with the contractid:

Request example
{ "contractId": 9876543 }

As a result, we'll receive a sessionId, that we need in our subsequent requests.

Response example
{ "sessionId": "334caa-1122-3344-5566-aabb34567" }

With this session id we can fill the basket with products and prices. We already seen that in previous 'how to'. If you would like to review that again, go to that request.

With this extensive list, it might be a bit much to comprehend. So there is a list of main products you can order. To GET this list send the request to basepath + /contracting/basket/main-products?sessionId=334caa-1122-3344-5566-aabb34567 You will receive a list of main products.

Response example
{ "result": [ { "bsId": 0, "name": "string", "oneTimePriceInCents": 0, "privateCopyingLevyInCents": 0 } ], "total": 0 }

Finally we have to apply the changes and submit the basket changes. Let's order something by issuing a POST request to basepath + /contracting/basket/order In the body payload, enter the desired change:

Request example
{ "accountGroupId": 0, "characteristicActions": [ { "name": "string", "value": "string" } ], "contractId": 0, "fixedContractId": 0, "mobileContractId": 0, "orderId": 0, "productActions": [ { "amount": 0, "productId": "string", "type": "PUT" } ], "simCardNumber": "string", "templateId": "string", "templateIdToModify": 0 }

When you have issued all changes to the basket, it's time to commit this. Issue a POST request to basepath + /contracting/basket/order In the body payload, enter the address:

Response example
{ "address": { "addressName": "string", "attention": "string", "city": "string", "companyName": "string", "country": "string", "floor": "string", "houseNumber": "string", "location": "string", "postalCode": "1234AB", "room": "string", "street": "string" }, "addressId": 0, "referenceNumber": "string", "wishDate": "2022-03-02T10:49:00.005Z" }