Beacon C++ SDK
The Beacon C++ SDK provides native integration for Windows desktop applications, server processes, and cross-platform C++ projects.
Installation
CMake FetchContent (recommended)
Add Beacon to your CMakeLists.txt:
include(FetchContent)
FetchContent_Declare(
beacon_sdk
GIT_REPOSITORY https://github.com/softagility/beacon-sdk-cpp.git
GIT_TAG v1.0.1
)
FetchContent_MakeAvailable(beacon_sdk)
target_link_libraries(your_app PRIVATE beacon_sdk)Build from Source
git clone https://github.com/softagility/beacon-sdk-cpp.git
cd beacon-sdk-cpp
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config ReleaseDependencies (libcurl, nlohmann_json, SQLite3) are fetched automatically via CMake FetchContent if not found on the system.
vcpkg
A vcpkg port is planned for a future release. For now, use CMake FetchContent or build from source.
System Requirements
- C++17 or later
- Windows 10+, Linux (glibc 2.28+), or macOS 12+
- CMake 3.25+
- libcurl, nlohmann_json, SQLite3 — resolved automatically by CMake FetchContent if not present
- OpenSSL development headers — required on Linux and macOS via
find_package(OpenSSL). On Windows, TLS uses Schannel and no extra dependency is needed.
The SDK selects the TLS backend based on platform: Schannel on Windows, OpenSSL on Linux and macOS.
Configuration
#include <beacon/beacon.hpp>
int main()
{
auto tracker = beacon::Tracker::configure([](beacon::Options& opts) {
opts.api_key = "your-api-key";
opts.api_base_url = "https://api.beacon.softagility.com";
opts.app_name = "MyApp";
opts.app_version = "1.2.0";
});
tracker->identify("user-123");
tracker->startSession();
// Your application code here...
tracker->endSession();
return 0;
}You can also pass an Options struct directly:
beacon::Options opts;
opts.api_key = "your-api-key";
opts.api_base_url = "https://api.beacon.softagility.com";
opts.app_name = "MyApp";
opts.app_version = "1.2.0";
auto tracker = beacon::Tracker::configure(opts);Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
api_key | std::string | — | Your Beacon API key (required) |
api_base_url | std::string | — | Beacon API base URL (required) |
app_name | std::string | — | Your product’s slug as registered in the Beacon dashboard (e.g., "inventory-manager"). Must match exactly or events are rejected with UNRECOGNIZED_PRODUCT. (required) |
app_version | std::string | — | Your application’s version string. (required) |
enabled | bool | true | Enable or disable tracking globally |
flush_interval_seconds | int | 60 | Batch send interval in seconds (1-3600) |
max_batch_size | int | 25 | Events per batch, clamped to 1-1000 |
max_queue_size_mb | int | 10 | Maximum offline queue size in MB (1-1000) |
max_breadcrumbs | int | 25 | Breadcrumb ring buffer size (0-200) |
logger | std::shared_ptr<beacon::ILogger> | nullptr | Optional logger for SDK diagnostics |
events | EventDefinitionBuilder | — | Builder for registering known event categories and names. Optional; populated via tracker->exportEventManifest(). |
Identifying Users
Before tracking events or sessions, identify the current actor:
tracker->identify("user-123");Once identified, all subsequent calls use this actor. You can also pass an explicit actor ID to tracking methods.
Tracking Events
Events are organized by category and name, with optional properties.
Basic Event
Properties are passed as std::unordered_map<std::string, std::string>. The C++ API doesn’t accept braced initializer lists directly — wrap explicitly:
tracker->track("ui", "button_clicked",
std::unordered_map<std::string, std::string>{
{"button_name", "export"},
{"screen", "dashboard"}
});With Explicit Actor
tracker->track("reports", "report_exported", "user-456",
std::unordered_map<std::string, std::string>{
{"format", "pdf"},
{"row_count", "1500"}
});Session Management
// Start a session (uses the identified actor)
tracker->startSession();
// Or start with an explicit actor ID
tracker->startSession("user-123");
// End the current session
tracker->endSession();Exception Tracking
Track exceptions with severity levels. Breadcrumbs from recent track() calls are attached automatically.
try
{
process_order(order);
}
catch (const std::exception& ex)
{
tracker->trackException(ex, beacon::ExceptionSeverity::NonFatal);
throw;
}Severity options: beacon::ExceptionSeverity::Fatal and beacon::ExceptionSeverity::NonFatal.
Flushing Events
Events are batched and sent on a timer or when the batch size is reached. To flush manually:
bool success = tracker->flush(); // Blocks up to 30 secondsCheck the last flush result:
beacon::FlushStatus status = tracker->last_flush_status();Offline Persistence
Events are persisted to a local SQLite database when the network is unavailable. The queue syncs automatically when connectivity returns.
- Persists across application restarts
- Thread-safe queue with a configurable size limit (
max_queue_size_mb) - Best-effort durable retry: events are retained through transient network failures, but if the queue reaches the configured cap, the oldest events are evicted. Permanent HTTP errors (non-retriable 4xx other than 401/402/429) discard the affected events.
- Call
tracker->flush()at shutdown to deliver pending events before the process exits.
Privacy Controls
The SDK supports opt-out and opt-in for user consent:
tracker->opt_out(); // stops tracking, clears queue
tracker->opt_in(); // resumes trackingOpt-out state persists across application restarts via the offline-persistence database.
Reset
Clear all in-memory state (session, queue, breadcrumbs, actor ID) and generate a new anonymous device ID:
tracker->reset();Use this on logout to separate user sessions.
Event Manifest
Register known events for import into the Beacon portal’s allowlist:
tracker->exportEventManifest("events.json");Singleton Access
After calling configure(), retrieve the tracker instance anywhere with:
auto tracker = beacon::Tracker::instance();Call beacon::Tracker::reset_for_testing() in test teardown to clear the singleton.
Thread Safety
beacon::Tracker is fully thread-safe. Share a single instance across threads.
Lifetime Management
configure() stores the tracker in an internal static shared_ptr, so a local auto tracker going out of scope does not destroy the tracker — it only releases your local reference. The destructor (when it eventually runs) persists in-memory events to disk and joins worker threads, but does not perform a network flush, end the active session, or send any final HTTP requests.
To shut down cleanly, call endSession() and flush() explicitly before your application exits:
auto tracker = beacon::Tracker::configure(configurator);
tracker->identify("user-123");
tracker->startSession();
// Track events...
// Explicit shutdown
tracker->endSession();
tracker->flush(); // blocks up to 30s waiting for the network round-tripWithout an explicit flush(), in-memory events are persisted to disk and delivered on the next session.
Next Steps
- Getting Started for a general overview
- API Reference for direct HTTP integration
- Verify your first event (User Manual) — confirm ingestion from the Beacon dashboard
- Pricing for plan details