Linkit
SDK Reference

C++ SDK

Lean, transport-first Linkit C++20 SDK with canonical routes, async support, header-only core, and zero forced HTTP dependencies.

C++ SDK

The Linkit C++ SDK provides a lean, header-only client for the Linkit e-commerce API. Built with C++20, it uses a transport-first design — inject your own HTTP backend (libcurl, Boost.Beast, Qt Network, etc.) and the SDK handles routing, serialization, and pagination.

Design Goal

Lean and fast: header-only core, no reflection, no hidden allocations beyond request URL/body handling. Plug in any HTTP transport.


Installation

include(FetchContent)
FetchContent_Declare(
    linkit
    URL https://linkit.works/downloads/sdks/cpp/linkit-cpp-0.1.0.tar.gz
)
FetchContent_MakeAvailable(linkit)

target_link_libraries(your_app PRIVATE linkit_cpp)
# Download and extract
tar xf linkit-cpp-0.1.0.tar.gz

# In your CMakeLists.txt:
add_subdirectory(linkit)
target_link_libraries(your_app PRIVATE linkit_cpp)
# Copy into your project
cp -r sdks/cpp/linkit ./third_party/linkit

# CMakeLists.txt:
add_subdirectory(third_party/linkit)
target_link_libraries(your_app PRIVATE linkit_cpp)

Build & Test

cd sdks/cpp/linkit
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build --output-on-failure

Quick Start

Implement a Transport

#include <memory>
#include "linkit/linkit.hpp"

class CurlTransport final : public linkit::Transport {
public:
    linkit::Response send(const linkit::Request& req) override {
        // Implement using libcurl, Boost.Beast, etc.
        // Map req.method, req.url, req.body, req.bearer_token
        return {200, R"({"status":"healthy"})"};
    }
};

Initialize the Client

auto transport = std::make_shared<CurlTransport>();
auto client = linkit::Client::quick_setup(
    "https://linkit.works/api/v1",
    "your-jwt-token",
    transport
);

Use Service APIs

// Health check — no auth header sent
const auto health = client.health().check();
if (!health.ok()) {
    std::cerr << "API unhealthy: " << health.status << "\n";
    return 1;
}

// Fetch a product by IV ID
const auto product = client.products().get_by_iv_id("PROD-001");
std::cout << "Product: " << product.body << "\n";

Configuration

auto config = linkit::Config{
    .base_url = "https://linkit.works/api/v1",
    .jwt_token = "your-jwt-token",
    .timeout_ms = 30000,
    .max_retries = 3,
    .retry_base_delay_ms = 150,
    .max_concurrent_requests = 16,
    .user_agent = "MyApp/1.0 LinkitCppSDK/0.1.0"
};

auto client = linkit::Client(config, transport);

Services Reference

ServiceMethodsDescription
client.health()check, detailed, pingSystem health (no auth)
client.products()create, get_by_iv_id, update, delete_by_iv_id, list, list_allProduct catalog
client.skus()create, get_by_iv_id, update, update_stock, delete_by_iv_id, list, list_allSKU inventory per branch
client.branches()create, get_by_iv_id, update, delete_by_iv_id, list, list_allPhysical locations
client.customers()create, get_by_id, update, delete_by_id, list, list_all, get_addresses, create_address, create_groupCustomer management
client.orders()get_by_id, update_status, listOrder management
client.offers()create, get_by_id, update, update_status, delete_by_id, list, bulk_upsertPromotions & discounts
client.brands()create, get_by_id, update, delete_by_idBrand management
client.categories()create, get_by_id, update, delete_by_idProduct categories
client.generics()create, get_by_id, update, delete_by_idGeneric entities
client.integrations()get_config, execute, enable, disablePlatform connections

Products

Create

auto product = client.products().create(R"({
    "ivId": "PROD-001",
    "nameEn": "Premium Coffee",
    "nameAr": "قهوة ممتازة",
    "averagePrice": 29.99,
    "isEnabled": true
})");

if (!product.ok()) {
    std::cerr << "Create failed: " << product.status << "\n";
}

Create with Typed Request

auto product = client.products().create(linkit::ProductRequest{
    .iv_id = "PROD-001",
    .name_en = "Premium Coffee",
    .name_ar = "قهوة ممتازة",
    .average_price = 29.99,
    .is_enabled = true
});

List with Filters

auto products = client.products().list({
    .page = 1,
    .limit = 50,
    .enabled = true,
    .category_id = "beverages",
    .search = "coffee"
});

Paginate All

auto it = client.products().list_all({.limit = 100});
while (auto page = it.next()) {
    std::cout << "Page body: " << page->body << "\n";
}

SKUs

Create & Update Stock

// Create SKU
auto sku = client.skus().create(linkit::SkuRequest{
    .iv_id = "SKU-001",
    .branch_iv_id = "BR-RYD-001",
    .product_iv_id = "PROD-001",
    .price = 29.99,
    .qty = 1000.0,
    .available = true
});

// Update stock
auto stock = client.skus().update_stock("SKU-001", R"({"qty": 950})", "BR-RYD-001");

Branches

// Create
auto branch = client.branches().create(linkit::BranchRequest{
    .iv_id = "BR-RYD-001",
    .name_en = "Riyadh Central",
    .name_ar = "الرياض سنتر",
    .location = {24.7136, 46.6753},
    .active = true,
    .email = "riyadh@example.com"
});

// Get by ID
auto existing = client.branches().get_by_iv_id("BR-RYD-001");

Customers

// Create
auto customer = client.customers().create(R"({
    "firstName": "Ahmad",
    "lastName": "Hamdi",
    "email": "ahmad@example.com",
    "phone": "+966500000000",
    "type": "individual"
})");

// Get addresses
auto addresses = client.customers().get_addresses("C-001");

// Create customer group
auto group = client.customers().create_group(R"({"name": "VIP Customers"})");

Orders & Offers

// Update order status
auto order = client.orders().update_status("ORD-001", R"({"status": "shipped"})");

// Update offer status
auto offer = client.offers().update_status("OFR-001", R"({"status": "paused"})");

// Bulk upsert offers
auto bulk = client.offers().bulk_upsert(R"([
    {"name": "Weekend 15%", "offerType": "direct_discount", "discountValue": 15.0},
    {"name": "BOGO Deal", "offerType": "bogo", "buyQty": 1, "getQty": 1}
])");

Integrations

// Get config
auto config = client.integrations().get_config("hungerstation-orders-v2");

// Enable, execute, disable
client.integrations().enable("hungerstation-orders-v2");
auto result = client.integrations().execute("hungerstation-orders-v2");
client.integrations().disable("hungerstation-orders-v2");

Async Operations

The SDK provides std::future-based async variants for hot flows:

#include <future>

// Fire off multiple requests concurrently
auto product_future = client.products().get_by_iv_id_async("PROD-001");
auto sku_future = client.skus().get_by_iv_id_async("SKU-001");

// Gather results
auto product = product_future.get();
auto sku = sku_future.get();

Error Handling

auto response = client.products().get_by_iv_id("NONEXISTENT");

if (!response.ok()) {
    switch (response.status) {
        case 404:
            std::cerr << "Product not found\n";
            break;
        case 401:
            std::cerr << "Authentication failed\n";
            break;
        case 429:
            std::cerr << "Rate limited — slow down\n";
            break;
        default:
            std::cerr << "API error " << response.status << ": " << response.body << "\n";
    }
}

Transport Interface

The SDK ships with no HTTP dependency — implement the linkit::Transport interface to use any HTTP library:

class linkit::Transport {
public:
    virtual ~Transport() = default;
    virtual linkit::Response send(const linkit::Request& req) = 0;
};

// Request contains:
struct Request {
    HttpMethod method;     // GET, POST, PUT, PATCH, DELETE
    std::string url;       // Full URL with query params
    std::string body;      // JSON body (empty for GET/DELETE)
    std::string bearer_token; // JWT token (empty for health routes)
};

// Response contains:
struct Response {
    int status;
    std::string body;

    bool ok() const { return status >= 200 && status < 300; }
};

Example: libcurl Transport

#include <curl/curl.h>

class CurlTransport final : public linkit::Transport {
    CURL* curl_;
public:
    CurlTransport() : curl_(curl_easy_init()) {}
    ~CurlTransport() { curl_easy_cleanup(curl_); }

    linkit::Response send(const linkit::Request& req) override {
        std::string response_body;
        curl_easy_setopt(curl_, CURLOPT_URL, req.url.c_str());
        curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &response_body);

        if (!req.bearer_token.empty()) {
            auto header = "Authorization: Bearer " + req.bearer_token;
            auto* list = curl_slist_append(nullptr, header.c_str());
            curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, list);
        }

        // Set method and body...
        auto res = curl_easy_perform(curl_);
        long http_code = 0;
        curl_easy_getinfo(curl_, CURLINFO_RESPONSE_CODE, &http_code);

        return {static_cast<int>(http_code), response_body};
    }
};

Core Features

  • Full 11-service parity with Linkit API domains
  • Canonical route mapping (/api/v1/products/iv/{id}, /api/v1/skus/iv/{id}/stock, etc.)
  • Async path via std::future for concurrent operations
  • Pluggable transport interface — direct integration with libcurl, Beast, Qt, or custom event loops
  • Pagination iterators via list_all(...) on product/sku/branch/customer services
  • Header-only core — no link-time dependencies beyond the C++ standard library

Download

Archive builds are staged into:

/downloads/sdks/cpp/