Screenshot API for Kotlin: Android, JVM & Multiplatform

Integrate SnapAPI screenshot and scraping endpoints in Kotlin with OkHttp, Ktor Client, or the official Kotlin SDK. Works on Android, JVM, and multiplatform targets.

Start Free — 200 captures/mo View Docs

Screenshot API for Kotlin and Android

SnapAPI integrates seamlessly with Kotlin projects on Android, JVM backend services, and multiplatform builds. Whether you are generating open graph preview images from a Ktor backend, capturing competitor screenshots in a Spring Boot service, or building an Android utility app that renders remote pages, SnapAPI exposes a simple REST endpoint that any HTTP client can call. No native browser dependencies are required in your application.

Kotlin with OkHttp

import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.File

val client = OkHttpClient()

val request = Request.Builder()
    .url("https://api.snapapi.pics/v1/screenshot" +
         "?url=https://example.com&full_page=true&format=png")
    .header("X-Api-Key", "YOUR_API_KEY")
    .build()

client.newCall(request).execute().use { response ->
    if (response.isSuccessful) {
        response.body?.bytes()?.let { bytes ->
            File("screenshot.png").writeBytes(bytes)
            println("Saved ${bytes.size} bytes")
        }
    } else {
        println("Error: ${response.code}")
    }
}

OkHttp is the standard HTTP client on Android and widely used in JVM Kotlin services. The example above makes a synchronous call inside a use block to ensure the response body is properly closed. For Android applications, wrap this in a coroutine with Dispatchers.IO to keep the main thread free.

Kotlin Coroutines with Ktor Client

import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import io.ktor.client.statement.*

val client = HttpClient(CIO)

suspend fun captureScreenshot(url: String, apiKey: String): ByteArray {
    val response: HttpResponse = client.get("https://api.snapapi.pics/v1/screenshot") {
        parameter("url", url)
        parameter("full_page", "true")
        header("X-Api-Key", apiKey)
    }
    return response.readBytes()
}

Ktor Client with the CIO engine is a lightweight, coroutine-native option for JVM and multiplatform targets. The suspend function integrates naturally with your existing coroutine scope, making it trivial to fire multiple screenshot requests concurrently with async and awaitAll.

Android Integration

On Android, add the OkHttp or Ktor dependencies to your build.gradle.kts and declare the internet permission in your manifest. For modern Android development with Jetpack Compose, fetch the screenshot bytes in a ViewModel using viewModelScope.launch, then load the result into an AsyncImage with Coil or convert the bytes to a Bitmap for display.

SnapAPI supports all core capture parameters from Android: viewport size via width and height, device emulation via device (30+ presets including Pixel 7, Galaxy S23, and iPad Air), full-page screenshots, custom CSS injection, and JavaScript execution before capture. This makes it practical to generate device-specific previews inside an Android app without bundling WebView hacks.

Using the Official Kotlin SDK

The official SnapAPI Kotlin SDK is available at github.com/Sleywill/snapapi-kotlin. It wraps the REST API with a type-safe DSL, handles authentication, and includes suspend functions for all endpoints: screenshot, scrape, extract, PDF, video, and AI analysis. Add it to your Gradle project and you can capture your first screenshot in three lines of Kotlin.

Sign up at snapapi.pics for 200 free captures per month. The free tier requires no credit card and supports all Kotlin integration patterns described above. Explore the full API reference at snapapi.pics/docs.html for complete parameter documentation covering every endpoint and response format.

Batch Screenshot Capture with Kotlin Coroutines

One of the strongest use cases for combining Kotlin coroutines with SnapAPI is concurrent batch processing. Suppose you need to generate screenshots for 50 product pages each night. With coroutines, you can launch all 50 requests simultaneously and await them together, completing the entire batch in the time it takes for the slowest single request rather than multiplying latency by 50.

import kotlinx.coroutines.*

suspend fun captureAll(urls: List<String>, apiKey: String): List<ByteArray> =
    coroutineScope {
        urls.map { url ->
            async(Dispatchers.IO) {
                captureScreenshot(url, apiKey)
            }
        }.awaitAll()
    }

// Usage in a background job
fun main() = runBlocking {
    val urls = listOf(
        "https://example.com/product/1",
        "https://example.com/product/2",
        "https://example.com/product/3"
    )
    val screenshots = captureAll(urls, System.getenv("SNAPAPI_KEY"))
    screenshots.forEachIndexed { i, bytes ->
        java.io.File("product_$i.png").writeBytes(bytes)
    }
    println("Captured ${screenshots.size} screenshots")
}

The coroutineScope ensures all launched coroutines complete before the function returns, providing structured concurrency. If any individual request fails, the exception propagates and the scope cancels remaining requests, preventing partial results from being silently swallowed.

Rate-Controlled Batching

For very large batches, use a Semaphore to cap concurrent requests and stay within API rate limits without a queue service:

import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit

suspend fun captureWithLimit(
    urls: List<String>,
    apiKey: String,
    maxConcurrent: Int = 10
): List<ByteArray> = coroutineScope {
    val semaphore = Semaphore(maxConcurrent)
    urls.map { url ->
        async(Dispatchers.IO) {
            semaphore.withPermit {
                captureScreenshot(url, apiKey)
            }
        }
    }.awaitAll()
}

Setting maxConcurrent to 10 keeps your pipeline efficient while ensuring you never fire more than 10 simultaneous browser render requests. Adjust this value based on your SnapAPI plan: Starter users should keep it at 5, Pro at 10-20, Business at 50 or more.

Kotlin Spring Boot Integration

Spring Boot is the dominant JVM framework for production microservices, and SnapAPI integrates naturally as a typed service bean. Define a SnapApiProperties configuration class bound to your application.yml, inject a RestTemplate or WebClient bean, and call the screenshot endpoint from any controller or scheduled task.

@ConfigurationProperties("snapapi")
data class SnapApiProperties(val apiKey: String, val baseUrl: String = "https://api.snapapi.pics")

@Service
class SnapApiService(private val props: SnapApiProperties, private val restTemplate: RestTemplate) {

    fun screenshot(url: String, fullPage: Boolean = true): ByteArray {
        val uri = UriComponentsBuilder.fromHttpUrl("${props.baseUrl}/v1/screenshot")
            .queryParam("url", url)
            .queryParam("full_page", fullPage)
            .build().toUri()
        val headers = HttpHeaders().apply { set("X-Api-Key", props.apiKey) }
        val request = RequestEntity<Void>(headers, HttpMethod.GET, uri)
        return restTemplate.exchange(request, ByteArray::class.java).body!!
    }
}

In application.yml, set snapapi.api-key: ${SNAPAPI_KEY} to pull the key from an environment variable. Spring Boot auto-configuration picks up the property and injects it into your service on startup. This pattern keeps the API key out of your codebase and makes it trivial to rotate without redeployment in Kubernetes or Docker Compose environments.

Reactive Integration with WebFlux

For reactive Spring WebFlux applications, replace RestTemplate with WebClient. The call returns a Mono<ByteArray> that fits naturally into reactive pipelines. Combine with flatMap to process capture results as they arrive without blocking threads, making the integration suitable for high-throughput Spring gateway services.

Kotlin Multiplatform

Kotlin Multiplatform projects can share SnapAPI client code across JVM, Android, and iOS targets. The common source set uses the Ktor client with the platform-appropriate engine: CIO for JVM server, OkHttp for Android, and Darwin for iOS. Define the SnapApiClient interface and suspend functions in commonMain and provide platform-specific engine configuration in jvmMain, androidMain, and iosMain.

This architecture is ideal for mobile-plus-backend product teams that want to reuse screenshot and scraping logic across platforms. A shared Kotlin Multiplatform module reduces duplication and ensures consistent error handling across every client surface in your product.

Device Emulation and Full-Feature API Access

SnapAPI gives Kotlin developers access to every capture feature through the same REST interface. Device emulation with 30+ presets lets you capture mobile renders from a JVM backend without spinning up a device farm or installing Android emulators. Pass device=Pixel_7 or device=iPhone_15 as a query parameter and receive a screenshot rendered at the correct resolution, pixel ratio, and user agent for that device.

PDF generation is equally straightforward. Replace /v1/screenshot with /v1/pdf in your Kotlin service and the response body contains a PDF byte stream. This is ideal for Spring Boot report generation pipelines where HTML templates need to be converted to downloadable PDF documents on demand.

SnapAPI Pricing for Kotlin Projects

The free tier provides 200 captures per month — more than enough for a proof of concept or low-traffic Android feature. The Starter plan at $19 per month covers 5,000 captures, suitable for a backend thumbnail service serving a small user base. Pro at $79 per month provides 50,000 captures, appropriate for e-commerce price monitoring or OG image generation for a mid-size publisher. Business at $299 per month includes 500,000 captures for large-scale data pipelines or high-traffic media platforms.

All plans include stealth mode, device emulation, custom JavaScript execution, CSS injection, ad blocking, cookie consent dismissal, and full-page screenshots. There are no feature tiers — every endpoint and parameter is available from the free account. Sign up at snapapi.pics and make your first Kotlin screenshot API call in under five minutes.

Error Handling in Kotlin

Wrap SnapAPI calls in a try-catch or use Kotlin Result types to handle network failures gracefully. Check the HTTP status code before consuming the response body: on 429 read the Retry-After header, on 400 log the full request URL for debugging, and on 5xx apply exponential backoff before retrying. Typed exception handling in Kotlin makes this error-handling boilerplate concise and readable compared to equivalent Java code.

kotlin screenshot api jvm android multiplatform screenshot capture web rendering kotlin coroutines ktor okhttp screenshot service kotlin spring boot screenshot api integration
screenshot api kotlin android ios swift java kotlin multiplatform screenshot capture api service