Skip to main content

SDK API Overview

The SpacetimeDB client SDKs provide a comprehensive API for interacting with your database. After generating client bindings and establishing a connection, you can query data, invoke server functions, and observe real-time changes.

This page describes the core concepts and patterns that apply across all client SDKs. For language-specific details and complete API documentation, see the reference pages for Rust, C#, TypeScript, or Unreal Engine.

Prerequisites

Before using the SDK API, you must:

  1. Generate client bindings using spacetime generate
  2. Create a connection to your database

Subscriptions

Subscriptions replicate a subset of the database to your client, maintaining a local cache that automatically updates as the server state changes. Clients should subscribe to the data they need, then query the local cache.

Creating Subscriptions

Subscribe to tables or queries using SQL:

// Subscribe with callbacks
conn.subscription_builder()
    .on_applied(|ctx| {
        println!("Subscription ready with {} users", ctx.db().user().count());
    })
    .on_error(|ctx, error| {
        eprintln!("Subscription failed: {}", error);
    })
    .subscribe(["SELECT * FROM user"]);

See the Subscriptions documentation for detailed information on subscription queries and semantics. Subscribe to tables for row data, or to views for computed query results.

Querying the Local Cache

Once subscribed, query the local cache without network round-trips:

// Iterate all cached rows
for user in conn.db().user().iter() {
    println!("{}: {}", user.id, user.name);
}

// Count cached rows
let user_count = conn.db().user().count();

// Find by unique column (if indexed)
if let Some(user) = conn.db().user().name().find("Alice") {
    println!("Found: {}", user.email);
}

// Filter cached rows
let admin_users: Vec<_> = conn.db().user()
    .iter()
    .filter(|u| u.is_admin)
    .collect();

Row Update Callbacks

Register callbacks to observe insertions, updates, and deletions in the local cache:

// Called when a row is inserted
conn.db().user().on_insert(|ctx, user| {
    println!("User inserted: {}", user.name);
});

// Called when a row is updated
conn.db().user().on_update(|ctx, old_user, new_user| {
    println!("User {} updated: {} -> {}", 
        new_user.id, old_user.name, new_user.name);
});

// Called when a row is deleted
conn.db().user().on_delete(|ctx, user| {
    println!("User deleted: {}", user.name);
});

These callbacks fire whenever the local cache changes due to subscription updates, providing real-time reactivity.

Complete Examples

For complete working examples, see the language-specific reference pages: