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-failureQuick 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
| Service | Methods | Description |
|---|---|---|
client.health() | check, detailed, ping | System health (no auth) |
client.products() | create, get_by_iv_id, update, delete_by_iv_id, list, list_all | Product catalog |
client.skus() | create, get_by_iv_id, update, update_stock, delete_by_iv_id, list, list_all | SKU inventory per branch |
client.branches() | create, get_by_iv_id, update, delete_by_iv_id, list, list_all | Physical locations |
client.customers() | create, get_by_id, update, delete_by_id, list, list_all, get_addresses, create_address, create_group | Customer management |
client.orders() | get_by_id, update_status, list | Order management |
client.offers() | create, get_by_id, update, update_status, delete_by_id, list, bulk_upsert | Promotions & discounts |
client.brands() | create, get_by_id, update, delete_by_id | Brand management |
client.categories() | create, get_by_id, update, delete_by_id | Product categories |
client.generics() | create, get_by_id, update, delete_by_id | Generic entities |
client.integrations() | get_config, execute, enable, disable | Platform 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::futurefor 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/