> ## Documentation Index
> Fetch the complete documentation index at: https://docs.platform.decart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> An Android SDK for Decart's realtime and video processing models

<Card title="GitHub" icon="github" href="https://github.com/DecartAI/decart-android">
  View source code and contribute
</Card>

## Installation

### Gradle (JitPack)

Add the JitPack repository to your `settings.gradle.kts`:

```kotlin settings.gradle.kts theme={null}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}
```

Add the dependency to your app's `build.gradle.kts`:

```kotlin build.gradle.kts theme={null}
dependencies {
    implementation("com.github.DecartAI:decart-android:0.6.0")
}
```

## Quick Start

```kotlin theme={null}
import ai.decart.sdk.DecartClient
import ai.decart.sdk.DecartClientConfig
import ai.decart.sdk.realtime.ConnectOptions
import ai.decart.sdk.realtime.InitialPrompt
import ai.decart.sdk.RealtimeModels

val client = DecartClient(context, DecartClientConfig(apiKey = "your-api-key"))
val realtime = client.realtime

// Initialize WebRTC
realtime.initialize(eglBase)

// Connect with a camera track
realtime.connect(
    localVideoTrack = cameraTrack,
    localAudioTrack = null,
    options = ConnectOptions(
        model = RealtimeModels.LUCY_RESTYLE_2,
        onRemoteVideoTrack = { track ->
            // Display the transformed video
            remoteRenderer.addSink(track)
        },
        initialPrompt = InitialPrompt("a cyberpunk cityscape")
    )
)

// Change prompt during session
realtime.setPrompt("a sunny beach scene", enhance = true)

// Disconnect when done
realtime.disconnect()
client.release()
```

## What can you build?

The SDK provides two main APIs for different use cases:

| If you need to...                         | Use          | Main method                    |
| ----------------------------------------- | ------------ | ------------------------------ |
| Transform live camera streams over WebRTC | Realtime API | `client.realtime.connect()`    |
| Generate/edit videos asynchronously       | Queue API    | `client.queue.submitAndPoll()` |

<CardGroup cols={2}>
  <Card title="Realtime API" href="/sdks/android-realtime">
    Realtime video streams via WebRTC
  </Card>

  <Card title="Queue API" href="/sdks/android-queue">
    Batch video processing
  </Card>
</CardGroup>

## Platform Requirements

<Note>
  The Android SDK requires:

  * **Android API 24+** (Android 7.0 Nougat)
  * **Kotlin 2.1+**
  * **Java 17**
  * A **real device** for camera access (emulator does not support WebRTC camera features)
</Note>

## Client Setup

Initialize the Decart client with your API key and an Android `Context`:

```kotlin theme={null}
import ai.decart.sdk.DecartClient
import ai.decart.sdk.DecartClientConfig

val client = DecartClient(
    context = applicationContext,
    config = DecartClientConfig(
        apiKey = "your-api-key",
        baseUrl = "wss://api.decart.ai",       // optional — WebSocket URL for realtime
        httpBaseUrl = "https://api.decart.ai",  // optional — HTTP URL for queue API
        logLevel = LogLevel.WARN,               // optional — SDK log verbosity
    )
)
```

**Parameters:**

* `apiKey` (required) - Your Decart API key from the [platform](https://platform.decart.ai)
* `baseUrl` (optional) - Custom WebSocket endpoint for the Realtime API
* `httpBaseUrl` (optional) - Custom HTTP endpoint for the Queue API
* `logLevel` (optional) - Minimum log level: `VERBOSE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `NONE`

<Warning>
  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.
</Warning>

## Client Tokens

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:

```kotlin theme={null}
// Fetch ephemeral key from your backend
val ephemeralKey = fetchTokenFromBackend()

// Use it to create the client
val client = DecartClient(
    context = applicationContext,
    config = DecartClientConfig(apiKey = ephemeralKey)
)
```

<Tip>
  See [Client Tokens](/getting-started/client-tokens) for details on secure client-side authentication.
</Tip>

## Available Models

### Realtime Models

Use these with `client.realtime.connect()`:

```kotlin theme={null}
import ai.decart.sdk.RealtimeModels

RealtimeModels.LUCY_2_1               // Realtime video editing (latest)
RealtimeModels.LUCY_2_1_VTON          // Virtual try-on
RealtimeModels.LUCY_RESTYLE_2         // Realtime video restyling

// Latest aliases
RealtimeModels.LUCY_LATEST            // Always the latest editing model
RealtimeModels.LUCY_RESTYLE_LATEST    // Always the latest restyling model
```

Each model exposes properties for optimal camera configuration:

```kotlin theme={null}
val model = RealtimeModels.LUCY_2_1
println(model.fps)     // 20
println(model.width)   // 1088
println(model.height)  // 624
```

### Batch Video Models

Use these with `client.queue.submit()` or `client.queue.submitAndPoll()`:

```kotlin theme={null}
import ai.decart.sdk.VideoModels

VideoModels.LUCY_2_1           // Video editing (latest)
VideoModels.LUCY_2_1_VTON      // Virtual try-on
VideoModels.LUCY_RESTYLE_2     // Video restyling

// Latest aliases
VideoModels.LUCY_LATEST        // Always the latest editing model
VideoModels.LUCY_VTON_LATEST   // Always the latest virtual try-on model
```

<Accordion title="Previous generation models">
  ```kotlin theme={null}
  VideoModels.LUCY_CLIP          // Video-to-video (Lucy Clip)
  ```
</Accordion>

## Kotlin Coroutines & Flow

The SDK uses Kotlin coroutines and Flow for reactive state management:

```kotlin theme={null}
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

// Realtime connection state as StateFlow
lifecycleScope.launch {
    client.realtime.connectionState.collect { state ->
        println("Connection: $state")
    }
}

// Errors as SharedFlow
lifecycleScope.launch {
    client.realtime.errors.collect { error ->
        println("Error: ${error.code} — ${error.message}")
    }
}

// Queue job progress as Flow
client.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)
    }
}
```

<Tip>
  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.
</Tip>

## Jetpack Compose Integration

The SDK works with Jetpack Compose through WebRTC's `SurfaceViewRenderer`:

```kotlin theme={null}
import androidx.compose.runtime.Composable
import androidx.compose.ui.viewinterop.AndroidView
import org.webrtc.SurfaceViewRenderer

@Composable
fun VideoRenderer(
    onSurfaceReady: (SurfaceViewRenderer) -> Unit
) {
    AndroidView(
        factory = { context ->
            SurfaceViewRenderer(context).apply {
                init(client.realtime.getEglBaseContext(), null)
                onSurfaceReady(this)
            }
        }
    )
}
```

## Android Permissions

Your app must declare camera and internet permissions. Add these to your `AndroidManifest.xml`:

```xml theme={null}
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
```

Request camera permission at runtime before connecting:

```kotlin theme={null}
val launcher = rememberLauncherForActivityResult(
    ActivityResultContracts.RequestPermission()
) { granted ->
    if (granted) {
        // Start camera and connect
    }
}

launcher.launch(Manifest.permission.CAMERA)
```

## Type Safety

The SDK uses typed input classes for each batch video model category, providing compile-time guarantees:

```kotlin theme={null}
import ai.decart.sdk.queue.*

// Video editing — requires prompt + video file
val edit = VideoEditInput(
    prompt = "Cinematic color grade",
    data = FileInput.fromUri(videoUri),
)
```

## Error Handling

The SDK provides two error mechanisms — one for realtime, one for queue:

**Realtime errors** are emitted via the `errors` SharedFlow:

```kotlin theme={null}
client.realtime.errors.collect { error ->
    when (error.code) {
        ErrorCodes.INVALID_API_KEY -> { /* handle auth error */ }
        ErrorCodes.WEBRTC_TIMEOUT_ERROR -> { /* handle timeout */ }
        ErrorCodes.WEBRTC_ICE_ERROR -> { /* handle ICE failure */ }
        else -> { /* handle other errors */ }
    }
}
```

**Queue errors** throw typed exceptions:

```kotlin theme={null}
try {
    val result = client.queue.submitAndPoll(model, input)
} catch (e: QueueSubmitException) {
    // Job submission failed
} catch (e: QueueStatusException) {
    // Status check failed
} catch (e: QueueResultException) {
    // Result download failed
} catch (e: InvalidInputException) {
    // Input validation failed
}
```

## Sample App

The SDK includes a [sample Jetpack Compose app](https://github.com/DecartAI/decart-android/tree/main/sample) with:

* **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](https://github.com/DecartAI/decart-example-android-realtime).

## Ready to start building?

<CardGroup cols={2}>
  <Card title="Realtime API Guide" href="/sdks/android-realtime">
    **Build realtime Android experiences**

    Complete guide with Jetpack Compose examples for camera handling, video transformation, and interactive applications.
  </Card>

  <Card title="Queue API Guide" href="/sdks/android-queue">
    **Batch video processing**

    Edit videos, control motion, and transform videos with typed input classes and Flow-based progress tracking.
  </Card>
</CardGroup>
