Welcome to the Snapit Virtual Try-On (VTON) SDK for Android. This native Java/Kotlin library provides a lightweight, zero-dependency interface for integrating Snapit's AI-powered try-on models directly into your Android applications.
- Zero-Dependency Core: Kept extremely lightweight to avoid dependency resolution conflicts in consumer apps.
- Sync & Async Interfaces: Built-in Executor thread-pool for asynchronous execution alongside direct blocking APIs.
- Robust File Handling: Streamlined multipart uploads supporting
java.io.File, rawbyte[], or standardInputStreamvalues. - Modern Exception Mapping: Structured exceptions to check for validation errors, credit depletion, or API key issues.
- Full Kotlin Interoperability: Designed with standard Java builders and getters that translate into idiomatic Kotlin properties.
- Clone or copy this SDK's
snapit_sdkfolder into your Android project's root directory. - Include the library module in your
settings.gradleorsettings.gradle.kts:include ':snapit_sdk' - Add the project dependency inside your app-level
build.gradleorbuild.gradle.ktsfile:dependencies { implementation project(':snapit_sdk') } - Sync your project with Gradle.
Because the library requires zero external dependencies, you can copy the contents of the package folder snapit_sdk/src/main/java/com/snapit/sdk/ directly into your main application's package structure (e.g., app/src/main/java/com/snapit/sdk/). Ensure that the org.json library is available (built-in on Android).
Add the dependency to your app's build.gradle or build.gradle.kts:
dependencies {
implementation 'com.snapit:snapit-sdk-android:1.0.0'
}Ensure mavenCentral() is declared in your root build.gradle or settings.gradle repository list:
repositories {
mavenCentral()
}You can build the SDK library output package or run the example application using Gradle from the command line:
To compile the library into a standalone binary .aar file (for distribution or simple import):
./gradlew :snapit_sdk:assembleReleaseThe compiled binary will be located at: snapit_sdk/build/outputs/aar/snapit_sdk-release.aar
To build the runnable example application's debug APK:
./gradlew :example:assembleDebugThe compiled APK will be located at: example/build/outputs/apk/debug/example-debug.apk
The SDK communicates with Snapit endpoints to run generations. Add the Internet permission to your AndroidManifest.xml if not already present:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
</manifest>The easiest way to integrate Snapit is using the built-in, premium dark-themed interactive virtual try-on screens. This handles the entire workflow: prompting the user to take a photo or select one from their gallery, uploading the photo, generating the try-on image, and displaying an interactive side-by-side swipe comparison.
To launch the UI, simply call Snapmydesign.launchTryOn:
import com.snapit.sdk.Snapmydesign
import com.snapit.sdk.SnapitUiCallback
Snapmydesign.launchTryOn(
context = this, // Activity context
apiKey = "smd_live_your_api_key_here",
userId = "your_user_id_here",
garmentImageUrl = "https://images.unsplash.com/photo-...", // Clothes image to try on
productId = "SKU-BLUE-SHIRT", // Optional catalog SKU
externalUserId = "customer_123", // Optional end-consumer identity
modelName = "medium", // "fast", "medium", or "quality"
version = 1.1, // SDK Model version
callback = object : SnapitUiCallback {
override fun onSuccess(resultImageUrl: String, generationId: String) {
// Virtual try-on succeeded! Use the generated image URL.
println("Try-on success! Result URL: $resultImageUrl")
}
override fun onFailure(errorMessage: String) {
// An error occurred (e.g. invalid credentials or engine error)
System.err.println("Try-on error: $errorMessage")
}
}
) import com.snapit.sdk.Snapmydesign;
import com.snapit.sdk.SnapitUiCallback;
Snapmydesign.launchTryOn(
this, // Activity context
"smd_live_your_api_key_here",
"your_user_id_here",
"https://images.unsplash.com/photo-...", // Clothes image
"SKU-BLUE-SHIRT", // Optional catalog SKU
"customer_123", // Optional external user ID
"medium", // "fast", "medium", or "quality"
1.1, // SDK Model version
new SnapitUiCallback() {
@Override
public void onSuccess(String resultImageUrl, String generationId) {
// Virtual try-on succeeded!
System.out.println("Try-on success! Result URL: " + resultImageUrl);
}
@Override
public void onFailure(String errorMessage) {
// An error occurred
System.err.println("Try-on error: " + errorMessage);
}
}
);Note
The SDK uses standard Android Manifest Merging. The SnapitTryOnActivity and its file providers are declared inside the SDK's manifest and will automatically merge into your application's manifest during build. You do not need to register them manually.
Provide your live secret API Key (starting with smd_live_...) to construct the client:
import com.snapit.sdk.SnapitClient
import com.snapit.sdk.SnapitConfig
// Standard initialization
val client = SnapitClient("smd_live_your_api_key_here")
// Custom configuration initialization
val config = SnapitConfig.Builder()
.connectTimeoutMs(20000)
.readTimeoutMs(90000) // VTON generation can take time
.build()
val customClient = SnapitClient("smd_live_your_api_key_here", config)import com.snapit.sdk.SnapitClient;
import com.snapit.sdk.SnapitConfig;
// Standard initialization
SnapitClient client = new SnapitClient("smd_live_your_api_key_here");
// Custom configuration initialization
SnapitConfig config = new SnapitConfig.Builder()
.connectTimeoutMs(20000)
.readTimeoutMs(90000)
.build();
SnapitClient customClient = new SnapitClient("smd_live_your_api_key_here", config);To trigger a try-on, you must first upload your images to obtain cloud-hosted asset URLs. The SDK accepts local files, raw byte streams, or input streams.
import com.snapit.sdk.SnapitCallback
import com.snapit.sdk.model.UploadRequest
import com.snapit.sdk.model.UploadResponse
import java.io.File
val garmentFile = File(context.cacheDir, "tshirt.png")
val uploadRequest = UploadRequest.Builder("user_abc123")
.addFile(garmentFile)
.resolution(1000) // Optional target size (default is 1000)
.build()
client.uploadImagesAsync(uploadRequest, object : SnapitCallback<UploadResponse> {
override fun onSuccess(result: UploadResponse) {
if (result.isSuccess) {
val uploadedUrl = result.uploaded[0].url
println("Asset uploaded successfully: $uploadedUrl")
}
}
override fun onFailure(t: Throwable) {
System.err.println("Upload failed: ${t.message}")
}
})import com.snapit.sdk.model.UploadRequest;
import com.snapit.sdk.model.UploadResponse;
import java.io.File;
new Thread(() -> {
try {
File garmentFile = new File(context.getCacheDir(), "tshirt.png");
UploadRequest uploadRequest = new UploadRequest.Builder("user_abc123")
.addFile(garmentFile)
.resolution(1000)
.build();
UploadResponse response = client.uploadImages(uploadRequest);
if (response.isSuccess()) {
String uploadedUrl = response.getUploaded().get(0).getUrl();
System.out.println("Asset uploaded: " + uploadedUrl);
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();Trigger the VTON try-on engine using your uploaded asset URLs:
import com.snapit.sdk.SnapitCallback
import com.snapit.sdk.model.VTONRequest
import com.snapit.sdk.model.VTONResponse
val vtonRequest = VTONRequest.Builder("medium") // "fast", "medium", or "quality"
.addClothesImageUrl("https://firebasestorage.googleapis.com/.../tshirt.png")
.addPersonImageUrl("https://firebasestorage.googleapis.com/.../model.png") // Optional
.prompt("Put the uploaded blue shirt on the model") // Optional
.version(1.0) // 1.0 or 1.1
.productId("SKU-BLUE-SHIRT") // Optional analytics SKU
.build()
client.generateTryOnAsync(vtonRequest, object : SnapitCallback<VTONResponse> {
override fun onSuccess(result: VTONResponse) {
if (result.isSuccess) {
val outputUrl = result.outputImageUrls[0]
println("Try-on output: $outputUrl")
println("Transaction cost: ${result.creditCost} credits")
}
}
override fun onFailure(t: Throwable) {
System.err.println("Try-on failed: ${t.message}")
}
})import com.snapit.sdk.model.VTONRequest;
import com.snapit.sdk.model.VTONResponse;
new Thread(() -> {
try {
VTONRequest request = new VTONRequest.Builder("quality")
.addClothesImageUrl("https://firebasestorage.googleapis.com/.../tshirt.png")
.version(1.1)
.productId("SKU-BLUE-SHIRT")
.build();
VTONResponse response = client.generateTryOn(request);
if (response.isSuccess()) {
String outputUrl = response.getOutputImageUrls().get(0);
System.out.println("Try-on success! URL: " + outputUrl);
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();Check how many credits are remaining on your API Key:
import com.snapit.sdk.model.UserCreditsRequest
val request = UserCreditsRequest("user_abc123")
client.checkCreditsAsync(request, object : SnapitCallback<UserCreditsResponse> {
override fun onSuccess(result: UserCreditsResponse) {
println("User ${result.userId} credits: ${result.credits}")
}
override fun onFailure(t: Throwable) {
t.printStackTrace()
}
})Retrieve a log history of your developer account's past runs:
import com.snapit.sdk.model.HistoryRequest
val request = HistoryRequest.Builder("user_abc123")
.limit(10)
.productId("SKU-BLUE-SHIRT")
.build()
client.getHistoryAsync(request, object : SnapitCallback<HistoryResponse> {
override fun onSuccess(result: HistoryResponse) {
for (item in result.data) {
println("ID: ${item.generationId} | Cost: ${item.creditCost} | Prompt: ${item.prompt}")
}
}
override fun onFailure(t: Throwable) {
t.printStackTrace()
}
})The SDK maps standard HTTP status responses into dedicated exception subclasses. You can catch these exceptions to build appropriate UI workflows:
| HTTP Status | SDK Exception Class | Meaning / Resolution |
|---|---|---|
401 |
SnapitException.InvalidAPIKeyException |
The X-API-Key is missing or invalid. Check dashboard configuration. |
403 |
SnapitException.UnauthorizedException |
The user ID doesn't match the API Key owner. |
404 |
SnapitException.UserNotFoundException |
Database lookup failed for User or API Key. |
422 |
SnapitException.RequestValidationException |
Invalid request parameters. Inspect .detail properties. |
501 |
SnapitException.InsufficientCreditsException |
Developer credits exhausted. Direct to top-up packages. |
500 |
SnapitException.InternalServerException |
Unhandled engine errors. Safely trigger a retry. |
try {
val response = client.generateTryOn(request)
} catch (e: SnapitException.InsufficientCreditsException) {
// Show 'Out of Credits' screen
} catch (e: SnapitException.InvalidAPIKeyException) {
// Log configuration alert
} catch (e: SnapitException) {
// Handle general VTON errors (e.g. invalid inputs)
} catch (e: Exception) {
// Handle generic network connectivity errors
}To release SDK resources when destroying activities or applications, make sure to shut down the client connection thread pool:
// Closes the client worker thread-pool executor
client.close()This SDK is available under the MIT License. See LICENSE for more details.