© 2018 Capita Business Services Ltd. All rights reserved.

Capita Education Software Solutions is a trading name of Capita Business Services Ltd. Our Registered office is 30 Berners Street, London, W1T 3LR and our registered number is 02299747. Further information about Capita plc can be found in our legal statement.

SIMS 8 - V3 APIs - Sample Code Overview

Every developer will have an opinion on how to consume web APIs; this application is intended to be the lowest common denominator to show principles and strip calls down to their bare essentials in a 'Postmanesque' theme. The code is available here.

Configuration Information.

<?xml version="1.0" encoding="utf-8" ?>
  <Scopes>simsserverapplication partner</Scopes>

In order to test the application, you will need to replace Client_ID and Organisation ID provided by partner support.

Arguments Passed

        static void Main(string[] args)
            XmlDocument commands = new XmlDocument();
            // Load the config
            PostitCommon.AuthRequest arq = new PostitCommon.AuthRequest();
            arq.Client_ID= commands.SelectSingleNode("Config/Client_ID").InnerXml;
            arq.Scopes = commands.SelectSingleNode("Config/Scopes").InnerXml;
            arq.STS = commands.SelectSingleNode("Config/STS").InnerXml;
            arq.Organisation_ID = commands.SelectSingleNode("Config/Organisation_ID").InnerXml;
            // We shouldn't encourage these to be stored in clear in a file!
            arq.Secret = args[0];
            arq.OCP_APIM_Key = args[1];

In addition we need to pass in the Client Secret and API Manager (OCP_APIMKey) Key in order to be able to:

  1. Create an authorisation request.
  2. Get a successful value back.
    public class AuthRequest
        public string STS { get; set; }
        public string Client_ID { get; set; }
        public string Secret { get; set; }
        public string Organisation_ID { get; set; }
        public string Scopes { get; set; }
        public string OCP_APIM_Key { get; set; }


Again these will be provided via SIMS ID and/or Partner Support.

Having collated the Authorisation request, we need to create an http client and make a post call to get an access token.

            // Get a token
            HttpClient httpClient = new HttpClient();
            PostitCommon.BearerToken bt = new PostitCommon.BearerToken(arq, httpClient);

Which under the hood looks like this:

using System.Web.Script.Serialization;
    public class BearerToken
        public string Token = "";
        public BearerToken(AuthRequest arq, HttpClient httpClient)
            string grant_type = "client_credentials";
            string client_id = arq.Client_ID; 
            string client_secret = arq.Secret;
            var form = new Dictionary<string, string>
                    {"grant_type", grant_type},
                    {"client_id", client_id},
                    {"client_secret", client_secret},
                    { "scope", arq.Scopes },
                    { "acr_values","orgselected:"+arq.Organisation_ID }

            var httpClientResponseTask = httpClient.PostAsync(arq.STS, new FormUrlEncodedContent(form));
            var result = httpClientResponseTask.Result;
            var responseStringTask = result.Content.ReadAsStringAsync();
            string responseString = responseStringTask.Result;
            var JSONObj = new JavaScriptSerializer().Deserialize<Dictionary<string, string>>(responseString);
            Token = JSONObj["access_token"];

NB: Error handling is slim to non - existent but the aim is to keep it simple.

This then returns a JWT (JSON Web Token) which is then used to make calls to the SIMS Primary APIs.


<?xml version="1.0" encoding="utf-8" ?>
  <Actions Service='Assessment'>
    <Action verb='GET'      version='V3' endpoint='AssessmentAspects'/>
    <Action verb='GET'      version='V3' endpoint='AssessmentAspects({ExternalID})'/>
    <Action verb='GET'      version='V3' endpoint='AssessmentAspects/SIMS.Changes(startDate={startDate})'/>
    <Action verb='POST'     version='V3' endpoint='AssessmentAspects'/>
    <Action verb='PATCH'    version='V3' endpoint='AssessmentAspects({ExternalID})'/>
    <Action verb='DELETE'   version='V3' endpoint='AssessmentAspects({ExternalID})'/>

The white list is the published set of end points

The application goes through the list and invokes any GET API with a $top=1 constraint 

           string BaseURL = commands.SelectSingleNode("Config/RootURL").InnerXml;
            PostitCommon.Log.LogFile = @"c:\temp\v3API.log";
            foreach (XmlNode n in WhiteList.SelectNodes("Whitelist/Actions"))
                string Service = n.Attributes["Service"].Value;
                PostitCommon.Call c = new PostitCommon.Call(BaseURL, Service, "V3", "$metadata","");
                c.ExecuteGet(bt.Token, httpClient, arq.OCP_APIM_Key);
                foreach (XmlNode n2 in n.ChildNodes)
                    string Verb = n2.Attributes["verb"].Value;
                    string Version = n2.Attributes["version"].Value;
                    string Endpoint = n2.Attributes["endpoint"].Value;
                    if (Verb == "GET" && !Endpoint.Contains("{" ))
                        c = new PostitCommon.Call(BaseURL,Service ,Version ,Endpoint,"$top=1");
                        c.ExecuteGet(bt.Token, httpClient, arq.OCP_APIM_Key);

The first call obtains the metadata for the service.

Subsequent calls explore the service.

We create a call (which formats the URL) ...

        public Call(string BaseURL, string Service, string Version, string Endpoint, string query)
            URL = BaseURL + Service + @"/" + Version + (Endpoint!=""? @"/" + Endpoint :"");
            if (query != "")
                URL = URL + "?" + query;
            // This is where it saves the output from the call to
            FolderName = @"c:\temp\APITest"; 
            FileName = Service + Version + Endpoint+".json";
            Name = Endpoint;
            Content_type = "";


and execute it...

public string ExecuteGet(string BearerToken, HttpClient httpClient, string OCP_APIM_Key)
            string rc = "";
                var request = new HttpRequestMessage()
                    RequestUri = new Uri(URL),
                    Method = HttpMethod.Get,
                if (Content_type != "")
                    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(Content_type));
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", BearerToken);
                request.Headers.Add("Ocp-Apim-Subscription-Key", OCP_APIM_Key);
                var httpClientResponseTask = httpClient.SendAsync(request);
                var result = httpClientResponseTask.Result;
                var responseStringTask = result.Content.ReadAsStringAsync();
                rc = responseStringTask.Result.ToString();
                // Then write logs and the output from the call

Whilst the page is long, the bones of code to utilise SIMS 8 Version 3 API calls 'fits' on a page and is available as a code sample.


Related resources for SIMS Primary

Working with SIMS Primary APIs

Information on how to work with the SIMS Primary APIs including general guidance and how to access the development portal.


SIMS 8 - APIs – V3 - Release Notes (23 Mar 20)

Release Notes for SIMS Primary APIs V3.


SIMS 8 - APIs - Version 3

The version three APIs expand the API coverage (both read and write) previously available. Integrators should code against V3 rather than V2.