Skip to main content
The Native API (boxlite_*) provides full-featured, flexible control over BoxLite with JSON configuration, streaming output callbacks, and advanced features like volumes and networking.

Box Creation

boxlite_create_box

Create and auto-start a box.
BoxliteErrorCode boxlite_create_box(
    CBoxliteRuntime* runtime,
    const char* options_json,
    CBoxHandle** out_box,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
runtimeCBoxliteRuntime*Runtime instance
options_jsonconst char*JSON-encoded BoxOptions
out_boxCBoxHandle**Output: box handle
out_errorCBoxliteError*Output: error information

Example

// Minimal options (required fields)
const char* options = "{"
    "\"rootfs\":{\"Image\":\"alpine:3.19\"},"
    "\"env\":[],\"volumes\":[],\"network\":\"Isolated\",\"ports\":[]"
"}";

CBoxHandle* box = NULL;
if (boxlite_create_box(runtime, options, &box, &error) != Ok) {
    fprintf(stderr, "Error: %s\n", error.message);
    boxlite_error_free(&error);
}

boxlite_start_box

Start or restart a stopped box.
BoxliteErrorCode boxlite_start_box(
    CBoxHandle* handle,
    CBoxliteError* out_error
);

boxlite_stop_box

Stop a running box.
BoxliteErrorCode boxlite_stop_box(
    CBoxHandle* handle,
    CBoxliteError* out_error
);
Consumes the handle - do not use after calling.

boxlite_remove

Remove a box.
BoxliteErrorCode boxlite_remove(
    CBoxliteRuntime* runtime,
    const char* id_or_name,
    int force,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
runtimeCBoxliteRuntime*Runtime instance
id_or_nameconst char*Box ID (full or prefix) or name
forceintNon-zero to force remove running box
out_errorCBoxliteError*Output: error information

boxlite_get

Reattach to an existing box.
BoxliteErrorCode boxlite_get(
    CBoxliteRuntime* runtime,
    const char* id_or_name,
    CBoxHandle** out_handle,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
runtimeCBoxliteRuntime*Runtime instance
id_or_nameconst char*Box ID (full or prefix) or name
out_handleCBoxHandle**Output: box handle
out_errorCBoxliteError*Output: error information

boxlite_box_id

Get box ID string from handle.
char* boxlite_box_id(CBoxHandle* handle);
Caller must free the returned string with boxlite_free_string().

Command Execution

boxlite_execute

Execute a command with optional streaming output.
BoxliteErrorCode boxlite_execute(
    CBoxHandle* handle,
    const char* command,
    const char* args_json,
    void (*callback)(const char* text, int is_stderr, void* user_data),
    void* user_data,
    int* out_exit_code,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
handleCBoxHandle*Box handle
commandconst char*Command to execute
args_jsonconst char*JSON array of arguments, e.g., ["arg1", "arg2"]
callbackfunction pointerOptional streaming output callback
user_datavoid*User data passed to callback
out_exit_codeint*Output: command exit code
out_errorCBoxliteError*Output: error information

Callback Signature

void callback(const char* text, int is_stderr, void* user_data);
ParameterDescription
textOutput text chunk
is_stderr0 for stdout, 1 for stderr
user_dataUser data from boxlite_execute

Example

void output_handler(const char* text, int is_stderr, void* data) {
    FILE* stream = is_stderr ? stderr : stdout;
    fprintf(stream, "%s", text);
}

int exit_code = 0;
BoxliteErrorCode code = boxlite_execute(
    box,
    "python",
    "[\"-c\", \"print('hello')\"]",
    output_handler,
    NULL,
    &exit_code,
    &error
);

if (code == Ok) {
    printf("Exit code: %d\n", exit_code);
}

Lifecycle Functions

boxlite_runtime_shutdown

Gracefully stop all running boxes.
BoxliteErrorCode boxlite_runtime_shutdown(
    CBoxliteRuntime* runtime,
    int timeout,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
runtimeCBoxliteRuntime*Runtime instance
timeoutintSeconds: 0=default(10), -1=infinite, >0=custom
out_errorCBoxliteError*Output: error information

boxlite_runtime_free

Free a runtime instance.
void boxlite_runtime_free(CBoxliteRuntime* runtime);
Safe to call with NULL. Automatically frees all boxes.

Discovery & Introspection

boxlite_list_info

List all boxes as JSON.
BoxliteErrorCode boxlite_list_info(
    CBoxliteRuntime* runtime,
    char** out_json,
    CBoxliteError* out_error
);
Returns JSON array. Caller must free out_json with boxlite_free_string().

boxlite_get_info

Get single box info as JSON.
BoxliteErrorCode boxlite_get_info(
    CBoxliteRuntime* runtime,
    const char* id_or_name,
    char** out_json,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
runtimeCBoxliteRuntime*Runtime instance
id_or_nameconst char*Box ID (full or prefix) or name
out_jsonchar**Output: JSON string (caller must free with boxlite_free_string())
out_errorCBoxliteError*Output: error information

boxlite_box_info

Get box info from handle as JSON.
BoxliteErrorCode boxlite_box_info(
    CBoxHandle* handle,
    char** out_json,
    CBoxliteError* out_error
);
Example JSON output:
{
  "id": "01HJK4TNRPQSXYZ8WM6NCVT9R5",
  "name": null,
  "state": {
    "status": "running",
    "running": true,
    "pid": 12345
  },
  "created_at": "2024-01-15T10:30:00Z",
  "image": "alpine:3.19",
  "cpus": 2,
  "memory_mib": 512
}

Complete Native API Example

#include <stdio.h>
#include "boxlite.h"

void output_callback(const char* text, int is_stderr, void* user_data) {
    FILE* stream = is_stderr ? stderr : stdout;
    fprintf(stream, "%s", text);
}

int main() {
    CBoxliteRuntime* runtime = NULL;
    CBoxHandle* box = NULL;
    CBoxliteError error = {0};

    // Create runtime
    if (boxlite_runtime_new(NULL, NULL, &runtime, &error) != Ok) {
        fprintf(stderr, "Error %d: %s\n", error.code, error.message);
        boxlite_error_free(&error);
        return 1;
    }

    // Create box with JSON configuration
    const char* options = "{"
        "\"rootfs\":{\"Image\":\"alpine:3.19\"},"
        "\"env\":[],\"volumes\":[],\"network\":\"Isolated\",\"ports\":[]"
    "}";

    if (boxlite_create_box(runtime, options, &box, &error) != Ok) {
        fprintf(stderr, "Error %d: %s\n", error.code, error.message);
        boxlite_error_free(&error);
        boxlite_runtime_free(runtime);
        return 1;
    }

    // Execute command with streaming output
    int exit_code = 0;
    const char* args = "[\"-la\", \"/\"]";

    if (boxlite_execute(box, "/bin/ls", args, output_callback, NULL, &exit_code, &error) == Ok) {
        printf("\nExit code: %d\n", exit_code);
    } else {
        fprintf(stderr, "Error: %s\n", error.message);
        boxlite_error_free(&error);
    }

    // Cleanup
    boxlite_runtime_free(runtime);
    return 0;
}

Migration from v0.1.x

Error Handling Change

v0.1.x (old):
char* error = NULL;
CBoxliteRuntime* runtime = boxlite_runtime_new(NULL, NULL, &error);
if (!runtime) {
    fprintf(stderr, "Error: %s\n", error);
    boxlite_free_string(error);
    return 1;
}
v0.2.0 (new):
CBoxliteRuntime* runtime = NULL;
CBoxliteError error = {0};
BoxliteErrorCode code = boxlite_runtime_new(NULL, NULL, &runtime, &error);
if (code != Ok) {
    fprintf(stderr, "Error %d: %s\n", error.code, error.message);
    boxlite_error_free(&error);
    return 1;
}

Execute Change

v0.1.x:
int exit_code = boxlite_execute(box, "echo", "[\"hello\"]", callback, NULL, &error);
if (exit_code < 0) {
    // Error
}
v0.2.0:
int exit_code = 0;
BoxliteErrorCode code = boxlite_execute(box, "echo", "[\"hello\"]", callback, NULL, &exit_code, &error);
if (code != Ok) {
    // Error
}

Migration Checklist

  • Replace char* error = NULL with CBoxliteError error = {0}
  • Initialize output pointers to NULL (e.g., CBoxliteRuntime* runtime = NULL)
  • Update all function calls to use output parameters
  • Replace return value checks with BoxliteErrorCode checks
  • Replace boxlite_free_string(error) with boxlite_error_free(&error)
  • Update JSON options to include all required fields