C++ SDK
Modern C++17 client built on libcurl and nlohmann/json — CMake FetchContent, vcpkg, or Conan; HMAC webhook verification via OpenSSL.
| Version | v1.0.1 · stable |
| Requires | C++17 (GCC 8+/Clang 7+/MSVC 2019+), CMake 3.16+, libcurl 7.75+, OpenSSL 3.0+ |
| Dependencies | libcurl (HTTP), nlohmann/json (auto-fetched), OpenSSL (HMAC) |
| Install | CMake FetchContent · vcpkg · Conan |
#Installation
CMakeLists.txt
cpp
# CMake FetchContent (recommended)
include(FetchContent)
FetchContent_Declare(sendafrica
GIT_REPOSITORY https://github.com/SendAfrica/SendAfrica-cpp-sdk.git
GIT_TAG v1.0.1
)
FetchContent_MakeAvailable(sendafrica)
target_link_libraries(your_app PRIVATE sendafrica::sendafrica)
# vcpkg
vcpkg install sendafrica
# Conan
conan install sendafrica/1.0.1@ --build=missing
# System deps (Debian/Ubuntu)
# sudo apt-get install cmake g++ libcurl4-openssl-dev libssl-dev#Client setup
auth.cpp
cpp
#include <sendafrica/sendafrica.hpp>
// Option 1: explicit key
sendafrica::Client client("SA-xxxxx");
// Option 2: set env var, then no arguments needed
// export SENDAFRICA_API_KEY="SA-xxxxx"
sendafrica::Client client;
// Full configuration
sendafrica::ClientOptions opts;
opts.timeout_seconds = 30; // default 10
opts.max_retries = 5; // default 3
opts.debug = true; // log to stderr
opts.webhook_secret = "whsec_...";
sendafrica::Client client("SA-xxxxx", opts);#Sending SMS
send.cpp
cpp
#include <sendafrica/sendafrica.hpp>
#include <iostream>
int main() {
sendafrica::Client client("SA-xxxxx");
auto result = client.sms().send(
"0712345678",
"Your OTP is 123456",
"MyBrand" // optional, max 11 chars
);
std::cout << result.message_id << "\n"; // "SA-xxxx-xxxx-xxxx"
std::cout << result.status << "\n"; // "sent"
std::cout << result.credits_used << "\n"; // 1
// Preview cost without sending (zero network calls)
auto analysis = client.sms().analyze("Habari, how are you?");
std::cout << analysis.encoding << ": " << analysis.parts << "\n";
}#Bulk sending
bulk.cpp
cpp
std::vector<sendafrica::SMSResource::BulkItem> items = {
{"+255711111111", "Hello John"},
{"+255722222222", "Hello Mary"},
};
auto bulk = client.sms().send_many(items, "MyBrand");
std::cout << bulk.sent_count() << " sent\n";
for (const auto& f : bulk.failed) {
std::cerr << "Index " << f.index << " (" << f.to << "): "
<< f.error << "\n";
}#Delivery status & credits
status.cpp
cpp
auto result = client.sms().send("0712345678", "Hello!");
// ... later ...
auto status = client.sms().status(result.message_id);
std::cout << status.status << "\n"; // "delivered"
auto balance = client.credits().balance();
std::cout << balance.balance << " credits\n";
auto txns = client.credits().history(1, 50);
for (const auto& tx : txns) {
std::cout << tx.id << " " << tx.type << " " << tx.amount << "\n";
}#Webhooks & errors
webhooks.cpp
cpp
// In your HTTP handler:
std::string raw_body = /* request body */;
std::string sig_header = /* X-SendAfrica-Signature header */;
auto event = client.webhooks().parse(raw_body, sig_header);
if (event.type == "sms.delivered") {
std::cout << "Delivered: " << *event.message_id << "\n";
}
try {
client.sms().send("0712345678", "Hello");
} catch (const sendafrica::InsufficientCreditsError& e) {
std::cerr << "Not enough credits\n";
} catch (const sendafrica::RateLimitError& e) {
std::cerr << "Rate limited, retry after " << *e.retry_after() << "s\n";
} catch (const sendafrica::Error& e) {
std::cerr << e.message() << " (HTTP " << *e.status_code() << ")\n";
}