Hi.
I get an 401 unauthorized error when trying to execute a POST request to the World Check API. I can successfully execute the POST request using Postman. Any help would be appreciated.
My code is as follows:
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace World_CheckAPITester
{
    using System = global::System;
    class Program
    {
        static async Task Main(string[] args)
        {
            await new Program().UsingHttpClient();
        }
        // Combine the data signature and the API secret key to get the HMAC
        // This is the Microsoft HMACSHA256 code copied from the documentation
        private static string generateAuthHeader(string dataToSign, string apisecret)
        {
            byte[] secretKey = Encoding.UTF8.GetBytes(apisecret);
            HMACSHA256 hmac = new HMACSHA256(secretKey);
            hmac.Initialize();
            byte[] bytes = Encoding.UTF8.GetBytes(dataToSign);
            byte[] rawHmac = hmac.ComputeHash(bytes);
            string hex = BitConverter.ToString(rawHmac).Replace("-", "");
            
            return (Convert.ToBase64String(rawHmac));
        }
        private async Task UsingHttpClient() {
            try
            {
                HttpClient wc1Client = new HttpClient();
                string apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
                string apiSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
                string groupId = "0a3687cf-6c70-198a-9b22-d3fa000009bb";
                string wc1Protocol = "https://";
                string wc1Gatewayhost = "rms-world-check-one-api-pilot.thomsonreuters.com";
                string wc1GatewayUrl = "/v1/";
                string wc1QueryUrl = "cases/screeningRequest";
                string wc1Date = DateTime.UtcNow.ToString("R");
                dynamic postObject = new ExpandoObject();
                postObject.secondaryFields = new string[] { };
                postObject.entityType = "INDIVIDUAL";
                postObject.customFields = new string[] { };
                postObject.groupId = groupId;
                postObject.providerTypes = new string[] { "WATCHLIST" };
                postObject.name = "john smith";
                string postData = JsonConvert.SerializeObject(postObject);
                UTF8Encoding encoding = new UTF8Encoding();
                byte[] byte1 = encoding.GetBytes(postData);
                string dataToSign = "(request-target): post " + wc1GatewayUrl + "cases/screeningRequest\n" +
                "host: " + wc1Gatewayhost + "\n" + // no https only the host name
                "date: " + wc1Date + "\n" + // GMT date as a string
                "content-type: " + "application/json" + "\n" +
                "content-length: " + byte1.Length + "\n" +
                postData;
                string hmac = generateAuthHeader(dataToSign, apiSecret);
                string authorisation = "Signature keyId=\"" + apiKey + "\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date content-type content-length\",signature=\"" + hmac + "\"";
                wc1Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                wc1Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("basic", authorisation);
                wc1Client.DefaultRequestHeaders.Date = DateTime.UtcNow;
                StringContent postContent = new StringContent(JsonConvert.SerializeObject(postObject), Encoding.UTF8, "application/json");
                HttpResponseMessage httpResponse = await wc1Client.PostAsync(wc1Protocol + wc1Gatewayhost + wc1GatewayUrl + "cases/screeningRequest", postContent);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
            }
        }
    }
}
Regards.