# Omniverse Client Library — C API Reference

Public header: `include/OmniClient.h` (~3000 lines). All functions use `extern "C"` with `OMNICLIENT_EXPORT`.

## Table of Contents

1. [Lifecycle](#lifecycle)
2. [Content Buffers](#content-buffers)
3. [Result Codes](#result-codes)
4. [URL Parsing](#url-parsing)
5. [Stat and List](#stat-and-list)
6. [File Read/Write](#file-readwrite)
7. [Folder Operations](#folder-operations)
8. [Copy and Move](#copy-and-move)
9. [Subscriptions](#subscriptions)
10. [Resolve](#resolve)
11. [Checkpoints and Versioning](#checkpoints-and-versioning)
12. [ACLs](#acls)
13. [Locking](#locking)
14. [Authentication](#authentication)
15. [Connection and File Status](#connection-and-file-status)
16. [Live Objects](#live-objects)
17. [Live Sessions](#live-sessions)
18. [User and Group Management](#user-and-group-management)
19. [Server Info](#server-info)
20. [Cloud Storage Configuration](#cloud-storage-configuration)
21. [OmniHub](#omnihub)
22. [Bookmarks](#bookmarks)
23. [Logging](#logging)
24. [Metrics](#metrics)
25. [Channels (Deprecated)](#channels-deprecated)

---

## Lifecycle

```c
omniClientInitialize(uint64_t version)          // Pass kOmniClientVersion
omniClientShutdown()                             // Call once at program exit
omniClientGetVersionString() -> char const*
omniClientSetProductInfo(name, version, extra)   // Identify your app to Nucleus
omniClientWriteChromeTrace()                     // Flush trace (needs OMNICLIENT_ENABLE_CHROME_TRACING)
```

## Content Buffers

```c
struct OmniClientContent {
    void* buffer;
    size_t size;
    void (*free)(void* buffer);  // nullptr if referenced (app owns)
};

omniClientAllocContent(size_t size) -> OmniClientContent     // Library takes ownership
omniClientReferenceContent(void* buf, size_t size) -> OmniClientContent  // App keeps ownership
omniClientMoveContent(OmniClientContent* content) -> OmniClientContent   // Take from callback
omniClientCopyContent(OmniClientContent const* content) -> OmniClientContent
omniClientFreeContent(OmniClientContent* content)
```

**Ownership rule**: In read callbacks, use `omniClientMoveContent()` to take ownership of the buffer. Otherwise it is freed after the callback returns.

## Result Codes

```c
enum OmniClientResult {
    eOmniClientResult_Ok,                    // Success
    eOmniClientResult_OkLatest,              // Live: have latest version
    eOmniClientResult_OkNotYetFound,         // Subscribe: not found but watching
    eOmniClientResult_Error,                 // Unknown error
    eOmniClientResult_ErrorConnection,       // Connection lost
    eOmniClientResult_ErrorNotSupported,     // Operation not supported
    eOmniClientResult_ErrorAccessDenied,     // No permission
    eOmniClientResult_ErrorNotFound,         // Item doesn't exist
    eOmniClientResult_ErrorAlreadyExists,    // Copy/move: destination exists
    eOmniClientResult_ErrorSourceIsDest,     // Source = destination
    eOmniClientResult_ErrorAccessLost,       // Item deleted or ACL changed
    eOmniClientResult_ErrorLocked,           // File locked by another client
    eOmniClientResult_ErrorBadRequest,       // Malformed HTTP request
    eOmniClientResult_FolderNotEmpty,        // Non-empty folder (obliterate/delete_single)
    eOmniClientResult_ErrorWrongType,        // Wrong item type for operation
    eOmniClientResult_ErrorUnsupportedVersion,
};

omniClientGetResultString(OmniClientResult result) -> char const*
```

### Request Control

```c
typedef uint64_t OmniClientRequestId;  // 0 = kInvalidRequestId

omniClientStop(OmniClientRequestId id)                          // Cancel request
omniClientWait(OmniClientRequestId id)                          // Block until done
omniClientWaitFor(OmniClientRequestId id, uint64_t ms) -> bool  // Wait with timeout
```

## URL Parsing

```c
struct OmniClientUrl {
    char const* scheme;    // "omniverse", "http", "file", etc.
    char const* user;
    char const* host;
    char const* port;
    char const* path;      // Percent-decoded
    char const* query;     // Percent-decoded
    char const* fragment;  // Percent-decoded
    bool isRaw;            // True for raw local paths (C:\file)
};

omniClientBreakUrl(char const* url) -> OmniClientUrl*
omniClientBreakUrlReference(char const* urlRef) -> OmniClientUrl*  // RFC 3986
omniClientFreeUrl(OmniClientUrl* url)

omniClientMakeUrl(OmniClientUrl const* url, char* buf, size_t* bufSize)
omniClientMakeFileUrl(char const* path, char* buf, size_t* bufSize)
omniClientNormalizeUrl(char const* url, char* buf, size_t* bufSize)
omniClientCombineUrls(char const* baseUrl, char const* otherUrl, char* buf, size_t* bufSize)
omniClientCombineUrls2(OmniClientUrl const* baseUrl, char const* otherUrl) -> OmniClientUrl*
omniClientMakeRelativeUrl(char const* baseUrl, char const* otherUrl, char* buf, size_t* bufSize)
omniClientMakePrintable(char const* str, char* buf, size_t* bufSize)
omniClientSetAlias(char const* src, char const* dst)  // dst=nullptr to remove
```

### Base URL Stack (Thread-Local)

```c
omniClientPushBaseUrl(char const* baseUrl)
omniClientPopBaseUrl(char const* baseUrl)  // Validates it matches top
omniClientGetBaseUrl() -> char const*      // nullptr if empty
omniClientCombineWithBaseUrl(char const* otherUrl, char* buf, size_t* bufSize)
```

## Stat and List

### Enums

```c
enum OmniClientAccessFlags {
    fOmniClientAccess_Read,   fOmniClientAccess_Write,
    fOmniClientAccess_Admin,  fOmniClientAccess_Full   // Read|Write|Admin
};

enum OmniClientItemFlags {
    fOmniClientItem_ReadableFile,        fOmniClientItem_WriteableFile,
    fOmniClientItem_CanHaveChildren,     fOmniClientItem_DoesNotHaveChildren,
    fOmniClientItem_IsMount,             fOmniClientItem_IsInsideMount,
    fOmniClientItem_CanLiveUpdate,       fOmniClientItem_IsOmniObject,
    fOmniClientItem_IsChannel,           fOmniClientItem_IsCheckpointed,
    fOmniClientItem_IsDeleted,
};

enum OmniClientListIncludeOption {
    eOmniClientListIncludeOption_DefaultNotDeleted,
    eOmniClientListIncludeOption_IncludeDeleted,
    eOmniClientListIncludeOption_OnlyDeleted,
};
```

### OmniClientListEntry

```c
struct OmniClientListEntry {
    const char* relativePath;   // Item name (or checkpoint query)
    uint32_t access;            // OmniClientAccessFlags bitmask
    uint32_t flags;             // OmniClientItemFlags bitmask
    uint64_t size;              // Bytes
    uint64_t modifiedTimeNs;    // Nanoseconds since epoch
    uint64_t createdTimeNs;
    const char* modifiedBy;
    const char* createdBy;
    const char* version;        // Provider-specific
    const char* hash;           // Provider-specific
    const char* comment;        // Checkpoints only
    uint64_t deletedTimeNs;
    const char* deletedBy;
    const char* lockedBy;       // nullptr if not locked
};
```

### Functions

```c
// Stat (single item)
omniClientStat(url, userData, callback) -> OmniClientRequestId
omniClientStat2(url, includeOption, userData, callback) -> OmniClientRequestId
// callback: void(void* ud, OmniClientResult, OmniClientListEntry const*)

// List (directory)
omniClientList(url, userData, callback) -> OmniClientRequestId
omniClientList2(url, includeOption, userData, callback) -> OmniClientRequestId
// callback: void(void* ud, OmniClientResult, uint32_t numEntries, OmniClientListEntry const*)

omniClientBypassListCache(bool bypass)
```

## File Read/Write

### Read

```c
omniClientReadFile(url, userData, callback) -> OmniClientRequestId
// callback: void(void* ud, OmniClientResult, char const* version, OmniClientContent*)
// Use omniClientMoveContent() in callback to take ownership of content
```

### Write

```c
omniClientWriteFile(url, content, userData, callback, message) -> OmniClientRequestId
// callback: void(void* ud, OmniClientResult)
// Library takes ownership of content

omniClientWriteFileEx(url, content, userData, callback, message) -> OmniClientRequestId
// callback: void(void* ud, OmniClientResult, OmniClientWriteFileExInfo const*)
// OmniClientWriteFileExInfo { version, hash }

omniClientWriteFileEx2(url, content, userData, callback, options) -> OmniClientRequestId
// OmniClientWriteFileEx2Options { version=1, skip_checkpoint, message }
```

### Hash-based Create

```c
omniClientCreateWithHash(url, hash, overwrite, userData, callback, message)
// Create placeholder for known content hash (dedup)
```

### Get Local File

```c
omniClientGetLocalFile(url, download, userData, callback)
// callback: void(void* ud, OmniClientResult, char const* localFilePath)
// Call omniClientStop() with returned ID to mark file closed in Hub cache
```

## Folder Operations

```c
omniClientCreateFolder(url, userData, callback)
omniClientDelete(url, userData, callback)             // Recursive
omniClientDeleteSingle(url, userData, callback)       // File or empty folder only
omniClientUndelete(url, userData, callback)            // Restore soft-deleted
omniClientObliterate(url, obliterateCheckpoints, userData, callback)  // Permanent, empty folders only
```

## Copy and Move

```c
enum OmniClientCopyBehavior {
    eOmniClientCopy_ErrorIfExists,
    eOmniClientCopy_Overwrite,
};

// Auto-detect file vs folder
omniClientCopy(srcUrl, dstUrl, userData, callback, behavior, message)
omniClientMove(srcUrl, dstUrl, userData, callback, behavior, message)
// Move callback: void(void* ud, OmniClientResult, bool copied)
// copied=true means cross-server copy+delete; false means server-side rename

// Explicit file/folder variants
omniClientCopyFile(srcUrl, dstUrl, userData, callback, behavior, message)
omniClientCopyFolder(srcUrl, dstUrl, userData, callback, behavior, message)
omniClientMoveFile(srcUrl, dstUrl, userData, callback, behavior, message)
omniClientMoveFolder(srcUrl, dstUrl, userData, callback, behavior, message)
```

## Subscriptions

```c
enum OmniClientListEvent {
    eOmniClientListEvent_Unknown,      eOmniClientListEvent_Created,
    eOmniClientListEvent_Updated,      eOmniClientListEvent_Deleted,
    eOmniClientListEvent_Metadata,     eOmniClientListEvent_Locked,
    eOmniClientListEvent_Unlocked,     eOmniClientListEvent_Obliterated,
};

// Stat subscribe: initial stat + ongoing updates
omniClientStatSubscribe(url, userData, statCallback, subscribeCallback)
omniClientStatSubscribe2(url, includeOption, userData, statCallback, subscribeCallback)
// subscribeCallback: void(void* ud, OmniClientResult, OmniClientListEvent, OmniClientListEntry const*)

// List subscribe: initial list + ongoing events
omniClientListSubscribe(url, userData, listCallback, subscribeCallback)
omniClientListSubscribe2(url, includeOption, userData, listCallback, subscribeCallback)
```

## Resolve

Search paths for files not found at primary location.

```c
omniClientResolve(relativePath, searchPaths[], numSearchPaths, userData, callback)
// callback: void(void* ud, OmniClientResult, OmniClientListEntry const*, char const* resolvedUrl)

omniClientResolveSubscribe(relativePath, searchPaths[], numSearchPaths, userData, callback, subscribeCallback)

// Default search path management
omniClientAddDefaultSearchPath(char const* searchPath)
omniClientRemoveDefaultSearchPath(char const* searchPath)
omniClientGetDefaultSearchPaths2() -> char const* const*  // Null-terminated array
omniClientFreeStringList(char const* const* list)
```

## Checkpoints and Versioning

```c
omniClientCreateCheckpoint(url, comment, force, userData, callback)
// callback: void(void* ud, OmniClientResult, char const* checkpointQuery)
// force=true creates even if unchanged

omniClientListCheckpoints(url, userData, callback)
// callback: void(void* ud, OmniClientResult, uint32_t numEntries, OmniClientListEntry const*)
// ListEntry::relativePath contains the query string

// Parse/build checkpoint queries
omniClientGetBranchAndCheckpointFromQuery(query) -> OmniClientBranchAndCheckpoint*
omniClientFreeBranchAndCheckpoint(OmniClientBranchAndCheckpoint*)
omniClientMakeQueryFromBranchAndCheckpoint(branch, checkpoint, buf, bufSize)
// Query format: "branch=name&checkpoint=30" or "name&30"
```

## ACLs

```c
struct OmniClientAclEntry {
    const char* name;    // User or group
    uint32_t access;     // OmniClientAccessFlags
};

omniClientGetAcls(url, userData, callback)
// callback: void(void* ud, OmniClientResult, uint32_t numEntries, OmniClientAclEntry*)

omniClientSetAcls(url, numEntries, entries[], userData, callback)
```

## Locking

```c
omniClientLock(url, userData, callback)    // Auto-unlocked on disconnect
omniClientUnlock(url, userData, callback)
```

## Authentication

### Auth Callback

```c
struct OmniClientCredentials {
    bool abort;                  // Set true to abort auth
    OmniClientContent token;     // Access token
    OmniClientContent username;
    OmniClientContent password;
};

// Return true if handled, false to try next callback
typedef bool(*OmniClientAuthCallback)(void* userData, char const* prefix, OmniClientCredentials* creds);

omniClientRegisterAuthCallback(userData, callback) -> uint32_t  // Returns handle
```

### Device Flow

```c
struct OmniClientAuthDeviceFlowParams {
    const char* server;
    const char* url;           // User visits this URL
    const char* code;          // User enters this code
    uint32_t expiration;       // Seconds
};

// params=nullptr means auth complete
typedef void(*OmniClientAuthDeviceFlowCallback)(void* ud, uint32_t authHandle, OmniClientAuthDeviceFlowParams const* params);

omniClientRegisterAuthDeviceFlowCallback(userData, callback) -> uint32_t
```

### Storage Auth (OmniStorage)

```c
// Return true if handling auth, false for fallback
typedef bool(*OmniClientStorageAuthCallback)(void* ud, uint32_t authHandle, char const* server);

omniClientRegisterStorageAuthCallback(userData, callback) -> uint32_t
omniClientSetStorageAccessToken(uint32_t authHandle, char const* accessToken) -> bool
```

### Other

```c
omniClientSignOut(char const* url)       // Disconnect + clear token
omniClientReconnect(char const* url)     // Force retry
omniClientAuthenticationCancel(uint32_t authHandle)
omniClientUnregisterCallback(uint32_t handle)  // Deregister any callback by handle
omniClientRefreshAuthToken(url, userData, callback)
```

## Connection and File Status

```c
enum OmniClientConnectionStatus {
    eOmniClientConnectionStatus_Connecting,
    eOmniClientConnectionStatus_Connected,
    eOmniClientConnectionStatus_ConnectError,
    eOmniClientConnectionStatus_Disconnected,
    eOmniClientConnectionStatus_SignedOut,
    eOmniClientConnectionStatus_AuthAbort,
    eOmniClientConnectionStatus_AuthCancelled,
    eOmniClientConnectionStatus_AuthError,
    eOmniClientConnectionStatus_AuthFailed,
    eOmniClientConnectionStatus_ServerIncompatible,
    eOmniClientConnectionStatus_InvalidHost,
};

// callback: void(void* ud, char const* url, OmniClientConnectionStatus)
omniClientRegisterConnectionStatusCallback(userData, callback) -> uint32_t

enum OmniClientFileStatus {
    eOmniClientFileStatus_Reading,    eOmniClientFileStatus_Writing,
    eOmniClientFileStatus_Copying,    eOmniClientFileStatus_Moving,
    eOmniClientFileStatus_Deleting,   eOmniClientFileStatus_Obliterating,
    eOmniClientFileStatus_Listing,    eOmniClientFileStatus_Stating,
};

// callback: void(void* ud, char const* url, OmniClientFileStatus, int percentage)
omniClientRegisterFileStatusCallback(userData, callback) -> uint32_t
```

## Live Objects

For Nucleus omni-object live collaboration.

### Update Types

```c
enum OmniClientLiveUpdateType {
    eOmniClientLiveUpdateType_Remote,   // From remote client
    eOmniClientLiveUpdateType_Local,    // Server ack of local update
    eOmniClientLiveUpdateType_More,     // Queued update ready
};
```

### Core Functions

```c
// Register for update notifications — CRITICAL: call omniClientLiveProcess() from main thread after notification
omniClientLiveRegisterQueuedCallback2(userData, callback) -> uint32_t
// callback: void(void* ud, OmniClientLiveUpdateInfo*)

omniClientLiveProcess()                              // Process pending updates (MAIN THREAD ONLY)
omniClientLiveProcessUpTo(url, serverTime)           // Process up to specific time
omniClientLiveGetLatestServerTime(url) -> uint64_t   // Latest server timestamp
omniClientLiveWaitForPendingUpdates()                // Block until all pending updates complete

// Jitter reduction: delay = sentTime + min(delayMax, delayConst + delayMult * avgLatency) - receivedTime
omniClientLiveConfigureJitterReduction(delayConstantMs, delayMultiple, delayMaximumMs)
// Default: 10ms constant, 2x average ping, 1s max. Pass (0,0,0) to disable.
```

### Read/Write

```c
omniClientLiveRead(url, haveObjectId, haveSequenceNum, userData, callback)
// Provide haveObjectId/Seq if you have a previous version (server sends delta)
// Callback receives: zero or more Ok, then OkLatest, then zero or more Ok
// Requires omniClientLiveProcess() calls

omniClientLiveRead2(url, haveObjectId, haveSequenceNum, userData, callback)
// Same but does NOT require omniClientLiveProcess()

omniClientLiveCreate(url, content, userData, callback)
// callback: void(void* ud, OmniClientResult, uint64_t objectId, uint64_t sequenceNum)

omniClientLiveUpdate(url, objectId, content, userData, callback)
// callback: void(void* ud, OmniClientResult, uint64_t sequenceNum, uint64_t requestId)

omniClientLiveUpdate2(url, objectId, content, userData, callback)
// Same but does NOT require omniClientLiveProcess()
```

## Live Sessions

Higher-level collaboration API for session management, user presence, and messaging.

```c
struct OmniClientLiveSessionInfo {
    const char* sessionUrl;
    const char* sessionName;
    const char* sessionOwner;
    uint64_t modifiedTimestamp;  // Nanoseconds since epoch
};

omniClientLiveListSessions(baseLayerUrl, userData, callback)
// callback: void(void* ud, OmniClientResult, uint32_t count, OmniClientLiveSessionInfo const*)

omniClientLiveCreateSession(baseLayerUrl, sessionName, userData, callback)
// callback: void(void* ud, OmniClientResult, const char* sessionUrl)

enum OmniClientLiveSessionEventType {
    eOmniClientLiveSessionEvent_Connection,  // Your connection_id
    eOmniClientLiveSessionEvent_Joined,      // Peer joined
    eOmniClientLiveSessionEvent_Left,        // Peer left
    eOmniClientLiveSessionEvent_Message,     // Message received
};

struct OmniClientLiveSessionEvent {
    OmniClientLiveSessionEventType eventType;
    const char* connectionId;
    const char* userName;       // Joined only
    const char* appName;        // Joined only
    const void* messageData;    // Message only
    size_t messageSize;
};

omniClientLiveJoinSession(sessionUrl, appName, userData, eventCallback) -> OmniClientRequestId
// First event is Connection (your connectionId)
// Call omniClientStop() with returned ID to leave

omniClientLiveSendMessage(sessionId, content, userData, callback)
// sessionId from omniClientLiveJoinSession()
```

## User and Group Management

```c
omniClientGetGroups(url, userData, callback)
omniClientGetGroupUsers(url, group, userData, callback)
omniClientCreateGroup(url, group, userData, callback)
omniClientRenameGroup(url, group, newGroup, userData, callback)
omniClientRemoveGroup(url, group, userData, callback)
omniClientGetUsers(url, userData, callback)
omniClientGetUserGroups(url, user, userData, callback)
omniClientAddUserToGroup(url, user, group, userData, callback)
omniClientRemoveUserFromGroup(url, user, group, userData, callback)
```

## Server Info

```c
struct OmniClientServerInfo {
    char const* version;
    char const* username;
    char const* authToken;
    char const* connectionId;
    bool cacheEnabled;
    bool omniObjectsEnabled;
    bool checkpointsEnabled;
    bool atomicCheckpoints;
    bool undeleteEnabled;
};

omniClientGetServerInfo(url, userData, callback)
```

## Cloud Storage Configuration

```c
// S3 (various overloads for session token and canonical host)
omniClientSetS3Configuration(host, bucket, region, accessKeyId, secretAccessKey,
                              cloudfrontUrl, cloudfrontForList, writeConfig)
omniClientSetS3Configuration2(..., sessionToken, ...)
omniClientSetS3Configuration3(..., sessionToken, canonicalHost, ...)

// Azure
omniClientSetAzureSASToken(host, container, sasToken, writeConfig)

// Generic HTTP headers
omniClientSetHttpHeader(key, value)  // value=nullptr to remove

// Cache
omniClientClearListCache(url) -> bool  // Clear list/stat cache for provider

// Storage registration
omniClientRegisterStorageFromDiscovery(discoveryUrl, userData, callback)
omniClientRegisterStorageDirect(OmniClientStorageRegistrationInfo*, userData, callback)
```

## OmniHub

```c
omniClientGetOmniHubVersion(userData, callback)
omniClientGetOmniHubHttpUri(userData, callback)
```

## Bookmarks

```c
struct OmniClientBookmark { char const* name; char const* url; };

omniClientAddBookmark(name, url)
omniClientRemoveBookmark(name)
omniClientListBookmarks(userData, callback)  // Subscribes to changes
```

## Logging

```c
enum OmniClientLogLevel {
    eOmniClientLogLevel_Debug, eOmniClientLogLevel_Verbose,
    eOmniClientLogLevel_Info,  eOmniClientLogLevel_Warning,
    eOmniClientLogLevel_Error,
};

omniClientSetLogCallback(callback)  // Safe to call before initialize
omniClientSetLogLevel(level)
omniClientGetLogLevelString(level) -> char const*
```

## Metrics

```c
struct OmniClientMetricsGrpc {
    uint16_t grpcStatusCode; uint64_t durationNs;
    char const* callName; char const* parameters;
};

struct OmniClientMetricsHttp {
    uint16_t httpStatusCode; uint64_t durationNs;
    char const* method; char const* url;
    uint64_t bytesUploaded; uint64_t bytesDownloaded;
};

enum OmniClientMetricsEvent {
    eOmniClientMetricsEvent_Grpc = 100,  // extraInfo = OmniClientMetricsGrpc*
    eOmniClientMetricsEvent_Http = 101,  // extraInfo = OmniClientMetricsHttp*
};

omniClientRegisterMetricsCallback(userData, callback) -> uint32_t
```

## Channels (Deprecated)

Use Live Sessions instead.

```c
enum OmniClientChannelEvent {
    eOmniClientChannelEvent_Error,   eOmniClientChannelEvent_Message,
    eOmniClientChannelEvent_Hello,   eOmniClientChannelEvent_Join,
    eOmniClientChannelEvent_Left,    eOmniClientChannelEvent_Deleted,
};

omniClientJoinChannel(url, userData, callback)         // Creates channel if needed
omniClientSendMessage(joinRequestId, content, userData, callback)
```

## Retry Configuration

```c
struct OmniClientRetryBehavior {
    uint32_t maxMs;      // Max retry time (0 = disabled). Default: 120000
    uint32_t baseMs;     // Base delay (multiplied by count^2). Default: 100
    uint32_t jitterMs;   // Random jitter (multiplied by count). Default: 100
};
// Delay = baseMs * count^2 + random(0, jitterMs * count)

omniClientSetRetries(retryBehavior) -> OmniClientRetryBehavior  // Returns previous
```

## Tracing

```c
omniClientTraceStart() -> bool   // Enable carb::tracer
omniClientTraceStop()            // Disable
```
