Store your API key securely. Never commit API keys to version control. Use BuildConfig fields, encrypted shared preferences, or fetch ephemeral keys from your backend.
For production Android apps using the Realtime API, fetch short-lived client tokens from your backend instead of embedding your permanent API key in the APK:
// Fetch ephemeral key from your backendval ephemeralKey = fetchTokenFromBackend()// Use it to create the clientval client = DecartClient( context = applicationContext, config = DecartClientConfig(apiKey = ephemeralKey))
See Client Tokens for details on secure client-side authentication.
Use these with client.queue.submit() or client.queue.submitAndPoll():
import ai.decart.sdk.VideoModelsVideoModels.LUCY_2_1 // Video editing (latest)VideoModels.LUCY_2_1_VTON // Virtual try-onVideoModels.LUCY_2 // Video editingVideoModels.LUCY_RESTYLE_2 // Video restylingVideoModels.LUCY_MOTION // Motion video (trajectory-guided)// Latest aliasesVideoModels.LUCY_LATEST // Always the latest editing modelVideoModels.LUCY_VTON_LATEST // Always the latest virtual try-on model
The SDK uses Kotlin coroutines and Flow for reactive state management:
import kotlinx.coroutines.flow.collectimport kotlinx.coroutines.launch// Realtime connection state as StateFlowlifecycleScope.launch { client.realtime.connectionState.collect { state -> println("Connection: $state") }}// Errors as SharedFlowlifecycleScope.launch { client.realtime.errors.collect { error -> println("Error: ${error.code} — ${error.message}") }}// Queue job progress as Flowclient.queue.submitAndObserve(model, input).collect { update -> when (update) { is QueueJobResult.InProgress -> println("Status: ${update.status}") is QueueJobResult.Completed -> saveVideo(update.data) is QueueJobResult.Failed -> showError(update.error) }}
All realtime state is exposed as Kotlin StateFlow or SharedFlow. Collect them in a lifecycle-aware scope (e.g., lifecycleScope or viewModelScope) to avoid leaks.
Request camera permission at runtime before connecting:
val launcher = rememberLauncherForActivityResult( ActivityResultContracts.RequestPermission()) { granted -> if (granted) { // Start camera and connect }}launcher.launch(Manifest.permission.CAMERA)
Realtime tab — Camera capture + WebRTC streaming with live prompt changes
Video tab — Batch job submission, status updates, and result playback
For a more complete app showcasing real-world use cases — video restyling, 90+ style presets, multiple view modes, and swipe navigation — see the Decart Android Example App.
Build realtime Android experiencesComplete guide with Jetpack Compose examples for camera handling, video transformation, and interactive applications.
Queue API Guide
Batch video processingEdit videos, control motion, and transform videos with typed input classes and Flow-based progress tracking.