Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
606 lines (430 sloc) 17.8 KB


This document serves as a reference guide for the LaunchDarkly C SDK API. It documents the functions and structs declared in ldapi.h. For complete installation and setup instructions, see the C SDK Reference.


LDConfig *LDConfigNew(const char *authkey)

Creates a new default configuration. authkey is required.

The configuration object is intended to be modified until it is passed to LDClientInit, at which point it should no longer be modified. Here are the modifiable attributes defined in LDConfig:

void LDConfigSetAllAttributesPrivate(LDConfig *config, bool allprivate);

Marks all user attributes private.

void LDConfigSetBackgroundPollingIntervalMillis(LDConfig *config, int millis);

Sets the interval in milliseconds between polls for flag updates when your app is in the background.

void LDConfigSetAppURI(LDConfig *config, const char *uri);

Set the URI for connecting to LaunchDarkly. You probably don't need to set this unless instructed by LaunchDarkly.

void LDConfigSetConnectionTimeoutMillies(LDConfig *config, int millis);

Sets the timeout in milliseconds when connecting to LaunchDarkly.

void LDConfigSetDisableBackgroundUpdating(LDConfig *config, bool disable);

Disables feature flag updates when your app is in the background.

void LDConfigSetEventsCapacity(LDConfig *config, int capacity);

Sets the max number of events to queue before sending them to LaunchDarkly.

void LDConfigSetEventsFlushIntervalMillis(LDConfig *config, int millis);

Sets the maximum amount of time in milliseconds to wait in between sending analytics events to LaunchDarkly.

void LDConfigSetEventsURI(LDConfig *config, const char *uri);

Set the events uri for sending analytics to LaunchDarkly. You probably don't need to set this unless instructed by LaunchDarkly.

void LDConfigSetMobileKey(LDConfig *config, const char *key);

Sets the key for authenticating with LaunchDarkly. This is required unless you're using the client in offline mode.

void LDConfigSetOffline(LDConfig *config, bool offline);

Configures the client for offline mode. In offline mode, no external network connections are made.

void LDConfigSetStreaming(LDConfig *config, bool streaming);

Enables or disables real-time streaming flag updates. Default: true. When set to false, an efficient caching polling mechanism is used. We do not recommend disabling streaming unless you have been instructed to do so by LaunchDarkly support.

void LDConfigSetPollingIntervalMillis(LDConfig *config, int millis);

Only relevant when streaming is disabled (set to false). Sets the interval between feature flag updates.

void LDConfigSetStreamURI(LDConfig *config, const char *uri);

Set the stream uri for connecting to the flag update stream. You probably don't need to set this unless instructed by LaunchDarkly.

void LDConfigSetUseReport(LDConfig *config, bool report);

Determines whether the REPORT or GET verb is used for calls to LaunchDarkly. Do not use unless advised by LaunchDarkly.

void LDConfigSetProxyURI(LDConfig *config, const char *uri);

Set the proxy server used for connecting to LaunchDarkly. By default no proxy is used. The URI string should be of the form socks5:// You may read more about how this SDK handles proxy servers by reading the libcurl documentation on the subject here.

LDConfigSetUseEvaluationReasons(LDConfig *config, bool usereasons);

Decide whether the client should fetch feature flag evaluation explanations from LaunchDarkly.


LDUser *LDUserNew(const char *key);

Allocate a new user. The user may be modified until it is passed to the LDClientIdentify or LDClientInit. The key argument is not required. When key is NULL then a device specific ID is used. If a device specific ID cannot be obtained then a random fallback is generated.

void LDUserSetAnonymous(LDUser *user, bool anon);

Mark the user as anonymous.

void LDUserSetIP(LDUser *user, const char *str);

Set the user's IP.

void LDUserSetFirstName(LDUser *user, const char *str);

Set the user's first name.

void LDUserSetLastName(LDUser *user, const char *str);

Set the user's last name.

void LDUserSetEmail(LDUser *user, const char *str);

Set the user's email.

void LDUserSetName(LDUser *user, const char *str);

Set the user's name.

void LDUserSetAvatar(LDUser *user, const char *str);

Set the user's avatar.

bool LDUserSetCustomAttributesJSON(LDUser *user, const char *jstring);
void LDUSerSetCustomAttributes(LDUser *user, LDNode *custom);

Helper function to set custom attributes for the user. The custom field may be built programmatically using the LDNode functions (see below), or may be set all at once with a json string.

void LDUserAddPrivateAttribute(LDUser *user, const char *name);

Add an attribute name to the private list which will not be recorded.

void LDClientIdentify(LDClient *client, LDUser *user);

Update the client with a new user. The old user is freed. This will re-fetch feature flag settings from LaunchDarkly-- for performance reasons, user contexts should not be changed frequently.

Client lifecycle management

LDClient *LDClientInit(LDConfig *config, LDUser *user, unsigned int maxwaitmilli);

Initialize the client with the config and user. After this call, the config and user must not be modified. The parameter maxwaitmilli indicates the maximum amount of time the client will wait to be fully initialized. If the timeout is hit the client will be available for feature flag evaluation but the results will be fallbacks. The client will continue attempting to connect to LaunchDarkly in the background. If maxwaitmilli is set to 0 then LDClientInit will wait indefinitely.

Only a single initialized client from LDClientInit may exist at one time. To initialize another instance you must first cleanup the previous client with LDClientClose. Should you initialize with LDClientInit while another client exists abort will be called.

LDClient *LDClientGet();

Get a reference to the (single, global) client.

void LDClientClose(LDClient *client);

Close the client, free resources, and generally shut down.

bool LDClientIsInitialized(LDClient *client);

Returns true if the client has been initialized.

bool LDClientAwaitInitialized(LDClient *client, unsigned int timeoutmilli);

Block until initialized up to timeout, returns true if initialized.

void LDClientFlush(LDClient *client);

Send any pending events to the server. They will normally be flushed after a timeout, but may also be flushed manually. This operation does not block.

void LDClientSetOffline(LDClient *client);

Make the client operate in offline mode. No network traffic.

void LDClientSetOnline(LDClient *client);

Return the client to online mode.

bool LDClientIsOffline();

Returns the offline status of the client.

void LDSetClientStatusCallback(void (callback)(LDStatus status));

Set a callback function for client status changes. These are major status changes only, not updates to the feature Node. Current status codes:

typedef enum {
    LDStatusInitializing, //Initializing. Flags may be evaluated at this time
    LDStatusInitialized, //Ready. The client has received an initial feature Node from the server and is ready to proceed
    LDStatusFailed, //Offline. The client has been shut down, likely due to a permission failure
    LDStatusShuttingdown, //In the process of shutting down. Flags should not be evaluated at this time
    LDStatusShutdown //The client has fully shutdown. Interacting with the client object is not safe
} LDStatus;

Feature flags

bool LDBoolVariation(LDClient *client, const char *featurekey , bool defaultvalue);
int LDIntVariation(LDClient *client, const char *featurekey, int defaultvalue);
double LDDoubleVariation(LDClient *client, const char *featurekey, double defaultvalue);

Ask for a bool, int, or double flag, respectively. Return the default if not found.

char *LDStringVariationAlloc(LDClient *client, const char *featurekey, const char *defaultvalue);
char *LDStringVariation(LDClient *client, const char *featurekey, const char *defaultvalue,
    char *buffer, size_t size);

Ask for a string flag. The first version allocates memory on every call. This must then be freed with LDFree. To avoid allocations, the second function fills a caller provided buffer. Up to size bytes will be copied into buffer, truncating if necessary. Both functions return a pointer.

LDNode *LDJSONVariation(LDClient *client, const char *featurekey, const LDNode *defaultvalue);

Ask for a JSON variation, returned as a parsed tree of LDNodes. You must free the result with LDNodeFree. See also LDNodeLookup.

bool LDBoolVariationDetail(LDClient *client, const char *featurekey, bool defaultvalue, LDVariationDetails *details);
int LDIntVariationDetail(LDClient *client, const char *featurekey, int defaultvalue, LDVariationDetails *details);
double LDDoubleVariationDetail(LDClient *client, const char *featurekey, double defaultvalue, LDVariationDetails *details);
char *LDStringVariationAllocDetail(LDClient *client, const char *featurekey, const char *defaultvalue, LDVariationDetails *details);
char *LDStringVariationDetail(LDClient *client, const char *featurekey, const char *, char *defaultvalue, size_t, LDVariationDetails *details);
LDNode *LDJSONVariationDetail(LDClient *client, const char *featurekey, const LDNode *defaultvalue, LDVariationDetails *details);

To receive evaluation explanations you must use the detail version of flag variations.

LDVariationDetails details;
bool value = LDBoolVariationDetail(client, "my-key", false, &details);

To use detail variations you must provide a pointer to an LDVariationDetails struct that will be filled by the evaluation routine. The contents of LDVariationDetails must be freed with LDFreeDetailContents when they are no longer needed.

typedef struct {
    int variationIndex;
    LDNode* reason;
} LDVariationDetails;

The LDVariationDetails struct provides the flag index and evaluation reason. For more about the content of the "reason" object, see:

typedef void (*LDlistenerfn)(const char *featurekey, int update);
bool LDClientRegisterFeatureFlagListener(LDClient *client, const char *featurekey, LDlistenerfn);
bool LDClientUnregisterFeatureFlagListener(LDClient *client, const char *featurekey, LDlistenerfn);

Register and unregister callbacks when features change. The name argument indicates the changed value. The update argument is 0 for new or updated and 1 for deleted.

LDNode *LDClientGetLockedFlags(LDClient *client);
void LDClientUnlockFlags(LDClient *client);

Directly access all flags. This locks the client until the flags are unlocked.

LDNode *LDAllFlags(LDClient *client);

Returns a hash table of all flags. This must be freed with LDNodeFree.

void LDClientTrack(LDClient *client, const char *name);
void LDClientTrackData(LDClient *client, const char *name, LDNode *data);

Record a custom event.

LDNode JSON interface

The LD client uses JSON to communicate, which is represented as LDNode structures. Both arrays and hashes (objects) are supported.

LDNode *LDNodeCreateHash();

Create a new empty hash. (Implementation note: empty hash is a NULL pointer, not indicative of failure).

void LDNodeAddBool(LDNode **hash, const char *key, bool b);
void LDNodeAddNumber(LDNode **hash, const char *key, double n);
void LDNodeAddString(LDNode **hash, const char *key, const char *s);
void LDNodeAddNode(LDNode **hash, const char *key, LDNode *m);

Add a new node to the hash table. Memory ownership: The string s will be duplicated internally. The Node m is not duplicated. It will be owned by the containing hash.

LDNode *LDNodeLookup(const LDNode *hash, const char *key);

Find a node in a hash. See below for structure.

void LDNodeFree(LDNode **hash);

Free a hash and all internal memory.

In addition to hash tables, arrays are also supported.

LDNode *LDNodeArray();

Create an empty array.

void LDNodeAppendBool(LDNode **array, bool b);
void LDNodeAppendNumber(LDNode **array, double n);
void LDNodeAppendString(LDNode **array, const char *s);

Add a bool, number, or string to an array.

LDNode *LDCloneHash(const LDNode *hash);
LDNode *LDCloneArray(const LDNode *array);

Return a deep copy of the originals.

LDNode *LDNodeIndex(const LDNode *array, unsigned int idx);

Retrieve the element at index idx.

char *LDHashToJSON(const LDNode *node)

Utility to convert a hash to a JSON object.

unsigned int LDNodeCount(const LDNode *hash);

Return the number of elements in a hash or array.

A Node node will have a type, one of string, number, bool, hash, or array. The corresponding union field, s, n, b, h, or a will be set.

typedef enum {
    LDNodeNone = 0,
} LDNodeType;

typedef struct {
    char *key;
    LDNodeType type;
    union {
        bool b;
        char *s;
        double n;
        LDNode *h;
        LDNode *a;
} LDNode;

Store interface

The client library supports persisting data between sessions or when internet connectivity is intermittent. This is exposed to the application via the LD_store interface which consists of two main functions.

void LD_store_setfns(void *context, LD_store_stringwriter, LD_store_stringreader);

LD_store_setfns sets the functions to be used. Reader and writer may optionally be NULL. The provided opaque context is passed to each open call.

typedef bool (*LD_store_stringwriter)(void *context, const char *name, const char *data);

Should write the data using the associated context to name. Returns true for success.

typedef char *(*LD_store_stringreader)(void *context, const char *name);

Read a string from the name associated with the context. Returns NULL on failure. Memory returned from the reader must come from LDAlloc.

A simple set of functions that operate on POSIX files is provided:

bool LD_store_filewrite(void *context, const char *name, const char *data);
char *LD_store_fileread(void *context, const char *name);


void LDSetLogFunction(int userlevel, void (userlogfn)(const char *))

Set the log function and log level. Increasing log levels result in increasing output. The current log levels are:

enum ld_log_level {
    LD_LOG_FATAL = 0,

Other utilities

void LDFree(void *)

Frees memory allocated by the SDK.

C++ interface

A C++ interface to LDClient is also available. Other C functions remain available.

class LDClient {
        static LDClient *Get();

Return the LDClient singleton.

        static LDClient *Init(LDConfig *config, LDUser *user);
        bool isInitialized();
        bool awaitInitialized(unsigned int timeoutmilli);

Initialize the client and functions to check the initialization status.

        bool boolVariation(const std::string &featurekey, bool defaultvalue);
        int intVariation(const std::string &featurekey, int defaultvalue);
        std::string stringVariation(const std::string &featurekey, const std::string &defaultvalue);
        char *stringVariation(const std::string &featurekey, const std::string &defaultvalue,
            char *buffer, size_t size);

Functions to ask for variations.

        LDNode *JSONVariation(const std::string &featurekey, const LDNode *defaultvalue);

Request a JSON variation. It must be freed.

        bool boolVariationDetail(const std::string &featurekey, bool defaultvalue, LDVariationDetails *details);
        int intVariationDetail(const std::string &featurekey, int defaultvalue, LDVariationDetails *details);
        double doubleVariationDetail(const std::string &featurekey, double defaultvalue, LDVariationDetails *details);
        std::string stringVariationDetail(const std::string &featurekey, const std::string &defaultvalue, LDVariationDetails *details);
        char *stringVariationDetail(const std::string &featurekey, const std::string &, char *defaultvalue, size_t, LDVariationDetails *details);
        LDNode *JSONVariationDetail(const std::string &featurekey, const LDNode *defaultvalue, LDVariationDetails *details);

Detail version of each evaluation variation.

        LDNode *getLockedFlags();
        void unlockFlags();
        LDNode *getAllFlags();

Functions to access or copy the flag store.

        void identify(LDUser *user);

Switch user and generate identify event, ownership of the user object is transferred to the client. This causes a reconnection to the LaunchDarkly servers and refreshes the flag store in the background. This should not be called frequently because of the performance implications. You may want to call awaitInitialized to wait until the updated flag store is ready.

        void setOffline();
        void setOnline();
        bool isOffline();
        std::string saveFlags();
        void restoreFlags(const std::string &flagsjson);
        void flush();
        void close();

In C++, LDNode has the following member functions.

class LDNode {
    LDNode *lookup(const std::string &key);

Find a subnode.

    LDNode *index(unsigned int idx);

Retrieve the element at index idx.