diff --git a/GreenArrow.Engine/DKIMKeysApi/DKIMKeysApiClient.cs b/GreenArrow.Engine/DKIMKeysApi/DKIMKeysApiClient.cs
new file mode 100644
index 0000000..a2e3eed
--- /dev/null
+++ b/GreenArrow.Engine/DKIMKeysApi/DKIMKeysApiClient.cs
@@ -0,0 +1,79 @@
+using GreenArrow.Engine.Extensions;
+using GreenArrow.Engine.RestApi;
+using Microsoft.Extensions.Options;
+using System.Net;
+using System.Net.Http.Headers;
+
+namespace GreenArrow.Engine.DKIMKeysApi
+{
+ ///
+ /// DKIM Keys API client implementation
+ ///
+ public class DKIMKeysApiClient : IDKIMKeysApi
+ {
+ private readonly GreenArrowEngineSettings _settings;
+ private readonly IHttpClientFactory _httpFactory;
+
+ private readonly string _endpoint;
+
+ ///
+ /// Initializes a new instance of Green Arrow DKIM Keys API Client
+ ///
+ /// Green Arrow settings with API Url and Authorization Token
+ /// HttpClienFactory for create HttpClient objects
+ public DKIMKeysApiClient(
+ IOptions options,
+ IHttpClientFactory httpFactory)
+ {
+ _settings = options.Value;
+ _httpFactory = httpFactory;
+ _endpoint = GetEndPoint();
+ }
+
+ private HttpClient CreateHttpClient()
+ {
+ var client = _httpFactory.CreateClient();
+ return client;
+ }
+
+ private string GetEndPoint()
+ {
+ var baseUri = new Uri(_settings.ServerUri);
+ var endpointUri = new Uri(baseUri, _settings.DKIMKeysAPIEndpoint);
+ return endpointUri.ToString();
+ }
+
+ ///
+ public async Task> PostAsync(DKIMKeysRequest request, CancellationToken cancellationToken = default)
+ {
+ try
+ {
+ var jsonContent = request.ToJson();
+
+ var client = CreateHttpClient();
+
+ var authenticationString = $"{request.Username}:{request.Password}";
+ var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(authenticationString));
+
+ client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString);
+
+ var httpContent = new StringContent(jsonContent, encoding: default, mediaType: "application/json");
+ var httpResponse = await client.PostAsync(_endpoint, httpContent, cancellationToken);
+
+ if (httpResponse.StatusCode == HttpStatusCode.OK)
+ {
+ var result = await httpResponse.Content.ReadAsStringAsync(cancellationToken);
+ var content = result.ToObject();
+ return new RestApiResponse(httpResponse.StatusCode, content);
+ }
+
+ return new RestApiResponse(httpResponse.StatusCode);
+
+ }
+ catch (Exception exception)
+ {
+ throw new RestApiException("Unexpected exception", exception);
+ }
+ }
+ }
+}
diff --git a/GreenArrow.Engine/DKIMKeysApi/DKIMKeysRequest.cs b/GreenArrow.Engine/DKIMKeysApi/DKIMKeysRequest.cs
new file mode 100644
index 0000000..d910fcb
--- /dev/null
+++ b/GreenArrow.Engine/DKIMKeysApi/DKIMKeysRequest.cs
@@ -0,0 +1,29 @@
+using GreenArrow.Engine.Model;
+using GreenArrow.Engine.RestApi;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+
+namespace GreenArrow.Engine.DKIMKeysApi
+{
+ ///
+ /// Create a DKIM Key Request
+ ///
+ [JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy), ItemNullValueHandling = NullValueHandling.Ignore)]
+ public class DKIMKeysRequest : IRestApiModel
+ {
+ ///
+ /// Username that is authorized to log in to GreenArrow Engine’s web interface.
+ ///
+ public string Username { get; set; }
+
+ ///
+ /// Password that is authorized to log in to GreenArrow Engine’s web interface.
+ ///
+ public string Password { get; set; }
+
+ ///
+ /// To create the private key
+ ///
+ public DkimKey DkimKey { get; set; }
+ }
+}
diff --git a/GreenArrow.Engine/DKIMKeysApi/DKIMKeysResponse.cs b/GreenArrow.Engine/DKIMKeysApi/DKIMKeysResponse.cs
new file mode 100644
index 0000000..b3ba93f
--- /dev/null
+++ b/GreenArrow.Engine/DKIMKeysApi/DKIMKeysResponse.cs
@@ -0,0 +1,42 @@
+using GreenArrow.Engine.Model;
+using GreenArrow.Engine.RestApi;
+
+namespace GreenArrow.Engine.DKIMKeysApi
+{
+ ///
+ /// GreenArrow Response is the full DKIM Key record data
+ ///
+ public class DKIMKeysResponse : IRestApiModel
+ {
+ ///
+ /// When request was succesful created
+ ///
+ public bool Success { get; init; }
+
+ ///
+ /// Full DKIM Key record data
+ ///
+ public DKIMKeysResponseData Data { get; init; }
+
+ ///
+ /// Error code when request was not accepted
+ ///
+ public string ErrorCode { get; init; }
+
+ ///
+ /// Error message when request was not accepted
+ ///
+ public string ErrorMessages { get; init; }
+ }
+
+ ///
+ /// Full DKIM Key record data
+ ///
+ public class DKIMKeysResponseData
+ {
+ ///
+ /// Full DKIM Key record data
+ ///
+ public DkimKey DkimKey { get; init; }
+ }
+}
diff --git a/GreenArrow.Engine/DKIMKeysApi/IDKIMKeysApi.cs b/GreenArrow.Engine/DKIMKeysApi/IDKIMKeysApi.cs
new file mode 100644
index 0000000..e7846de
--- /dev/null
+++ b/GreenArrow.Engine/DKIMKeysApi/IDKIMKeysApi.cs
@@ -0,0 +1,19 @@
+using GreenArrow.Engine.RestApi;
+
+namespace GreenArrow.Engine.DKIMKeysApi
+{
+ ///
+ /// Represent the actions available in Green Arrow Engine DKIM Keys API
+ ///
+ ///
+ public interface IDKIMKeysApi
+ {
+ ///
+ /// Create a DKIM Key
+ ///
+ ///
+ /// The cancellation toekn
+ /// A generic rest api response with the deserialized DKIM Keys API response when success
+ Task> PostAsync(DKIMKeysRequest request, CancellationToken cancellationToken = default);
+ }
+}
diff --git a/GreenArrow.Engine/GreenArrowEngineSettings.cs b/GreenArrow.Engine/GreenArrowEngineSettings.cs
index 48d477f..0237531 100644
--- a/GreenArrow.Engine/GreenArrowEngineSettings.cs
+++ b/GreenArrow.Engine/GreenArrowEngineSettings.cs
@@ -14,5 +14,10 @@ public class GreenArrowEngineSettings
/// The HTTP Submission API Endpoint
///
public string HTTPSubmissionAPIEndpoint { get; set; } = "/api/v1/send.json";
+
+ ///
+ /// The DKIM API Endpoint
+ ///
+ public string DKIMKeysAPIEndpoint { get; set; } = "/api/v3/eng/dkim_keys";
}
}
diff --git a/GreenArrow.Engine/Model/DkimKey.cs b/GreenArrow.Engine/Model/DkimKey.cs
new file mode 100644
index 0000000..162dedd
--- /dev/null
+++ b/GreenArrow.Engine/Model/DkimKey.cs
@@ -0,0 +1,53 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+
+namespace GreenArrow.Engine.Model
+{
+ ///
+ /// Dkim Key Data
+ ///
+ [JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy), ItemNullValueHandling = NullValueHandling.Ignore)]
+ public class DkimKey
+ {
+ ///
+ /// The domain name associated with this DKIM Key.
+ ///
+ public string Domain { get; init; }
+
+ ///
+ /// The selector used to identify this DKIM Key.
+ ///
+ public string Selector { get; init; }
+
+ ///
+ /// Whether this is the default DKIM key for this domain.
+ ///
+ public string DefaultForDomain { get; init; }
+
+ ///
+ /// The key data
+ ///
+ public Key Key { get; init; }
+ }
+
+ ///
+ /// The key data
+ ///
+ public class Key
+ {
+ ///
+ /// The number of bits used to generate this key.
+ ///
+ public int Bits { get; init; }
+
+ ///
+ /// The PEM-encoded private key.
+ ///
+ public string Private { get; init; }
+
+ ///
+ /// The public key, derived from the private key. This is PEM-encoded with the header line, footer line, and line-breaks stripped.
+ ///
+ public string Public { get; init; }
+ }
+}