Learn

Hierarchy

You own Products
Each Product contains Subscriptions.
Each Subscription represents a client, customer or device that contains Keys.
Each Key issued has a serial code.
Simple!

Basics

In the case of a physical product one can think of a subscription as a consumer that has a warranty period tracked through a serial code. QR Codes can be printed and attached to these physical goods removing the need for receipt-checking. In a software case think of a subscriber as the end user that is issued a Product Key with a validity period, an example would be a Netflix 1-month trial or a Windows 10 Software Box. In an IoT case, it can be both!

Step 1

Create an Account or login with your favourite Social service.

Step 2

After login, hit "Create New" to Create Your First Product. It is recommended (but not required) that you enter the name of your product. Your API Key will then be revealed.

Step 3

Hit 'Add Subscription' to create any subscribers you may have for your Product.

You have the following options as to how these Subscriptions will be treated when they expire:

  • Renew : Subscription gets a fresh new key
  • Extend : Creates a new copy of the key
  • Disable : Changes 'Current' state of key
  • Delete : Key is deleted altogether

Step 4

We do :)

Api Documentation

The OpenAPI v3 and Swagger specification documents are also available.
You have complete access to both Subscriptions and Products i.e List, Create, Read, Update & Delete.
As a graspable concept think of it as no more than a UUID / Guid that has a "life span" after which some "action" must occur! To that end at it's most primitive level it case be even used for something as trivial as generating one-time tokens / vouchers.
We'd much prefer if it be used for something cooler like 'calling back' a low-powered microcontroller with no RTC facility.

Protocol

By default HTTPS is required at all times.
HTTP can only be used by setting the query parameter 'default' to 'false' :

eg. 'http://keyserv.solutions/v1/ProductsApi?default=false'

Operation Verb
List POST | *GET
Create POST
Read POST | *GET
Update PUT / PATCH
Delete DELETE

*For security reasons we have disabled GET requests for the Products & Subscriptions APIs, THIS IS INTENTIONAL. We recommend it only be used on the Keys API which was designed for lighter client-side requests.

IP Address Rate Limiting is also in effect to mitigate attacks:
Stay within 60 Requests per minute. Burst-Rate: 180

Controllers

Products https://keyserv.solutions/v1/ProductsApi
Subscriptions https://keyserv.solutions/v1/SubscriptionsApi
Keys https://keyserv.solutions/v1/KeysApi

Find results can be paginated, returning 500 results at a time. Use the query parameter 'page' to access further records.

Products

Endpoint Spec & Example Returns

Count

ProductsApi/Count
Field Type Description Constraint Object
key string API Key Required UUID
POST /v1/ProductsApi/Count HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4"
}

{
    "count": 12
}

List

ProductsApi/List(?{page})
[OData Ready]
Field Type Description Constraint Object
key string API Key Required UUID
page number Page Number Optional Integer
POST /v1/ProductsApi/List HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4"
}

Products
[
    {
        "name": "Lawn Trimmer",
        "serial": "944514ef-9263-4978-905a-7028bd0f9e6a",
        "created": "2019-01-13T14:22:00+02:00",
        "custom": {
            "manufacturerNo": "D2-D1RFS-1",
            "sellOnline": false
        }
    },
    {
        "name": "Bowl",
        "serial": "09b07fd4-d873-49bb-8aa7-e2ec9f463dac",
        "created": "2019-01-13T18:47:01+02:00"
    }
]

Create

ProductsApi/Save
Field Type Description Constraint Object
key string API Key Required UUID
name string Product Name Optional
custom json Your Own JSON Optional
POST /v1/ProductsApi/Save HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "name": "Lawn Trimmer",
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "custom": {
        "manufacturerNo": "D2-D1RFS-1",
        "sellOnline": false
    }
}

201 : Product
{
        "name": "Lawn Trimmer",
        "serial": "944514ef-9263-4978-905a-7028bd0f9e6a",
        "created": "2019-01-13T14:22:00+02:00",
        "custom": {
            "manufacturerNo": "D2-D1RFS-1",
            "sellOnline": false
    }
}

Read

ProductsApi/Find(?{page})
Field Type Description Constraint Object
key string API Key Required UUID
serial string Product Serial Required UUID
page number Page Number Of Subscriptions Optional Integer
POST /v1/ProductsApi/Find HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial": "944514ef-9263-4978-905a-7028bd0f9e6a"
}

Product & Subscriptions
{
	"name": "Lawn Trimmer",
	"serial": "944514ef-9263-4978-905a-7028bd0f9e6a",
	"created": "2019-01-13T14:22:00+02:00",
	"subscriptions": [{
			"name": "John Doe",
			"commenced": "2019-01-13T18:54:00+02:00",
			"callbackOnModify": false,
			"created": "2019-01-13T18:51:51+02:00",
			"frequency": "Monthly",
			"action": "Renew",
			"custom": {
				"storeVisit": "2019-01-13T14:23:00+02:00"
			}
		},
		{
			"name": "698b2a63-3e11-42c9-adf8-b027c0143efa",
			"commenced": "2019-01-13T18:57:00+02:00",
			"callbackOnModify": false,
			"created": "2019-01-13T18:56:11+02:00",
			"frequency": "Weekly",
			"action": "Renew"
		}
	],
	"custom": {
		"manufacturerNo": "D2-D1RFS-1",
		"sellOnline": false
	}
}

Update

ProductsApi
Field Type Description Constraint Object
key string API Key Required UUID
serial string Product Serial Required UUID
name string Product Name Optional
custom json Your Own JSON Optional
PATCH /v1/ProductsApi HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "name": "Lawn Trimmer",
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial":"944514ef-9263-4978-905a-7028bd0f9e6a",
    "custom": {
    "manufacturerNo":"D2-D1RFS-1",
    "sellOnline": true
    }
}

204

Delete

ProductsApi/{serial}
Field Type Description Constraint Object
X-Api-Key string API Key Required UUID
serial string Product Serial Required UUID
DELETE /v1/ProductsApi/944514ef-9263-4978-905a-7028bd0f9e6a HTTP/1.1
Content-Type: application/json; charset=utf-8
X-Api-Key: 7ecaa17b-8afb-423d-a7fc-861147ecd5f4
204

Subscriptions

Endpoint Spec & Example Returns

Count

SubscriptionsApi/Count
Field Type Description Constraint Object
key string API Key Required UUID
serial string Product Serial Optional UUID
POST /v1/SubscriptionsApi/Count HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial": "944514ef-9263-4978-905a-7028bd0f9e6a"
}

{
    "count": 24
}

List

SubscriptionsApi/List(?{page})
[OData Ready]
Field Type Description Constraint Object
key string API Key Required UUID
serial string Product Serial Required UUID
page number Page Number Optional Integer
POST /v1/SubscriptionsApi/List HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial": "944514ef-9263-4978-905a-7028bd0f9e6a"
}

Subscriptions
[
    {
        "name": "John Doe",
        "commenced": "2019-01-20T22:03:00+02:00",
        "callbackOnModify": false,
        "created": "2019-01-20T22:00:44+02:00",
        "updated": "2019-01-20T22:03:08+02:00",
        "frequency": "Monthly",
        "action": "Renew",
        "keys": [
            {
                "name": "70419b0a-aba6-4fac-b875-ca3b9ac9f131",
                "serial": "70419b0a-aba6-4fac-b875-ca3b9ac9f131",
                "current": false,
                "commenced": "2019-01-20T22:03:00+02:00",
                "callbackOnModify": false,
                "created": "2019-01-20T22:00:44+02:00",
                "frequency": "Monthly",
                "action": "Renew"
            },
            {
                "name": "John Doe",
                "serial": "a8c5536c-6583-4042-b572-9fd994365e99",
                "current": true,
                "commenced": "2019-01-20T22:03:00+02:00",
                "callbackOnModify": false,
                "created": "2019-01-20T22:02:35+02:00",
                "updated": "2019-01-20T22:03:09+02:00",
                "frequency": "Monthly",
                "action": "Renew"
            }
        ]
    },
    {
        "name": "Another Subscription",
        "commenced": "2019-01-20T22:07:00+02:00",
        "callbackOnModify": false,
        "created": "2019-01-20T22:05:05+02:00",
        "frequency": "Monthly",
        "action": "Renew",
        "keys": [
            {
                "name": "Another Subscription",
                "serial": "a7f7b9c2-0e5c-431a-9708-919f3690a196",
                "current": true,
                "commenced": "2019-01-20T22:07:00+02:00",
                "callbackOnModify": false,
                "created": "2019-01-20T22:05:05+02:00",
                "frequency": "Monthly",
                "action": "Renew"
            }
        ]
    }
]

Create

SubscriptionsApi/Save
Field Type Description Constraint Object
key string API Key Required UUID
serial string Product Serial Required UUID
frequency string Intervals:
"Monthly", "Yearly", "Quarterly", "Biennially", "Lifetime", "Daily", "Hourly", "Weekly"
Required
action string Actions:
"Renew", "Disable", "Delete", "Extend"
Required
name string Subscription Name Optional
startFrom string Supports:
ISO 8601
Unix TS
Javascript Date
DateTimeOffset
Optional Date
callbackOnModify boolean Callback When Changed Optional
callbackUrl string Your Website Endpoint Optional Url
custom json Your Own JSON Optional
POST /v1/SubscriptionsApi/Save HTTP/1.1
Content-Type: application/json; charset=utf-8

{

    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial": "944514ef-9263-4978-905a-7028bd0f9e6a",
    "frequency": "Hourly",
    "action": "Disable",
    "name": "Some New Subscription",
    "startFrom": "2019-02-17T02:20:00+02:00",
    "callbackUrl": "https://mysite.com/backend",
    "callbackOnModify": false,
    "custom": {
        "myStuff": "here"
    }
}

201 : Key
{
    "name": "Some New Subscription",
    "custom": {
        "myStuff": "here"
    },
    "serial": "bd65df70-ce00-45f7-be93-94ffcecfc3a1",
    "current": true,
    "commenced": "2019-02-17T02:20:00+02:00",
    "callbackOnModify": false,
    "created": "2019-01-21T02:13:05+02:00",
    "frequency": "Hourly",
    "action": "Disable",
    "callbackUrl": "https://mysite.com/backend"
}

Read

SubscriptionsApi/Find
Field Type Description Constraint Object
key string API Key Required UUID
serial string Any Key Serial Required UUID
POST /v1/SubscriptionsApi/Find HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial": "bd65df70-ce00-45f7-be93-94ffcecfc3a1"
}

Subscription
{
    "name": "Some New Subscription",
    "callbackUrl": "https://mysite.com/backend",
    "custom": {
        "myStuff": "here"
    },
    "keys": [
        {
            "name": "Some New Subscription",
            "callbackUrl": "https://mysite.com/backend",
            "custom": {
                "myStuff": "here"
            },
            "serial": "bd65df70-ce00-45f7-be93-94ffcecfc3a1",
            "current": true,
            "commenced": "2019-02-17T02:20:00+02:00",
            "callbackOnModify": false,
            "created": "2019-01-21T02:13:05+02:00",
            "frequency": "Hourly",
            "action": "Disable"
        }
    ],
    "commenced": "2019-02-17T02:20:00+02:00",
    "callbackOnModify": false,
    "created": "2019-01-21T02:13:04+02:00",
    "frequency": "Hourly",
    "action": "Disable"
}

Update

SubscriptionsApi
Field Type Description Constraint Object
key string API Key Required UUID
serial string Any Key Serial Required UUID
frequency string Intervals:
"Monthly", "Yearly", "Quarterly", "Biennially", "Lifetime", "Daily", "Hourly", "Weekly"
Required
action string Actions:
"Renew", "Disable", "Delete", "Extend"
Required
name string Subscription Name Optional
startFrom string Supports:
ISO 8601
Unix TS
Javascript Date
DateTimeOffset
Optional Date
callbackOnModify boolean Callback When Changed Optional
callbackUrl string Your Website Endpoint Optional Url
custom json Your Own JSON Optional
PUT /v1/SubscriptionsApi/ HTTP/1.1
Content-Type: application/json; charset=utf-8

{

    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial": "bd65df70-ce00-45f7-be93-94ffcecfc3a1",
    "frequency": "Hourly",
    "action": "Delete",
    "name": "Some New Subscription",
    "startFrom": "2019-02-17T02:20:00+02:00",
    "callbackUrl": "https://mysite.com/backend",
    "callbackOnModify": true,
    "custom": {
        "myStuff": "changed"
    }
}

204

Delete

SubscriptionsApi/{serial}(?{keep})
Field Type Description Constraint Object
X-Api-Key string API Key Required UUID
serial string Any Key Serial Required UUID
keep boolean When set to 'true' Deletes Key instead of Subscription Optional
DELETE /v1/SubscriptionsApi/bd65df70-ce00-45f7-be93-94ffcecfc3a1 HTTP/1.1
Content-Type: application/json; charset=utf-8
X-Api-Key: 7ecaa17b-8afb-423d-a7fc-861147ecd5f4


NB: If you wish to delete subscriptions that lack keys, use a blank serial (i.e "00000000-0000-0000-0000-000000000000")
THIS WILL DELETE ALL SUBSCRIPTIONS THAT DON'T HAVE A SERIAL.

204

Disable

SubscriptionsApi/Disable
Field Type Description Constraint Object
key string API Key Required UUID
serial string Any Key Serial Required UUID
PATCH /v1/SubscriptionsApi/Disable HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial": "bd65df70-ce00-45f7-be93-94ffcecfc3a1"
}

204

Enable

SubscriptionsApi/Enable
Field Type Description Constraint Object
key string API Key Required UUID
serial string Any Key Serial Required UUID
PATCH /v1/SubscriptionsApi/Enable HTTP/1.1
Content-Type: application/json; charset=utf-8

{
    "key": "7ecaa17b-8afb-423d-a7fc-861147ecd5f4",
    "serial": "bd65df70-ce00-45f7-be93-94ffcecfc3a1"
}

204

Keys

Intended For Clients, Customers & Edge Devices

Endpoint Example Returns

Read

KeysApi/Find/{serial}
Field Type Description Constraint Object
serial string Key Serial Required UUID
GET /v1/KeysApi/Find/bd65df70-ce00-45f7-be93-94ffcecfc3a1 HTTP/1.1
Content-Type: application/json; charset=utf-8
Key
{
    "name": "Some New Subscription",
    "custom": {
        "SKU": "FOUNTAINPEN01",
        "Brand": "Parker",
        "Quantity": 4,
        "Discontinued": false
    },
    "serial": "bd65df70-ce00-45f7-be93-94ffcecfc3a1",
    "current": true,
    "commenced": "2019-02-17T02:20:00+02:00",
    "callbackOnModify": false,
    "created": "2019-01-21T02:13:05+02:00",
    "frequency": "Hourly",
    "action": "Disable",
    "callbackUrl": "https://mysite.com/backend"
}

Current

KeysApi/Current/{serial}
Field Type Description Constraint Object
serial string Key Serial Required UUID
GET /v1/KeysApi/Current/bd65df70-ce00-45f7-be93-94ffcecfc3a1 HTTP/1.1
Content-Type: application/json; charset=utf-8
{
    "current": true
}
{
    "current": false
}

Expiry

KeysApi/Expiry/{serial}
Field Type Description Constraint Object
serial string Key Serial Required UUID
GET /v1/KeysApi/Expiry/944514ef-9263-4978-905a-7028bd0f9e6a HTTP/1.1
Content-Type: application/json; charset=utf-8
{
    "expires": "2019-02-17T02:20:00+02:00",
    "time": "31.00:00:00"
}

Custom

KeysApi/Custom/{serial}
Field Type Description Constraint Object
serial string Key Serial Required UUID
GET /v1/KeysApi/Custom/944514ef-9263-4978-905a-7028bd0f9e6a HTTP/1.1
Content-Type: application/json; charset=utf-8
{
    "SKU": "FOUNTAINPEN01",
    "Brand": "Parker",
    "Quantity": 4,
    "Discontinued": false
}

Response Reference List

Code Type Reasons
200 OK Request Fulfilled
Return Requested Resource(s)
201 Created Resource Created Successfully
Request Completed : Resource(s)
202 Accepted Request Accepted For Further Processing
Resource To Be Deleted
204 Completed Request Completed (NFTR)
Resource Modified Successfully
304 Not Modified Resource Information Unchanged
No Update Necessary
410 Gone Resource Deleted
Resource(s) Recently Removed
402 Payment Required Subscription Upgrade Required
Tier Limit Reached
429 Too Many Requests Too Many Requests Within Short Time
Many Clients Using Same Public IP
400 Bad Request Variable Null or Invalid
Invalid Request
409 Conflict Resource With Variables Exists
Resource Name Taken
300 Ambigious Multiple Results Found
Empty Resource(s) Request
404 Not Found No Resource Found
No Such Route
412 Precondition Failed Request Doesn't Meet Requirements
Resource Missing Variables
406 Not Acceptable Resource Has Invalid Variables
Resource Data Incorrect
403 Forbidden Not Using HTTPS
Server Firewalled Resource
500 Internal Error Request Failed (Server Side)
Technical Problem (Try Again?)

Recipes

Arduino

1) Checking if serial is current

In these two examples we will be using an Arduino Ethernet Shield 2 to make GET requests to the server. Now because our given microcontroller doesn't have the requisite horse-power to handle an HTTPS request we will be doing it over simple port 80, HTTP. Observe that we are passing query parameter "default=false" in order to pass through HTTP requests. Sample serial: 63533594-b30c-430f-a6fd-7472d1829d0d used. We are also using the gold standard in JSON deserialization ArduinoJson (v6) on the microcontroller. You can use the handy calculator they have available online: https://arduinojson.org/v6/assistant to compute the DynamicJsonDocument size.

// #include <SPI.h>
#include <Ethernet2.h>
#include <ArduinoJson.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "keyserv.solutions";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 10, 48);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

// The response string we get back from the server
String response = "";

//Fetch "current" object from json
const size_t capacity = JSON_OBJECT_SIZE(1) + 10;

int l = 0;

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /v1/KeysApi/Current/63533594-b30c-430f-a6fd-7472d1829d0d?default=false HTTP/1.1");
    client.println("Host: keyserv.solutions");
    client.println("Connection: close");
    client.println();
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()
{
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    if (l > 0) {
      response += c;
    } else if (c == '{') {
      response += c;
      l = response.length();
    }
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    DynamicJsonDocument doc(capacity);
    DeserializationError error = deserializeJson(doc, response);

    // if no errors deserializing json:
    if (!error) {

      JsonObject obj = doc.as<JsonObject>();

      // if the response contains ["current": true]
      // therefore the key is currently valid:
      if (obj["current"] == true) {

        // switch on light
        digitalWrite(LED_BUILTIN, HIGH);
        Serial.println("\r\n-- LIGHT ON --");
      } else {
        digitalWrite(LED_BUILTIN, LOW);
        Serial.println("\r\n-- LIGHT OFF --");
      }

    } else Serial.println(error.c_str());

    // do nothing forevermore:
    while (true);
  }
}

And this is what the Arduino Serial console outputs:

connecting...
connected

disconnecting.
{"current":true}

-- LIGHT ON --

2) Checking the expiry of a serial
// #include <SPI.h>
#include <Ethernet2.h>
#include <ArduinoJson.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "keyserv.solutions";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 10, 48);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

// The response string we get back from the server
String response = "";

//Fetch "expires" and "time" objects from json
const size_t capacity = JSON_OBJECT_SIZE(2) + 62;

int l = 0;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /v1/KeysApi/Expiry/63533594-b30c-430f-a6fd-7472d1829d0d?default=false HTTP/1.1");
    client.println("Host: keyserv.solutions");
    client.println("Connection: close");
    client.println();
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()
{
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    if (l > 0) {
      response += c;
    } else if (c == '{') {
      response += c;
      l = response.length();
    }
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    DynamicJsonDocument doc(capacity);
    DeserializationError error = deserializeJson(doc, response);

    // if no errors deserializing json:
    if (!error) {
      JsonObject obj = doc.as<JsonObject>();
      Serial.println("Key expiration date: " + obj["expires"].as<String>());
      Serial.println("Time from now: " + obj["time"].as<String>());
    } else Serial.println(error.c_str());

    // do nothing forevermore:
    while (true);
  }
}

And the Serial console displaying the deserialized values:

connecting...
connected

disconnecting.
Key expires at: 2021-06-01T20:39:00+02:00
Time from now: 731.00:00:00

TypeScript

/* tslint:disable */
/* eslint-disable */
//----------------------
// <auto-generated>
//     Generated using the NSwag toolchain v13.0.6.0 (NJsonSchema v10.0.23.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------
// ReSharper disable InconsistentNaming

export class KeysApiClient {
    private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
    private baseUrl: string;
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;

    constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
        this.http = http ? http : <any>window;
        this.baseUrl = baseUrl ? baseUrl : "https://keyserv.solutions";
    }

    find(serial: string): Promise<KeyView | null> {
        let url_ = this.baseUrl + "/v1/KeysApi/Find/{serial}";
        if (serial === undefined || serial === null)
            throw new Error("The parameter 'serial' must be defined.");
        url_ = url_.replace("{serial}", encodeURIComponent("" + serial)); 
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <RequestInit>{
            method: "GET",
            headers: {
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processFind(_response);
        });
    }

    protected processFind(response: Response): Promise<KeyView | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = resultData200 ? KeyView.fromJS(resultData200) : <any>null;
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<KeyView | null>(<any>null);
    }

    current(serial: string): Promise<CurrentKey | null> {
        let url_ = this.baseUrl + "/v1/KeysApi/Current/{serial}";
        if (serial === undefined || serial === null)
            throw new Error("The parameter 'serial' must be defined.");
        url_ = url_.replace("{serial}", encodeURIComponent("" + serial)); 
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <RequestInit>{
            method: "GET",
            headers: {
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processCurrent(_response);
        });
    }

    protected processCurrent(response: Response): Promise<CurrentKey | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = resultData200 ? CurrentKey.fromJS(resultData200) : <any>null;
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<CurrentKey | null>(<any>null);
    }

    custom(serial: string): Promise<FileResponse> {
        let url_ = this.baseUrl + "/v1/KeysApi/Custom/{serial}";
        if (serial === undefined || serial === null)
            throw new Error("The parameter 'serial' must be defined.");
        url_ = url_.replace("{serial}", encodeURIComponent("" + serial)); 
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <RequestInit>{
            method: "GET",
            headers: {
                "Accept": "application/octet-stream"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processCustom(_response);
        });
    }

    protected processCustom(response: Response): Promise<FileResponse> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200 || status === 206) {
            const contentDisposition = response.headers ? response.headers.get("content-disposition") : undefined;
            const fileNameMatch = contentDisposition ? /filename="?([^"]*?)"?(;|$)/g.exec(contentDisposition) : undefined;
            const fileName = fileNameMatch && fileNameMatch.length > 1 ? fileNameMatch[1] : undefined;
            return response.blob().then(blob => { return { fileName: fileName, data: blob, status: status, headers: _headers }; });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<FileResponse>(<any>null);
    }

    expiry(serial: string): Promise<Expiry | null> {
        let url_ = this.baseUrl + "/v1/KeysApi/Expiry/{serial}";
        if (serial === undefined || serial === null)
            throw new Error("The parameter 'serial' must be defined.");
        url_ = url_.replace("{serial}", encodeURIComponent("" + serial)); 
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <RequestInit>{
            method: "GET",
            headers: {
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processExpiry(_response);
        });
    }

    protected processExpiry(response: Response): Promise<Expiry | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = resultData200 ? Expiry.fromJS(resultData200) : <any>null;
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<Expiry | null>(<any>null);
    }
}

export class ProductsApiClient {
    private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
    private baseUrl: string;
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;

    constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
        this.http = http ? http : <any>window;
        this.baseUrl = baseUrl ? baseUrl : "https://keyserv.solutions";
    }

    count(apiCreds: ApiKey | null): Promise<CountOf | null> {
        let url_ = this.baseUrl + "/v1/ProductsApi/Count";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processCount(_response);
        });
    }

    protected processCount(response: Response): Promise<CountOf | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = resultData200 ? CountOf.fromJS(resultData200) : <any>null;
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<CountOf | null>(<any>null);
    }

    find(page: number | null, apiCreds: FindCredentials | null): Promise<ProductView | null> {
        let url_ = this.baseUrl + "/v1/ProductsApi/Find?";
        if (page === undefined)
            throw new Error("The parameter 'page' must be defined.");
        else
            url_ += "page=" + encodeURIComponent("" + page) + "&"; 
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processFind(_response);
        });
    }

    protected processFind(response: Response): Promise<ProductView | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = resultData200 ? ProductView.fromJS(resultData200) : <any>null;
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<ProductView | null>(<any>null);
    }

    list(page: number | null, apiCreds: ApiKey | null): Promise<ProductView[] | null> {
        let url_ = this.baseUrl + "/v1/ProductsApi/List?";
        if (page === undefined)
            throw new Error("The parameter 'page' must be defined.");
        else
            url_ += "page=" + encodeURIComponent("" + page) + "&"; 
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processList(_response);
        });
    }

    protected processList(response: Response): Promise<ProductView[] | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            if (Array.isArray(resultData200)) {
                result200 = [] as any;
                for (let item of resultData200)
                    result200!.push(ProductView.fromJS(item));
            }
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<ProductView[] | null>(<any>null);
    }

    patchProduct(productJson: ProductCreateModify | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/ProductsApi";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(productJson);

        let options_ = <RequestInit>{
            body: content_,
            method: "PATCH",
            headers: {
                "Content-Type": "application/json",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processPatchProduct(_response);
        });
    }

    protected processPatchProduct(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    patchProduct2(productJson: ProductCreateModify | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/ProductsApi";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(productJson);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processPatchProduct2(_response);
        });
    }

    protected processPatchProduct2(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    save(productJson: ProductCreateModify | null): Promise<ProductView | null> {
        let url_ = this.baseUrl + "/v1/ProductsApi/Save";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(productJson);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processSave(_response);
        });
    }

    protected processSave(response: Response): Promise<ProductView | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 201) {
            return response.text().then((_responseText) => {
            let result201: any = null;
            let resultData201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result201 = resultData201 ? ProductView.fromJS(resultData201) : <any>null;
            return result201;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<ProductView | null>(<any>null);
    }

    deleteProduct(x_Api_Key: string, serial: string): Promise<void> {
        let url_ = this.baseUrl + "/v1/ProductsApi/{serial}";
        if (serial === undefined || serial === null)
            throw new Error("The parameter 'serial' must be defined.");
        url_ = url_.replace("{serial}", encodeURIComponent("" + serial)); 
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <RequestInit>{
            method: "DELETE",
            headers: {
                "X-Api-Key": x_Api_Key !== undefined && x_Api_Key !== null ? "" + x_Api_Key : "",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processDeleteProduct(_response);
        });
    }

    protected processDeleteProduct(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    deleteProduct2(x_Api_Key: string, serial: string): Promise<void> {
        let url_ = this.baseUrl + "/v1/ProductsApi/{serial}";
        if (serial === undefined || serial === null)
            throw new Error("The parameter 'serial' must be defined.");
        url_ = url_.replace("{serial}", encodeURIComponent("" + serial)); 
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <RequestInit>{
            method: "POST",
            headers: {
                "X-Api-Key": x_Api_Key !== undefined && x_Api_Key !== null ? "" + x_Api_Key : "",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processDeleteProduct2(_response);
        });
    }

    protected processDeleteProduct2(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }
}

export class SubscriptionsApiClient {
    private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
    private baseUrl: string;
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;

    constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
        this.http = http ? http : <any>window;
        this.baseUrl = baseUrl ? baseUrl : "https://keyserv.solutions";
    }

    count(apiCreds: ApiCredentials | null): Promise<CountOf | null> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/Count";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processCount(_response);
        });
    }

    protected processCount(response: Response): Promise<CountOf | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = resultData200 ? CountOf.fromJS(resultData200) : <any>null;
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<CountOf | null>(<any>null);
    }

    find(apiCreds: FindCredentials | null): Promise<SubscriptionView | null> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/Find";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processFind(_response);
        });
    }

    protected processFind(response: Response): Promise<SubscriptionView | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = resultData200 ? SubscriptionView.fromJS(resultData200) : <any>null;
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<SubscriptionView | null>(<any>null);
    }

    list(page: number | null, apiCreds: FindCredentials | null): Promise<SubscriptionView[] | null> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/List?";
        if (page === undefined)
            throw new Error("The parameter 'page' must be defined.");
        else
            url_ += "page=" + encodeURIComponent("" + page) + "&"; 
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processList(_response);
        });
    }

    protected processList(response: Response): Promise<SubscriptionView[] | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 200) {
            return response.text().then((_responseText) => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            if (Array.isArray(resultData200)) {
                result200 = [] as any;
                for (let item of resultData200)
                    result200!.push(SubscriptionView.fromJS(item));
            }
            return result200;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<SubscriptionView[] | null>(<any>null);
    }

    putSubscription(subscriptionJson: SubscriptionCreateModify | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(subscriptionJson);

        let options_ = <RequestInit>{
            body: content_,
            method: "PUT",
            headers: {
                "Content-Type": "application/json",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processPutSubscription(_response);
        });
    }

    protected processPutSubscription(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    putSubscription2(subscriptionJson: SubscriptionCreateModify | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(subscriptionJson);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processPutSubscription2(_response);
        });
    }

    protected processPutSubscription2(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    disable(apiCreds: FindCredentials | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/Disable";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "PATCH",
            headers: {
                "Content-Type": "application/json",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processDisable(_response);
        });
    }

    protected processDisable(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    disable2(apiCreds: FindCredentials | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/Disable";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processDisable2(_response);
        });
    }

    protected processDisable2(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    enable(apiCreds: FindCredentials | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/Enable";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "PATCH",
            headers: {
                "Content-Type": "application/json",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processEnable(_response);
        });
    }

    protected processEnable(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    enable2(apiCreds: FindCredentials | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/Enable";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(apiCreds);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processEnable2(_response);
        });
    }

    protected processEnable2(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    save(subscriptionJson: SubscriptionCreateModify | null): Promise<KeyView | null> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/Save";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(subscriptionJson);

        let options_ = <RequestInit>{
            body: content_,
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processSave(_response);
        });
    }

    protected processSave(response: Response): Promise<KeyView | null> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 201) {
            return response.text().then((_responseText) => {
            let result201: any = null;
            let resultData201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result201 = resultData201 ? KeyView.fromJS(resultData201) : <any>null;
            return result201;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<KeyView | null>(<any>null);
    }

    deleteSubscription(x_Api_Key: string, serial: string, keep: boolean | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/{serial}?";
        if (serial === undefined || serial === null)
            throw new Error("The parameter 'serial' must be defined.");
        url_ = url_.replace("{serial}", encodeURIComponent("" + serial)); 
        if (keep === undefined)
            throw new Error("The parameter 'keep' must be defined.");
        else
            url_ += "keep=" + encodeURIComponent("" + keep) + "&"; 
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <RequestInit>{
            method: "DELETE",
            headers: {
                "X-Api-Key": x_Api_Key !== undefined && x_Api_Key !== null ? "" + x_Api_Key : "",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processDeleteSubscription(_response);
        });
    }

    protected processDeleteSubscription(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }

    deleteSubscription2(x_Api_Key: string, serial: string, keep: boolean | null): Promise<void> {
        let url_ = this.baseUrl + "/v1/SubscriptionsApi/{serial}?";
        if (serial === undefined || serial === null)
            throw new Error("The parameter 'serial' must be defined.");
        url_ = url_.replace("{serial}", encodeURIComponent("" + serial)); 
        if (keep === undefined)
            throw new Error("The parameter 'keep' must be defined.");
        else
            url_ += "keep=" + encodeURIComponent("" + keep) + "&"; 
        url_ = url_.replace(/[?&]$/, "");

        let options_ = <RequestInit>{
            method: "POST",
            headers: {
                "X-Api-Key": x_Api_Key !== undefined && x_Api_Key !== null ? "" + x_Api_Key : "",
            }
        };

        return this.http.fetch(url_, options_).then((_response: Response) => {
            return this.processDeleteSubscription2(_response);
        });
    }

    protected processDeleteSubscription2(response: Response): Promise<void> {
        const status = response.status;
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
        if (status === 204) {
            return response.text().then((_responseText) => {
            return;
            });
        } else if (status !== 200 && status !== 204) {
            return response.text().then((_responseText) => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            });
        }
        return Promise.resolve<void>(<any>null);
    }
}

export class KeyView implements IKeyView {
    serial?: string;
    current?: boolean;
    commenced!: Date;
    callbackOnModify!: boolean;
    created?: Date;
    updated?: Date | undefined;
    frequency!: string;
    action!: string;
    name?: string | undefined;
    callbackUrl?: string | undefined;
    custom?: any | undefined;

    constructor(data?: IKeyView) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.serial = data["serial"];
            this.current = data["current"];
            this.commenced = data["commenced"] ? new Date(data["commenced"].toString()) : <any>undefined;
            this.callbackOnModify = data["callbackOnModify"];
            this.created = data["created"] ? new Date(data["created"].toString()) : <any>undefined;
            this.updated = data["updated"] ? new Date(data["updated"].toString()) : <any>undefined;
            this.frequency = data["frequency"];
            this.action = data["action"];
            this.name = data["name"];
            this.callbackUrl = data["callbackUrl"];
            this.custom = data["custom"];
        }
    }

    static fromJS(data: any): KeyView {
        data = typeof data === 'object' ? data : {};
        let result = new KeyView();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["serial"] = this.serial;
        data["current"] = this.current;
        data["commenced"] = this.commenced ? this.commenced.toISOString() : <any>undefined;
        data["callbackOnModify"] = this.callbackOnModify;
        data["created"] = this.created ? this.created.toISOString() : <any>undefined;
        data["updated"] = this.updated ? this.updated.toISOString() : <any>undefined;
        data["frequency"] = this.frequency;
        data["action"] = this.action;
        data["name"] = this.name;
        data["callbackUrl"] = this.callbackUrl;
        data["custom"] = this.custom;
        return data; 
    }
}

export interface IKeyView {
    serial?: string;
    current?: boolean;
    commenced: Date;
    callbackOnModify: boolean;
    created?: Date;
    updated?: Date | undefined;
    frequency: string;
    action: string;
    name?: string | undefined;
    callbackUrl?: string | undefined;
    custom?: any | undefined;
}

export class CurrentKey implements ICurrentKey {
    current?: boolean;

    constructor(data?: ICurrentKey) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.current = data["current"];
        }
    }

    static fromJS(data: any): CurrentKey {
        data = typeof data === 'object' ? data : {};
        let result = new CurrentKey();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["current"] = this.current;
        return data; 
    }
}

export interface ICurrentKey {
    current?: boolean;
}

export class Expiry implements IExpiry {
    expires?: Date;
    time?: string;

    constructor(data?: IExpiry) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.expires = data["expires"] ? new Date(data["expires"].toString()) : <any>undefined;
            this.time = data["time"];
        }
    }

    static fromJS(data: any): Expiry {
        data = typeof data === 'object' ? data : {};
        let result = new Expiry();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["expires"] = this.expires ? this.expires.toISOString() : <any>undefined;
        data["time"] = this.time;
        return data; 
    }
}

export interface IExpiry {
    expires?: Date;
    time?: string;
}

export class CountOf implements ICountOf {
    count?: number;

    constructor(data?: ICountOf) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.count = data["count"];
        }
    }

    static fromJS(data: any): CountOf {
        data = typeof data === 'object' ? data : {};
        let result = new CountOf();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["count"] = this.count;
        return data; 
    }
}

export interface ICountOf {
    count?: number;
}

export class ApiKey implements IApiKey {
    key?: string;

    constructor(data?: IApiKey) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.key = data["key"];
        }
    }

    static fromJS(data: any): ApiKey {
        data = typeof data === 'object' ? data : {};
        let result = new ApiKey();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["key"] = this.key;
        return data; 
    }
}

export interface IApiKey {
    key?: string;
}

export class ProductView implements IProductView {
    name?: string | undefined;
    serial?: string;
    created?: Date;
    updated?: Date | undefined;
    custom?: any | undefined;
    subscriptions?: SubscriptionView[] | undefined;

    constructor(data?: IProductView) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.name = data["name"];
            this.serial = data["serial"];
            this.created = data["created"] ? new Date(data["created"].toString()) : <any>undefined;
            this.updated = data["updated"] ? new Date(data["updated"].toString()) : <any>undefined;
            this.custom = data["custom"];
            if (Array.isArray(data["subscriptions"])) {
                this.subscriptions = [] as any;
                for (let item of data["subscriptions"])
                    this.subscriptions!.push(SubscriptionView.fromJS(item));
            }
        }
    }

    static fromJS(data: any): ProductView {
        data = typeof data === 'object' ? data : {};
        let result = new ProductView();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["name"] = this.name;
        data["serial"] = this.serial;
        data["created"] = this.created ? this.created.toISOString() : <any>undefined;
        data["updated"] = this.updated ? this.updated.toISOString() : <any>undefined;
        data["custom"] = this.custom;
        if (Array.isArray(this.subscriptions)) {
            data["subscriptions"] = [];
            for (let item of this.subscriptions)
                data["subscriptions"].push(item.toJSON());
        }
        return data; 
    }
}

export interface IProductView {
    name?: string | undefined;
    serial?: string;
    created?: Date;
    updated?: Date | undefined;
    custom?: any | undefined;
    subscriptions?: SubscriptionView[] | undefined;
}

export class SubscriptionView implements ISubscriptionView {
    commenced!: Date;
    callbackOnModify!: boolean;
    created?: Date;
    updated?: Date | undefined;
    frequency!: string;
    action!: string;
    name?: string | undefined;
    callbackUrl?: string | undefined;
    custom?: any | undefined;
    keys?: KeyView[] | undefined;

    constructor(data?: ISubscriptionView) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.commenced = data["commenced"] ? new Date(data["commenced"].toString()) : <any>undefined;
            this.callbackOnModify = data["callbackOnModify"];
            this.created = data["created"] ? new Date(data["created"].toString()) : <any>undefined;
            this.updated = data["updated"] ? new Date(data["updated"].toString()) : <any>undefined;
            this.frequency = data["frequency"];
            this.action = data["action"];
            this.name = data["name"];
            this.callbackUrl = data["callbackUrl"];
            this.custom = data["custom"];
            if (Array.isArray(data["keys"])) {
                this.keys = [] as any;
                for (let item of data["keys"])
                    this.keys!.push(KeyView.fromJS(item));
            }
        }
    }

    static fromJS(data: any): SubscriptionView {
        data = typeof data === 'object' ? data : {};
        let result = new SubscriptionView();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["commenced"] = this.commenced ? this.commenced.toISOString() : <any>undefined;
        data["callbackOnModify"] = this.callbackOnModify;
        data["created"] = this.created ? this.created.toISOString() : <any>undefined;
        data["updated"] = this.updated ? this.updated.toISOString() : <any>undefined;
        data["frequency"] = this.frequency;
        data["action"] = this.action;
        data["name"] = this.name;
        data["callbackUrl"] = this.callbackUrl;
        data["custom"] = this.custom;
        if (Array.isArray(this.keys)) {
            data["keys"] = [];
            for (let item of this.keys)
                data["keys"].push(item.toJSON());
        }
        return data; 
    }
}

export interface ISubscriptionView {
    commenced: Date;
    callbackOnModify: boolean;
    created?: Date;
    updated?: Date | undefined;
    frequency: string;
    action: string;
    name?: string | undefined;
    callbackUrl?: string | undefined;
    custom?: any | undefined;
    keys?: KeyView[] | undefined;
}

export class FindCredentials implements IFindCredentials {
    key?: string;
    serial?: string;

    constructor(data?: IFindCredentials) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.key = data["key"];
            this.serial = data["serial"];
        }
    }

    static fromJS(data: any): FindCredentials {
        data = typeof data === 'object' ? data : {};
        let result = new FindCredentials();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["key"] = this.key;
        data["serial"] = this.serial;
        return data; 
    }
}

export interface IFindCredentials {
    key?: string;
    serial?: string;
}

export class ProductCreateModify implements IProductCreateModify {
    key?: string;
    serial?: string | undefined;
    name?: string | undefined;
    custom?: any | undefined;

    constructor(data?: IProductCreateModify) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.key = data["key"];
            this.serial = data["serial"];
            this.name = data["name"];
            this.custom = data["custom"];
        }
    }

    static fromJS(data: any): ProductCreateModify {
        data = typeof data === 'object' ? data : {};
        let result = new ProductCreateModify();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["key"] = this.key;
        data["serial"] = this.serial;
        data["name"] = this.name;
        data["custom"] = this.custom;
        return data; 
    }
}

export interface IProductCreateModify {
    key?: string;
    serial?: string | undefined;
    name?: string | undefined;
    custom?: any | undefined;
}

export class ApiCredentials implements IApiCredentials {
    key?: string;
    serial?: string | undefined;

    constructor(data?: IApiCredentials) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.key = data["key"];
            this.serial = data["serial"];
        }
    }

    static fromJS(data: any): ApiCredentials {
        data = typeof data === 'object' ? data : {};
        let result = new ApiCredentials();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["key"] = this.key;
        data["serial"] = this.serial;
        return data; 
    }
}

export interface IApiCredentials {
    key?: string;
    serial?: string | undefined;
}

export class SubscriptionCreateModify implements ISubscriptionCreateModify {
    frequency!: string;
    action!: string;
    name?: string | undefined;
    callbackUrl?: string | undefined;
    key?: string;
    serial?: string;
    custom?: any | undefined;
    startFrom?: string | undefined;
    callbackOnModify?: boolean | undefined;

    constructor(data?: ISubscriptionCreateModify) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(data?: any) {
        if (data) {
            this.frequency = data["frequency"];
            this.action = data["action"];
            this.name = data["name"];
            this.callbackUrl = data["callbackUrl"];
            this.key = data["key"];
            this.serial = data["serial"];
            this.custom = data["custom"];
            this.startFrom = data["startFrom"];
            this.callbackOnModify = data["callbackOnModify"];
        }
    }

    static fromJS(data: any): SubscriptionCreateModify {
        data = typeof data === 'object' ? data : {};
        let result = new SubscriptionCreateModify();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["frequency"] = this.frequency;
        data["action"] = this.action;
        data["name"] = this.name;
        data["callbackUrl"] = this.callbackUrl;
        data["key"] = this.key;
        data["serial"] = this.serial;
        data["custom"] = this.custom;
        data["startFrom"] = this.startFrom;
        data["callbackOnModify"] = this.callbackOnModify;
        return data; 
    }
}

export interface ISubscriptionCreateModify {
    frequency: string;
    action: string;
    name?: string | undefined;
    callbackUrl?: string | undefined;
    key?: string;
    serial?: string;
    custom?: any | undefined;
    startFrom?: string | undefined;
    callbackOnModify?: boolean | undefined;
}

export interface FileResponse {
    data: Blob;
    status: number;
    fileName?: string;
    headers?: { [name: string]: any };
}

export class ApiException extends Error {
    message: string;
    status: number; 
    response: string; 
    headers: { [key: string]: any; };
    result: any; 

    constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) {
        super();

        this.message = message;
        this.status = status;
        this.response = response;
        this.headers = headers;
        this.result = result;
    }

    protected isApiException = true;

    static isApiException(obj: any): obj is ApiException {
        return obj.isApiException === true;
    }
}

function throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any {
    if (result !== null && result !== undefined)
        throw result;
    else
        throw new ApiException(message, status, response, headers, null);
}

.Net C#

//----------------------
// <auto-generated>
//     Generated using the NSwag toolchain v13.0.6.0 (NJsonSchema v10.0.23.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------

#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ...
#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..."

namespace MyNamespace
{
    using System = global::System;
    
    [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.0.6.0 (NJsonSchema v10.0.23.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class KeysApiClient 
    {
        private string _baseUrl = "https://keyserv.solutions";
        private System.Net.Http.HttpClient _httpClient;
        private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
    
        public KeysApiClient(System.Net.Http.HttpClient httpClient)
        {
            _httpClient = httpClient; 
            _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(() => 
            {
                var settings = new Newtonsoft.Json.JsonSerializerSettings();
                UpdateJsonSerializerSettings(settings);
                return settings;
            });
        }
    
        public string BaseUrl 
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }
    
        protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
    
        partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
        partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
        partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
        partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<KeyView> FindAsync(System.Guid serial)
        {
            return FindAsync(serial, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<KeyView> FindAsync(System.Guid serial, System.Threading.CancellationToken cancellationToken)
        {
            if (serial == null)
                throw new System.ArgumentNullException("serial");
    
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/KeysApi/Find/{serial}");
            urlBuilder_.Replace("{serial}", System.Uri.EscapeDataString(ConvertToString(serial, System.Globalization.CultureInfo.InvariantCulture)));
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    request_.Method = new System.Net.Http.HttpMethod("GET");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<KeyView>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(KeyView);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<CurrentKey> CurrentAsync(System.Guid serial)
        {
            return CurrentAsync(serial, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<CurrentKey> CurrentAsync(System.Guid serial, System.Threading.CancellationToken cancellationToken)
        {
            if (serial == null)
                throw new System.ArgumentNullException("serial");
    
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/KeysApi/Current/{serial}");
            urlBuilder_.Replace("{serial}", System.Uri.EscapeDataString(ConvertToString(serial, System.Globalization.CultureInfo.InvariantCulture)));
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    request_.Method = new System.Net.Http.HttpMethod("GET");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<CurrentKey>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(CurrentKey);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<FileResponse> CustomAsync(System.Guid serial)
        {
            return CustomAsync(serial, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<FileResponse> CustomAsync(System.Guid serial, System.Threading.CancellationToken cancellationToken)
        {
            if (serial == null)
                throw new System.ArgumentNullException("serial");
    
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/KeysApi/Custom/{serial}");
            urlBuilder_.Replace("{serial}", System.Uri.EscapeDataString(ConvertToString(serial, System.Globalization.CultureInfo.InvariantCulture)));
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    request_.Method = new System.Net.Http.HttpMethod("GET");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/octet-stream"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200" || status_ == "206") 
                        {
                            var responseStream_ = response_.Content == null ? System.IO.Stream.Null : await response_.Content.ReadAsStreamAsync().ConfigureAwait(false);
                            var fileResponse_ = new FileResponse((int)response_.StatusCode, headers_, responseStream_, null, response_); 
                            client_ = null; response_ = null; // response and client are disposed by FileResponse
                            return fileResponse_;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(FileResponse);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<Expiry> ExpiryAsync(System.Guid serial)
        {
            return ExpiryAsync(serial, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<Expiry> ExpiryAsync(System.Guid serial, System.Threading.CancellationToken cancellationToken)
        {
            if (serial == null)
                throw new System.ArgumentNullException("serial");
    
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/KeysApi/Expiry/{serial}");
            urlBuilder_.Replace("{serial}", System.Uri.EscapeDataString(ConvertToString(serial, System.Globalization.CultureInfo.InvariantCulture)));
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    request_.Method = new System.Net.Http.HttpMethod("GET");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<Expiry>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(Expiry);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        protected struct ObjectResponseResult<T>
        {
            public ObjectResponseResult(T responseObject, string responseText)
            {
                this.Object = responseObject;
                this.Text = responseText;
            }
    
            public T Object { get; }
    
            public string Text { get; }
        }
    
        public bool ReadResponseAsString { get; set; }
        
        protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
        {
            if (response == null || response.Content == null)
            {
                return new ObjectResponseResult<T>(default(T), string.Empty);
            }
        
            if (ReadResponseAsString)
            {
                var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                try
                {
                    var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
                    return new ObjectResponseResult<T>(typedBody, responseText);
                }
                catch (Newtonsoft.Json.JsonException exception)
                {
                    var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
                    throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
                }
            }
            else
            {
                try
                {
                    using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    using (var streamReader = new System.IO.StreamReader(responseStream))
                    using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
                    {
                        var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
                        var typedBody = serializer.Deserialize<T>(jsonTextReader);
                        return new ObjectResponseResult<T>(typedBody, string.Empty);
                    }
                }
                catch (Newtonsoft.Json.JsonException exception)
                {
                    var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
                    throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
                }
            }
        }
    
        private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
        {
            if (value is System.Enum)
            {
                string name = System.Enum.GetName(value.GetType(), value);
                if (name != null)
                {
                    var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
                    if (field != null)
                    {
                        var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute)) 
                            as System.Runtime.Serialization.EnumMemberAttribute;
                        if (attribute != null)
                        {
                            return attribute.Value != null ? attribute.Value : name;
                        }
                    }
                }
            }
            else if (value is bool) {
                return System.Convert.ToString(value, cultureInfo).ToLowerInvariant();
            }
            else if (value is byte[])
            {
                return System.Convert.ToBase64String((byte[]) value);
            }
            else if (value != null && value.GetType().IsArray)
            {
                var array = System.Linq.Enumerable.OfType<object>((System.Array) value);
                return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
            }
        
            return System.Convert.ToString(value, cultureInfo);
        }
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.0.6.0 (NJsonSchema v10.0.23.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class ProductsApiClient 
    {
        private string _baseUrl = "https://keyserv.solutions";
        private System.Net.Http.HttpClient _httpClient;
        private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
    
        public ProductsApiClient(System.Net.Http.HttpClient httpClient)
        {
            _httpClient = httpClient; 
            _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(() => 
            {
                var settings = new Newtonsoft.Json.JsonSerializerSettings();
                UpdateJsonSerializerSettings(settings);
                return settings;
            });
        }
    
        public string BaseUrl 
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }
    
        protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
    
        partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
        partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
        partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
        partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<CountOf> CountAsync(ApiKey apiCreds)
        {
            return CountAsync(apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<CountOf> CountAsync(ApiKey apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/ProductsApi/Count");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<CountOf>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(CountOf);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<ProductView> FindAsync(int? page, FindCredentials apiCreds)
        {
            return FindAsync(page, apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<ProductView> FindAsync(int? page, FindCredentials apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/ProductsApi/Find?");
            urlBuilder_.Append(System.Uri.EscapeDataString("page") + "=").Append(System.Uri.EscapeDataString(page != null ? ConvertToString(page, System.Globalization.CultureInfo.InvariantCulture) : "")).Append("&");
            urlBuilder_.Length--;
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<ProductView>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(ProductView);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ProductView>> ListAsync(int? page, ApiKey apiCreds)
        {
            return ListAsync(page, apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ProductView>> ListAsync(int? page, ApiKey apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/ProductsApi/List?");
            urlBuilder_.Append(System.Uri.EscapeDataString("page") + "=").Append(System.Uri.EscapeDataString(page != null ? ConvertToString(page, System.Globalization.CultureInfo.InvariantCulture) : "")).Append("&");
            urlBuilder_.Length--;
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<ProductView>>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(System.Collections.Generic.ICollection<ProductView>);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task PatchProductAsync(ProductCreateModify productJson)
        {
            return PatchProductAsync(productJson, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task PatchProductAsync(ProductCreateModify productJson, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/ProductsApi");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(productJson, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("PATCH");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task PatchProduct2Async(ProductCreateModify productJson)
        {
            return PatchProduct2Async(productJson, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task PatchProduct2Async(ProductCreateModify productJson, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/ProductsApi");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(productJson, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<ProductView> SaveAsync(ProductCreateModify productJson)
        {
            return SaveAsync(productJson, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<ProductView> SaveAsync(ProductCreateModify productJson, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/ProductsApi/Save");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(productJson, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "201") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<ProductView>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(ProductView);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task DeleteProductAsync(System.Guid x_Api_Key, System.Guid serial)
        {
            return DeleteProductAsync(x_Api_Key, serial, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task DeleteProductAsync(System.Guid x_Api_Key, System.Guid serial, System.Threading.CancellationToken cancellationToken)
        {
            if (serial == null)
                throw new System.ArgumentNullException("serial");
    
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/ProductsApi/{serial}");
            urlBuilder_.Replace("{serial}", System.Uri.EscapeDataString(ConvertToString(serial, System.Globalization.CultureInfo.InvariantCulture)));
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    if (x_Api_Key == null)
                        throw new System.ArgumentNullException("x_Api_Key");
                    request_.Headers.TryAddWithoutValidation("X-Api-Key", ConvertToString(x_Api_Key, System.Globalization.CultureInfo.InvariantCulture));
                    request_.Method = new System.Net.Http.HttpMethod("DELETE");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task DeleteProduct2Async(System.Guid x_Api_Key, System.Guid serial)
        {
            return DeleteProduct2Async(x_Api_Key, serial, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task DeleteProduct2Async(System.Guid x_Api_Key, System.Guid serial, System.Threading.CancellationToken cancellationToken)
        {
            if (serial == null)
                throw new System.ArgumentNullException("serial");
    
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/ProductsApi/{serial}");
            urlBuilder_.Replace("{serial}", System.Uri.EscapeDataString(ConvertToString(serial, System.Globalization.CultureInfo.InvariantCulture)));
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    if (x_Api_Key == null)
                        throw new System.ArgumentNullException("x_Api_Key");
                    request_.Headers.TryAddWithoutValidation("X-Api-Key", ConvertToString(x_Api_Key, System.Globalization.CultureInfo.InvariantCulture));
                    request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json");
                    request_.Method = new System.Net.Http.HttpMethod("POST");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        protected struct ObjectResponseResult<T>
        {
            public ObjectResponseResult(T responseObject, string responseText)
            {
                this.Object = responseObject;
                this.Text = responseText;
            }
    
            public T Object { get; }
    
            public string Text { get; }
        }
    
        public bool ReadResponseAsString { get; set; }
        
        protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
        {
            if (response == null || response.Content == null)
            {
                return new ObjectResponseResult<T>(default(T), string.Empty);
            }
        
            if (ReadResponseAsString)
            {
                var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                try
                {
                    var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
                    return new ObjectResponseResult<T>(typedBody, responseText);
                }
                catch (Newtonsoft.Json.JsonException exception)
                {
                    var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
                    throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
                }
            }
            else
            {
                try
                {
                    using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    using (var streamReader = new System.IO.StreamReader(responseStream))
                    using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
                    {
                        var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
                        var typedBody = serializer.Deserialize<T>(jsonTextReader);
                        return new ObjectResponseResult<T>(typedBody, string.Empty);
                    }
                }
                catch (Newtonsoft.Json.JsonException exception)
                {
                    var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
                    throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
                }
            }
        }
    
        private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
        {
            if (value is System.Enum)
            {
                string name = System.Enum.GetName(value.GetType(), value);
                if (name != null)
                {
                    var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
                    if (field != null)
                    {
                        var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute)) 
                            as System.Runtime.Serialization.EnumMemberAttribute;
                        if (attribute != null)
                        {
                            return attribute.Value != null ? attribute.Value : name;
                        }
                    }
                }
            }
            else if (value is bool) {
                return System.Convert.ToString(value, cultureInfo).ToLowerInvariant();
            }
            else if (value is byte[])
            {
                return System.Convert.ToBase64String((byte[]) value);
            }
            else if (value != null && value.GetType().IsArray)
            {
                var array = System.Linq.Enumerable.OfType<object>((System.Array) value);
                return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
            }
        
            return System.Convert.ToString(value, cultureInfo);
        }
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.0.6.0 (NJsonSchema v10.0.23.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class SubscriptionsApiClient 
    {
        private string _baseUrl = "https://keyserv.solutions";
        private System.Net.Http.HttpClient _httpClient;
        private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
    
        public SubscriptionsApiClient(System.Net.Http.HttpClient httpClient)
        {
            _httpClient = httpClient; 
            _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(() => 
            {
                var settings = new Newtonsoft.Json.JsonSerializerSettings();
                UpdateJsonSerializerSettings(settings);
                return settings;
            });
        }
    
        public string BaseUrl 
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }
    
        protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
    
        partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
        partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
        partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
        partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<CountOf> CountAsync(ApiCredentials apiCreds)
        {
            return CountAsync(apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<CountOf> CountAsync(ApiCredentials apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/Count");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<CountOf>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(CountOf);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<SubscriptionView> FindAsync(FindCredentials apiCreds)
        {
            return FindAsync(apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<SubscriptionView> FindAsync(FindCredentials apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/Find");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<SubscriptionView>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(SubscriptionView);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<System.Collections.Generic.ICollection<SubscriptionView>> ListAsync(int? page, FindCredentials apiCreds)
        {
            return ListAsync(page, apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<SubscriptionView>> ListAsync(int? page, FindCredentials apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/List?");
            urlBuilder_.Append(System.Uri.EscapeDataString("page") + "=").Append(System.Uri.EscapeDataString(page != null ? ConvertToString(page, System.Globalization.CultureInfo.InvariantCulture) : "")).Append("&");
            urlBuilder_.Length--;
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<SubscriptionView>>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(System.Collections.Generic.ICollection<SubscriptionView>);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task PutSubscriptionAsync(SubscriptionCreateModify subscriptionJson)
        {
            return PutSubscriptionAsync(subscriptionJson, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task PutSubscriptionAsync(SubscriptionCreateModify subscriptionJson, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(subscriptionJson, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("PUT");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task PutSubscription2Async(SubscriptionCreateModify subscriptionJson)
        {
            return PutSubscription2Async(subscriptionJson, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task PutSubscription2Async(SubscriptionCreateModify subscriptionJson, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(subscriptionJson, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task DisableAsync(FindCredentials apiCreds)
        {
            return DisableAsync(apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task DisableAsync(FindCredentials apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/Disable");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("PATCH");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task Disable2Async(FindCredentials apiCreds)
        {
            return Disable2Async(apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task Disable2Async(FindCredentials apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/Disable");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task EnableAsync(FindCredentials apiCreds)
        {
            return EnableAsync(apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task EnableAsync(FindCredentials apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/Enable");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("PATCH");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task Enable2Async(FindCredentials apiCreds)
        {
            return Enable2Async(apiCreds, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task Enable2Async(FindCredentials apiCreds, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/Enable");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(apiCreds, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task<KeyView> SaveAsync(SubscriptionCreateModify subscriptionJson)
        {
            return SaveAsync(subscriptionJson, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task<KeyView> SaveAsync(SubscriptionCreateModify subscriptionJson, System.Threading.CancellationToken cancellationToken)
        {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/Save");
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(subscriptionJson, _settings.Value));
                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
                    request_.Content = content_;
                    request_.Method = new System.Net.Http.HttpMethod("POST");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "201") 
                        {
                            var objectResponse_ = await ReadObjectResponseAsync<KeyView>(response_, headers_).ConfigureAwait(false);
                            return objectResponse_.Object;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
            
                        return default(KeyView);
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task DeleteSubscriptionAsync(System.Guid x_Api_Key, System.Guid serial, bool? keep)
        {
            return DeleteSubscriptionAsync(x_Api_Key, serial, keep, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task DeleteSubscriptionAsync(System.Guid x_Api_Key, System.Guid serial, bool? keep, System.Threading.CancellationToken cancellationToken)
        {
            if (serial == null)
                throw new System.ArgumentNullException("serial");
    
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/{serial}?");
            urlBuilder_.Replace("{serial}", System.Uri.EscapeDataString(ConvertToString(serial, System.Globalization.CultureInfo.InvariantCulture)));
            urlBuilder_.Append(System.Uri.EscapeDataString("keep") + "=").Append(System.Uri.EscapeDataString(keep != null ? ConvertToString(keep, System.Globalization.CultureInfo.InvariantCulture) : "")).Append("&");
            urlBuilder_.Length--;
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    if (x_Api_Key == null)
                        throw new System.ArgumentNullException("x_Api_Key");
                    request_.Headers.TryAddWithoutValidation("X-Api-Key", ConvertToString(x_Api_Key, System.Globalization.CultureInfo.InvariantCulture));
                    request_.Method = new System.Net.Http.HttpMethod("DELETE");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public System.Threading.Tasks.Task DeleteSubscription2Async(System.Guid x_Api_Key, System.Guid serial, bool? keep)
        {
            return DeleteSubscription2Async(x_Api_Key, serial, keep, System.Threading.CancellationToken.None);
        }
    
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="ApiException">A server side error occurred.</exception>
        public async System.Threading.Tasks.Task DeleteSubscription2Async(System.Guid x_Api_Key, System.Guid serial, bool? keep, System.Threading.CancellationToken cancellationToken)
        {
            if (serial == null)
                throw new System.ArgumentNullException("serial");
    
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/SubscriptionsApi/{serial}?");
            urlBuilder_.Replace("{serial}", System.Uri.EscapeDataString(ConvertToString(serial, System.Globalization.CultureInfo.InvariantCulture)));
            urlBuilder_.Append(System.Uri.EscapeDataString("keep") + "=").Append(System.Uri.EscapeDataString(keep != null ? ConvertToString(keep, System.Globalization.CultureInfo.InvariantCulture) : "")).Append("&");
            urlBuilder_.Length--;
    
            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    if (x_Api_Key == null)
                        throw new System.ArgumentNullException("x_Api_Key");
                    request_.Headers.TryAddWithoutValidation("X-Api-Key", ConvertToString(x_Api_Key, System.Globalization.CultureInfo.InvariantCulture));
                    request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json");
                    request_.Method = new System.Net.Http.HttpMethod("POST");
    
                    PrepareRequest(client_, request_, urlBuilder_);
                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
                    PrepareRequest(client_, request_, url_);
    
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }
    
                        ProcessResponse(client_, response_);
    
                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "204") 
                        {
                            return;
                        }
                        else
                        if (status_ != "200" && status_ != "204")
                        {
                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                            throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
                        }
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }
        }
    
        protected struct ObjectResponseResult<T>
        {
            public ObjectResponseResult(T responseObject, string responseText)
            {
                this.Object = responseObject;
                this.Text = responseText;
            }
    
            public T Object { get; }
    
            public string Text { get; }
        }
    
        public bool ReadResponseAsString { get; set; }
        
        protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
        {
            if (response == null || response.Content == null)
            {
                return new ObjectResponseResult<T>(default(T), string.Empty);
            }
        
            if (ReadResponseAsString)
            {
                var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                try
                {
                    var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
                    return new ObjectResponseResult<T>(typedBody, responseText);
                }
                catch (Newtonsoft.Json.JsonException exception)
                {
                    var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
                    throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
                }
            }
            else
            {
                try
                {
                    using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    using (var streamReader = new System.IO.StreamReader(responseStream))
                    using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
                    {
                        var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
                        var typedBody = serializer.Deserialize<T>(jsonTextReader);
                        return new ObjectResponseResult<T>(typedBody, string.Empty);
                    }
                }
                catch (Newtonsoft.Json.JsonException exception)
                {
                    var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
                    throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
                }
            }
        }
    
        private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
        {
            if (value is System.Enum)
            {
                string name = System.Enum.GetName(value.GetType(), value);
                if (name != null)
                {
                    var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
                    if (field != null)
                    {
                        var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute)) 
                            as System.Runtime.Serialization.EnumMemberAttribute;
                        if (attribute != null)
                        {
                            return attribute.Value != null ? attribute.Value : name;
                        }
                    }
                }
            }
            else if (value is bool) {
                return System.Convert.ToString(value, cultureInfo).ToLowerInvariant();
            }
            else if (value is byte[])
            {
                return System.Convert.ToBase64String((byte[]) value);
            }
            else if (value != null && value.GetType().IsArray)
            {
                var array = System.Linq.Enumerable.OfType<object>((System.Array) value);
                return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
            }
        
            return System.Convert.ToString(value, cultureInfo);
        }
    }

    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class KeyView 
    {
        [Newtonsoft.Json.JsonProperty("serial", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Serial { get; set; }
    
        [Newtonsoft.Json.JsonProperty("current", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public bool Current { get; set; }
    
        [Newtonsoft.Json.JsonProperty("commenced", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public System.DateTimeOffset Commenced { get; set; }
    
        [Newtonsoft.Json.JsonProperty("callbackOnModify", Required = Newtonsoft.Json.Required.Always)]
        public bool CallbackOnModify { get; set; }
    
        [Newtonsoft.Json.JsonProperty("created", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.DateTimeOffset Created { get; set; }
    
        [Newtonsoft.Json.JsonProperty("updated", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.DateTimeOffset? Updated { get; set; }
    
        [Newtonsoft.Json.JsonProperty("frequency", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public string Frequency { get; set; }
    
        [Newtonsoft.Json.JsonProperty("action", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public string Action { get; set; }
    
        [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        [System.ComponentModel.DataAnnotations.StringLength(80)]
        public string Name { get; set; }
    
        [Newtonsoft.Json.JsonProperty("callbackUrl", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        [System.ComponentModel.DataAnnotations.StringLength(800)]
        public System.Uri CallbackUrl { get; set; }
    
        [Newtonsoft.Json.JsonProperty("custom", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public object Custom { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class CurrentKey 
    {
        [Newtonsoft.Json.JsonProperty("current", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public bool Current { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class Expiry 
    {
        [Newtonsoft.Json.JsonProperty("expires", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.DateTimeOffset Expires { get; set; }
    
        [Newtonsoft.Json.JsonProperty("time", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.TimeSpan Time { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class CountOf 
    {
        [Newtonsoft.Json.JsonProperty("count", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public int Count { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class ApiKey 
    {
        [Newtonsoft.Json.JsonProperty("key", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Key { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class ProductView 
    {
        [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        [System.ComponentModel.DataAnnotations.StringLength(80)]
        public string Name { get; set; }
    
        [Newtonsoft.Json.JsonProperty("serial", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Serial { get; set; }
    
        [Newtonsoft.Json.JsonProperty("created", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.DateTimeOffset Created { get; set; }
    
        [Newtonsoft.Json.JsonProperty("updated", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.DateTimeOffset? Updated { get; set; }
    
        [Newtonsoft.Json.JsonProperty("custom", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public object Custom { get; set; }
    
        [Newtonsoft.Json.JsonProperty("subscriptions", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Collections.Generic.ICollection<SubscriptionView> Subscriptions { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class SubscriptionView 
    {
        [Newtonsoft.Json.JsonProperty("commenced", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public System.DateTimeOffset Commenced { get; set; }
    
        [Newtonsoft.Json.JsonProperty("callbackOnModify", Required = Newtonsoft.Json.Required.Always)]
        public bool CallbackOnModify { get; set; }
    
        [Newtonsoft.Json.JsonProperty("created", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.DateTimeOffset Created { get; set; }
    
        [Newtonsoft.Json.JsonProperty("updated", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.DateTimeOffset? Updated { get; set; }
    
        [Newtonsoft.Json.JsonProperty("frequency", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public string Frequency { get; set; }
    
        [Newtonsoft.Json.JsonProperty("action", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public string Action { get; set; }
    
        [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        [System.ComponentModel.DataAnnotations.StringLength(80)]
        public string Name { get; set; }
    
        [Newtonsoft.Json.JsonProperty("callbackUrl", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        [System.ComponentModel.DataAnnotations.StringLength(800)]
        public System.Uri CallbackUrl { get; set; }
    
        [Newtonsoft.Json.JsonProperty("custom", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public object Custom { get; set; }
    
        [Newtonsoft.Json.JsonProperty("keys", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Collections.Generic.ICollection<KeyView> Keys { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class FindCredentials 
    {
        [Newtonsoft.Json.JsonProperty("key", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Key { get; set; }
    
        [Newtonsoft.Json.JsonProperty("serial", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Serial { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class ProductCreateModify 
    {
        [Newtonsoft.Json.JsonProperty("key", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Key { get; set; }
    
        [Newtonsoft.Json.JsonProperty("serial", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid? Serial { get; set; }
    
        [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Name { get; set; }
    
        [Newtonsoft.Json.JsonProperty("custom", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public object Custom { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class ApiCredentials 
    {
        [Newtonsoft.Json.JsonProperty("key", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Key { get; set; }
    
        [Newtonsoft.Json.JsonProperty("serial", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid? Serial { get; set; }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.23.0 (Newtonsoft.Json v11.0.0.0)")]
    public partial class SubscriptionCreateModify 
    {
        [Newtonsoft.Json.JsonProperty("frequency", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public string Frequency { get; set; }
    
        [Newtonsoft.Json.JsonProperty("action", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public string Action { get; set; }
    
        [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        [System.ComponentModel.DataAnnotations.StringLength(80)]
        public string Name { get; set; }
    
        [Newtonsoft.Json.JsonProperty("callbackUrl", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        [System.ComponentModel.DataAnnotations.StringLength(800)]
        public System.Uri CallbackUrl { get; set; }
    
        [Newtonsoft.Json.JsonProperty("key", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Key { get; set; }
    
        [Newtonsoft.Json.JsonProperty("serial", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid Serial { get; set; }
    
        [Newtonsoft.Json.JsonProperty("custom", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public object Custom { get; set; }
    
        [Newtonsoft.Json.JsonProperty("startFrom", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string StartFrom { get; set; }
    
        [Newtonsoft.Json.JsonProperty("callbackOnModify", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public bool? CallbackOnModify { get; set; }
    
    
    }

    public partial class FileResponse : System.IDisposable
    {
        private System.IDisposable _client; 
        private System.IDisposable _response; 

        public int StatusCode { get; private set; }

        public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }

        public System.IO.Stream Stream { get; private set; }

        public bool IsPartial
        {
            get { return StatusCode == 206; }
        }

        public FileResponse(int statusCode, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.IO.Stream stream, System.IDisposable client, System.IDisposable response)
        {
            StatusCode = statusCode; 
            Headers = headers; 
            Stream = stream; 
            _client = client; 
            _response = response;
        }

        public void Dispose() 
        {
            if (Stream != null)
                Stream.Dispose();
            if (_response != null)
                _response.Dispose();
            if (_client != null)
                _client.Dispose();
        }
    }

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.0.6.0 (NJsonSchema v10.0.23.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class ApiException : System.Exception
    {
        public int StatusCode { get; private set; }

        public string Response { get; private set; }

        public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }

        public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Exception innerException) 
            : base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + response.Substring(0, response.Length >= 512 ? 512 : response.Length), innerException)
        {
            StatusCode = statusCode;
            Response = response; 
            Headers = headers;
        }

        public override string ToString()
        {
            return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
        }
    }

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.0.6.0 (NJsonSchema v10.0.23.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class ApiException<TResult> : ApiException
    {
        public TResult Result { get; private set; }

        public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, TResult result, System.Exception innerException) 
            : base(message, statusCode, response, headers, innerException)
        {
            Result = result;
        }
    }

}

#pragma warning restore 1591
#pragma warning restore 1573
#pragma warning restore  472
#pragma warning restore  114
#pragma warning restore  108

...coming soon, Raspberry PI examples