uncloseai.

C Examples - Free LLM & TTS AI Service

C Examples

This page demonstrates how to use the uncloseai. API endpoints with C using libcurl. All examples use the OpenAI-compatible API interface, making it easy to switch between different models and endpoints.

Available Endpoints:

Setup & Dependencies

Install libcurl development libraries:

# Ubuntu/Debian
sudo apt-get install libcurl4-openssl-dev

# macOS
brew install curl

# Alpine
apk add curl-dev

Compile with:

gcc -o chat chat.c -lcurl

Non-Streaming Examples

Non-streaming mode waits for the complete response before returning. This is simpler to use but provides no intermediate feedback during generation.

Using Hermes (General Purpose)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

struct Memory {
    char *response;
    size_t size;
};

static size_t write_callback(void *data, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    struct Memory *mem = (struct Memory *)userp;
    char *ptr = realloc(mem->response, mem->size + realsize + 1);
    if (!ptr) return 0;
    mem->response = ptr;
    memcpy(&(mem->response[mem->size]), data, realsize);
    mem->size += realsize;
    mem->response[mem->size] = 0;
    return realsize;
}

int main(void) {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    struct Memory chunk = {.response = malloc(1), .size = 0};
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");

    const char *payload =
        "{"
        "\"model\": \"adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic\","
        "\"messages\": [{\"role\": \"user\", \"content\": \"Give a Python Fizzbuzz solution in one line of code?\"}],"
        "\"max_tokens\": 150"
        "}";

    curl_easy_setopt(curl, CURLOPT_URL, "https://hermes.ai.unturf.com/v1/chat/completions");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    CURLcode res = curl_easy_perform(curl);
    if (res == CURLE_OK) {
        printf("Response:\n%s\n", chunk.response);
    }

    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    free(chunk.response);
    return 0;
}

Using Qwen 3 Coder (Specialized for Coding)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

// ... same write_callback and Memory struct as above ...

int main(void) {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    struct Memory chunk = {.response = malloc(1), .size = 0};
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");

    const char *payload =
        "{"
        "\"model\": \"hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M\","
        "\"messages\": [{\"role\": \"user\", \"content\": \"Explain quicksort in C with code\"}],"
        "\"max_tokens\": 500"
        "}";

    curl_easy_setopt(curl, CURLOPT_URL, "https://qwen.ai.unturf.com/v1/chat/completions");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    CURLcode res = curl_easy_perform(curl);
    if (res == CURLE_OK) {
        printf("Response:\n%s\n", chunk.response);
    }

    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    free(chunk.response);
    return 0;
}

Streaming Examples

Streaming mode returns chunks of the response as they are generated, providing real-time feedback. This is ideal for interactive applications and long responses.

Streaming with Hermes

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

static size_t stream_callback(void *data, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    char *chunk = (char *)data;

    // Process SSE data lines
    char *line = strtok(chunk, "\n");
    while (line) {
        if (strncmp(line, "data: ", 6) == 0) {
            const char *json = line + 6;
            if (strcmp(json, "[DONE]") != 0) {
                // Extract content from: {"choices":[{"delta":{"content":"..."}}]}
                const char *content_start = strstr(json, "\"content\":\"");
                if (content_start) {
                    content_start += 11;
                    const char *content_end = strchr(content_start, '"');
                    if (content_end) {
                        fwrite(content_start, 1, content_end - content_start, stdout);
                        fflush(stdout);
                    }
                }
            }
        }
        line = strtok(NULL, "\n");
    }
    return realsize;
}

int main(void) {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");

    const char *payload =
        "{"
        "\"model\": \"adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic\","
        "\"messages\": [{\"role\": \"user\", \"content\": \"Write a short poem about coding\"}],"
        "\"max_tokens\": 200,"
        "\"stream\": true"
        "}";

    curl_easy_setopt(curl, CURLOPT_URL, "https://hermes.ai.unturf.com/v1/chat/completions");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, stream_callback);

    printf("Streaming response:\n");
    curl_easy_perform(curl);
    printf("\n");

    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return 0;
}

Text-to-Speech Examples

Generate audio from text using the TTS endpoint.

Basic TTS

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>

static size_t write_file(void *data, size_t size, size_t nmemb, void *userp) {
    return fwrite(data, size, nmemb, (FILE *)userp);
}

int main(void) {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    FILE *fp = fopen("output.mp3", "wb");
    if (!fp) {
        curl_easy_cleanup(curl);
        return 1;
    }

    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");

    const char *payload =
        "{"
        "\"model\": \"tts-1\","
        "\"input\": \"Hello! This is a test of text to speech.\","
        "\"voice\": \"alloy\""
        "}";

    curl_easy_setopt(curl, CURLOPT_URL, "https://speech.ai.unturf.com/v1/audio/speech");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

    CURLcode res = curl_easy_perform(curl);
    if (res == CURLE_OK) {
        printf("Audio saved to output.mp3\n");
    }

    fclose(fp);
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return 0;
}

Available voices: alloy, echo, fable, onyx, nova, shimmer

Full SDK Implementation

For a complete SDK with model discovery and advanced features, see the full implementations in the source repository: