Solari

C++ SDK

Two C++17 libraries cover the Solari products: solari::browser (target solari_browser) for browsers, and solari (target solari) for sandboxes. Both are blocking and synchronous. Every call is one round-trip over libcurl, with nlohmann/json for wire types. VMs (GUI desktops) are created with createDesktop(), but driving their GUI needs another SDK; see VMs.

Not published: consumed as source
Neither library ships to a registry. There is no Conan, vcpkg, or system package. You pull them into your build with CMake FetchContent, as below. This applies to every page in this section.

Installation

LibraryTargetNamespaceProduct
pinetree-browser / sdk/cppsolari_browsersolari::browserBrowsers
pinetree-desktop / sdk/cppsolarisolariSandboxes
cmake_minimum_required(VERSION 3.16)
project(my_app CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)

# Don't build either SDK's own test target inside your project.
set(SOLARI_BUILD_TESTS OFF CACHE BOOL "" FORCE)

# Browsers: solari::browser
FetchContent_Declare(
  solari_browser
  GIT_REPOSITORY https://github.com/solari-sdk/solari-browser-cpp.git
  GIT_TAG        v0.1.0
)

# Sandboxes: solari
FetchContent_Declare(
  solari
  GIT_REPOSITORY https://github.com/solari-sdk/solari-sandbox-cpp.git
  GIT_TAG        v0.1.0
)

FetchContent_MakeAvailable(solari_browser solari)

add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE solari_browser solari)

Take only the FetchContent_Declare you need. The two are independent. Fetched for you at configure time: nlohmann/json v3.11.3, IXWebSocket v11.4.5, and doctest v2.4.11 (tests only). Required from the system: libcurl, a threads library, and OpenSSL for IXWebSocket TLS.

The two libraries share their options and deps
Both declare SOLARI_WITH_WS and SOLARI_BUILD_TESTS, so setting either affects both. They also pin the same versions of nlohmann/json and IXWebSocket, so FetchContent de-duplicates them cleanly when you take both.

Getting Started

Create a browser session

#include <iostream>
#include <solari/browser/browser.hpp>

int main() {
  solari::browser::ClientOptions opts;
  opts.apiKey = "slr_live_...";
  solari::browser::Client client(opts);

  solari::browser::CreateSessionOptions o;
  o.stealth = true;
  o.proxy = std::string("us");

  auto session = client.sessions.create(o);
  std::cout << session.cdpEndpoint << "\n";  // drive this with a CDP client
  client.sessions.release(session.id);
}

There is no launch(). C++ has no Playwright client. See Browsers.

Create a VM

#include <solari/solari.hpp>

solari::ClientOptions opts;
opts.apiKey = "slr_live_...";
opts.baseUrl = "https://api.getsolari.com";
solari::Client client(opts);

solari::CreateSandboxOptions o;
o.template_ = "office";

// createDesktop() sends kind:"desktop"; create() stays a headless sandbox.
auto vm = client.createDesktop(o);
vm->connect();

std::cout << *vm->streamUrl() << "\n";  // wss://.../stream/<id>

// commands / files / code / git work on a VM. Mouse, keyboard, and
// screenshots do NOT exist in C++. See the VMs page.
vm->kill();

Requires the desktop entitlement, or the gateway answers 402 PlanError. There is no Desktop class: driving the GUI needs the REST API or the TypeScript SDK. Full detail on VMs.

Create a sandbox

#include <iostream>
#include <solari/solari.hpp>

int main() {
  solari::ClientOptions opts;
  opts.apiKey = "slr_live_...";
  opts.baseUrl = "https://api.getsolari.com";
  solari::Client client(opts);

  auto sbx = client.create();
  sbx->connect();

  solari::CommandOptions o;
  o.args = {"hi"};
  auto r = sbx->commands.run("echo", o);
  std::cout << r.stdout_;  // "hi"

  sbx->kill();
}

Configuration

Each library has its own ClientOptions struct, passed to its Client constructor. Neither reads an environment variable. Pass apiKey explicitly.

FieldTypeDefaultStructNotes
apiKeystd::stringrequiredbothSent as Authorization: Bearer. Throws if empty.
baseUrlstd::stringsee notesbothsolari::browser: https://api.getsolari.com. solari: required, e.g. https://api.getsolari.com.
maxAttemptsint2solari::browserTotal attempts. 2 means one retry.
backoffMslong500solari::browserFixed pause between attempts, not exponential.
timeoutMslong90000solari::browserPer attempt, not per call.
callTimeoutMslong300000solariPer-RPC timeout given to the Sandbox handles this client creates.
429 is never retried
Both transports retry transport errors and 5xx (the browser one only 502/503/504, with a fixed pause; the sandbox one 5xx and retryable bodies on idempotent requests, with exponential backoff + jitter). Neither retries 429. A concurrency-cap rejection needs caller-side backoff.

Reference

ClassTargetPurpose
solari::browser::Clientsolari_browserBrowser control plane: sessions, profiles, proxy countries.
solari::browser::CdpConnectionsolari_browserMinimal raw-CDP escape hatch, behind SOLARI_WITH_WS. Not an automation API.
solari::ClientsolariSandbox entry point: create, connect, get, kill.
solari::SandboxsolariA live session: commands, files, code, git.
VMssolaricreateDesktop(), streamUrl(), and the core namespaces. No GUI surface.