Wow, what a change.. *specifically* to the server_creation_params example. This will take a bit of time to digest, for sure. There are certainly several things "of note" to deal with, especially when it comes to adding proper database support. I am working on an example of "how to", and when I get some success I will post that for reference.

Anyway, with that said.... there is certainly one issue that needs updating, dealing with the "key_pair" file. In the current sample, there is no 'write to the file when it doesn't exist' function. I tried copying the code from the server and putting it into the same "generic" place into the new version, but that failed. I suspect that it had to do with the new creation array stuff, where the virtual server had not yet 'officially' been created... until after all of the channels have been defined and validated, and then the array is used to create the server. So, I create a local variable at the top of the code
#ifdef _WINDOWS
#define SLEEP(x) Sleep(x)
#define SLEEP(x) usleep(x*1000)

#define CHECK_ERROR(x) if((error = x) != ERROR_ok) { goto on_error; }

bool found_kp = false; // <<< added this line
In "create_VirtualServer2" I made this change
    /* Assemble filename: keypair_<port>.txt */
    strcpy(filename, "keypair_");
    sprintf(port_str, "%d", port);
    strcat(filename, port_str);
    strcat(filename, ".txt");

    /* Try reading keyPair from file */
    if(readKeyPairFromFile(filename, buffer) == 0) {
        keyPair = buffer;  /* Id read from file */
		found_kp = true; // <<< added this line
    } else {
        keyPair = "";  /* No Id saved, start virtual server with empty keyPair string */
and then at the "leave" label in the same function above, I modified it as follows
    /* Cleanup struct virtual server param. The included struct channel param will be automatically
     * freed when the virtual server param is freed, so you do not need to call freeMemory on
     * the channel params, too. */

	/* If we didn't load the keyPair before, query it from virtual server and save to file */
	if (!found_kp) {
		if ((error = ts3server_getVirtualServerKeyPair(serverID, &keyPair)) != ERROR_ok) {
			char* errormsg;
			if (ts3server_getGlobalErrorMessage(error, &errormsg) == ERROR_ok) {
				printf("Error querying keyPair: %s\n\n", errormsg);
			return 0;

		/* Save keyPair to file "keypair_<port>.txt"*/
		if (writeKeyPairToFile(filename, keyPair) != 0) {
			return 0;

    /* Finally return the virtual server ID of our just created virtual server */
    return serverID;
Now, it's possible that the "return 0" should be -1 instead, just in case one of those 2 internal functions fails... but, it worked for me. It wrote a proper keypair code, and loaded it properly at the next run.