InstantDB API
Complete API reference for the core InstantDB class
The InstantDB class is the main entry point for interacting with your InstantDB database. It provides methods for initialization, queries, transactions, authentication, and real-time synchronization.
Initialization
InstantDB.init()
Initialize a new InstantDB instance.
static Future<InstantDB> init({
required String appId,
InstantConfig config = const InstantConfig(),
})Parameters:
appId(String): Your InstantDB application IDconfig(InstantConfig, optional): Configuration options
Returns: Future<InstantDB> - The initialized database instance
Example:
final db = await InstantDB.init(
appId: 'your-app-id',
config: const InstantConfig(
syncEnabled: true,
verboseLogging: false,
),
);InstantConfig
Configuration options for InstantDB initialization.
class InstantConfig {
const InstantConfig({
this.persistenceDir,
this.syncEnabled = true,
this.baseUrl = 'https://api.instantdb.com',
this.maxCacheSize = 50 * 1024 * 1024, // 50MB
this.reconnectDelay = const Duration(seconds: 1),
this.verboseLogging = false,
});
final String? persistenceDir;
final bool syncEnabled;
final String baseUrl;
final int maxCacheSize;
final Duration reconnectDelay;
final bool verboseLogging;
}Properties:
persistenceDir(String?): Custom directory for SQLite database storagesyncEnabled(bool): Enable real-time synchronization (default:true)baseUrl(String): Custom API endpoint URL (default:https://api.instantdb.com)maxCacheSize(int): Maximum size of the local database cache in bytes (default: 50MB)reconnectDelay(Duration): Delay between reconnection attempts (default: 1 second)verboseLogging(bool): Enable detailed debug logging (default:false)
Core Properties
isReady
A reactive signal indicating if the database is initialized and ready for use.
ReadonlySignal<bool> get isReadyExample:
if (db.isReady.value) {
print('Database is ready');
}isOnline
A reactive signal indicating if the database is currently connected to the sync server.
ReadonlySignal<bool> get isOnlineExample:
Watch((context) {
final online = db.isOnline.value;
return Text(online ? 'Connected' : 'Disconnected');
});appId
Get the application ID for this database instance.
String get appIdReturns: String - The application ID
Example:
print('Database app ID: ${db.appId}');auth
Access the authentication manager.
AuthManager get authReturns: AuthManager - The authentication manager instance
Example:
final currentUser = db.auth.currentUser.value;
if (currentUser != null) {
print('User: ${currentUser.email}');
}presence
Access the presence manager for real-time collaboration.
PresenceManager get presenceReturns: PresenceManager - The presence manager instance
Example:
final room = db.presence.joinRoom('chat-room');
await room.setPresence({'status': 'online'});syncEngine
Access the internal synchronization engine. Note that most synchronization logic is handled automatically through db.query and db.transact.
SyncEngine get syncEngineReturns: SyncEngine - The sync engine instance
Query Methods
query()
Create a reactive query that updates automatically when data changes. This is the preferred method for getting data.
Signal<QueryResult> query(Map<String, dynamic> query, {bool syncedOnly = false})Parameters:
query(Map<String, dynamic>): The InstaQL query objectsyncedOnly(bool, optional): If true, only returns entities that sync to cloud (excludes local-only entities)
Returns: Signal<QueryResult> - A reactive signal containing query results
Example:
final todosSignal = db.query({
'todos': {
'where': {'completed': false},
'orderBy': {'createdAt': 'desc'},
'limit': 20,
},
});subscribeQuery()
Alias for query(), kept for API compatibility.
Signal<QueryResult> subscribeQuery(Map<String, dynamic> query)Example:
final todosSignal = db.subscribeQuery({
'todos': {
'where': {'completed': false},
'orderBy': {'createdAt': 'desc'},
'limit': 20,
},
});
// Use in reactive widgets
Watch((context) {
final result = todosSignal.value;
final todos = result.data?['todos'] ?? [];
return TodoList(todos: todos);
});queryOnce()
Execute a one-time query without creating a subscription.
Future<QueryResult> queryOnce(Map<String, dynamic> query, {bool syncedOnly = false})Parameters:
query(Map<String, dynamic>): The InstaQL query objectsyncedOnly(bool, optional): If true, only returns entities that sync to cloud
Returns: Future<QueryResult> - The query result
Example:
final result = await db.queryOnce({
'users': {
'where': {'role': 'admin'},
'limit': 5,
},
});
final adminUsers = result.data?['users'] ?? [];
print('Found ${adminUsers.length} admin users');Transaction Methods
transact()
Execute a transaction with a list of operations or transaction chunk.
Future<TransactionResult> transact(dynamic transaction)Parameters:
transaction(List<Operation>orTransactionChunk): The operations to execute
Returns: Future<TransactionResult> - The transaction result
Example:
// With list of operations
await db.transact([
...db.create('todos', {
'id': db.id(),
'text': 'Learn InstantDB',
'completed': false,
}),
]);
// With transaction chunk (new tx API)
await db.transact(
db.tx['todos'][todoId].update({'completed': true})
);transactChunk() (Deprecated)
Execute a transaction chunk. Use transact() instead.
@Deprecated('Use transact() instead')
Future<TransactionResult> transactChunk(TransactionChunk chunk)create()
Create a new entity operation.
List<Operation> create(String entityType, Map<String, dynamic> data)Parameters:
entityType(String): The type of entity to createdata(Map<String, dynamic>): The entity data
Returns: List<Operation> - List containing the create operation
Example:
final operations = db.create('posts', {
'id': db.id(),
'title': 'Hello World',
'content': 'This is my first post',
'authorId': userId,
'createdAt': DateTime.now().millisecondsSinceEpoch,
});
await db.transact(operations);update()
Create an update entity operation.
Operation update(String entityId, Map<String, dynamic> data)Parameters:
entityId(String): The ID of the entity to updatedata(Map<String, dynamic>): The data to update
Returns: Operation - The update operation
Example:
await db.transact([
db.update(postId, {
'title': 'Updated Title',
'updatedAt': DateTime.now().millisecondsSinceEpoch,
}),
]);delete()
Create a delete entity operation.
Operation delete(String entityId)Parameters:
entityId(String): The ID of the entity to delete
Returns: Operation - The delete operation
Example:
await db.transact([
db.delete(postId),
]);merge()
Create a deep merge operation.
Operation merge(String entityId, Map<String, dynamic> data)Parameters:
entityId(String): The ID of the entity to mergedata(Map<String, dynamic>): The data to deep merge
Returns: Operation - The merge operation
Example:
await db.transact([
db.merge(userId, {
'preferences': {
'theme': 'dark',
'notifications': {'email': false},
},
}),
]);link()
Create a link operation between entities.
Operation link(String fromId, String linkName, String toId)Parameters:
fromId(String): The source entity IDlinkName(String): The name of the link relationshiptoId(String): The target entity ID
Returns: Operation - The link operation
Example:
await db.transact([
db.link(userId, 'posts', postId),
]);unlink()
Create an unlink operation between entities.
Operation unlink(String fromId, String linkName, String toId)Parameters:
fromId(String): The source entity IDlinkName(String): The name of the link relationshiptoId(String): The target entity ID
Returns: Operation - The unlink operation
Example:
await db.transact([
db.unlink(userId, 'posts', postId),
]);Transaction API (tx namespace)
tx
Access the new transaction API namespace for fluent operations.
TransactionNamespace get txReturns: TransactionNamespace - The transaction namespace
Example:
// Fluent API for complex operations
await db.transact(
db.tx['users'][userId]
.update({'name': 'New Name'})
.link({'posts': [postId]})
.merge({
'preferences': {'theme': 'dark'},
})
);Utility Methods
id()
Generate a new UUID for entity IDs.
String id()Returns: String - A new UUID string
Example:
final newId = db.id();
print('Generated ID: $newId'); // e.g., "123e4567-e89b-12d3-a456-426614174000"
await db.transact([
...db.create('items', {
'id': newId,
'name': 'New Item',
}),
]);lookup()
Create a lookup reference for referencing entities by attribute instead of ID.
LookupRef lookup(String entityType, String attribute, dynamic value)Parameters:
entityType(String): The type of entity to lookupattribute(String): The attribute to match againstvalue(dynamic): The value to match
Returns: LookupRef - A lookup reference object
Example:
// Reference user by email instead of ID
await db.transact([
...db.create('posts', {
'id': db.id(),
'title': 'Hello World',
'authorId': lookup('users', 'email', 'john@example.com'),
}),
]);
// Use in queries
final posts = db.subscribeQuery({
'posts': {
'where': {
'author': lookup('users', 'email', 'john@example.com'),
},
},
});Authentication Helpers
getAuth()
Get the current authentication state (one-time check).
AuthUser? getAuth()Returns: AuthUser? - The current user, or null if not authenticated
Example:
final currentUser = db.getAuth();
if (currentUser != null) {
print('Logged in as: ${currentUser.email}');
} else {
print('Not logged in');
}subscribeAuth()
Get a stream of authentication state changes.
Stream<AuthUser?> subscribeAuth()Returns: Stream<AuthUser?> - A stream of auth user state
Example:
db.subscribeAuth().listen((user) {
if (user != null) {
print('User signed in: ${user.email}');
} else {
print('User signed out');
}
});getAnonymousUserId()
Get or generate an anonymous user ID for presence and collaboration.
String getAnonymousUserId()Returns: String - An anonymous user ID
Example:
final anonymousId = db.getAnonymousUserId();
final room = db.presence.joinRoom('public-room', initialPresence: {
'userId': anonymousId,
'userName': 'Guest ${anonymousId.substring(0, 4)}',
});Lifecycle Methods
dispose()
Clean up database resources and connections.
Future<void> dispose()Returns: Future<void>
Example:
@override
void dispose() {
super.dispose();
// Clean up database when app is disposed
db.dispose();
}Error Handling
All InstantDB methods can throw InstantException for database-related errors:
try {
await db.transact([
...db.create('invalid', {}), // Missing required fields
]);
} on InstantException catch (e) {
print('InstantDB Error: ${e.code}');
print('Message: ${e.message}');
// Handle specific error types
switch (e.code) {
case 'validation_error':
// Handle validation errors
break;
case 'network_error':
// Handle network issues
break;
case 'auth_error':
// Handle authentication errors
break;
}
} catch (e) {
print('Unexpected error: $e');
}Complete Example
Here's a complete example showing common InstantDB operations:
class TodoService {
final InstantDB db;
TodoService(this.db);
// Get reactive todos
Signal<QueryResult> getTodos({bool? completed}) {
return db.subscribeQuery({
'todos': {
if (completed != null) 'where': {'completed': completed},
'orderBy': {'createdAt': 'desc'},
},
});
}
// Create a new todo
Future<void> createTodo({
required String text,
bool completed = false,
}) async {
await db.transact([
...db.create('todos', {
'id': db.id(),
'text': text,
'completed': completed,
'createdAt': DateTime.now().millisecondsSinceEpoch,
'userId': db.auth.currentUser.value?.id,
}),
]);
}
// Update todo using new tx API
Future<void> updateTodo(String todoId, {String? text, bool? completed}) async {
final updates = <String, dynamic>{};
if (text != null) updates['text'] = text;
if (completed != null) updates['completed'] = completed;
updates['updatedAt'] = DateTime.now().millisecondsSinceEpoch;
await db.transact(
db.tx['todos'][todoId].update(updates)
);
}
// Delete todo
Future<void> deleteTodo(String todoId) async {
await db.transact([db.delete(todoId)]);
}
// Get todos by user email (using lookup)
Signal<QueryResult> getTodosByUser(String email) {
return db.subscribeQuery({
'todos': {
'where': {
'user': lookup('users', 'email', email),
},
},
});
}
// Bulk operations
Future<void> markAllCompleted() async {
final result = await db.queryOnce({
'todos': {'where': {'completed': false}},
});
final todos = (result.data?['todos'] as List? ?? [])
.cast<Map<String, dynamic>>();
final operations = todos.map((todo) =>
db.update(todo['id'], {'completed': true})
).toList();
if (operations.isNotEmpty) {
await db.transact(operations);
}
}
}Next Steps
Explore specific API areas:
- Transactions API - Detailed transaction and operation methods
- Queries API - Advanced querying and InstaQL syntax
- Presence API - Real-time collaboration methods
- Flutter Widgets - Reactive UI components
- Types Reference - Complete type definitions