Kotlin icon

Kotlin Quick Start Guide

Get started with FacePing's face recognition API using Kotlin

Prerequisites

Installation

Create a new Kotlin project with Gradle. Update build.gradle.kts:

plugins {
    kotlin("jvm") version "1.9.0"
    kotlin("plugin.serialization") version "1.9.0"
}

dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.12.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
    implementation("io.github.cdimascio:dotenv-kotlin:6.4.1")
}

Step 1: Create Face Group

Create FacePingClient.kt:

import io.github.cdimascio.dotenv.dotenv
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request

class FacePingClient {
    private val apiKey = dotenv()["FACEPING_API_KEY"]
    private val client = OkHttpClient()
    private val baseUrl = "https://api.faceping.ai"

    suspend fun createGroup(groupName: String) {
        withContext(Dispatchers.IO) {
            val request = Request.Builder()
                .url("$baseUrl/groups/$groupName")
                .post(EMPTY_REQUEST)
                .addHeader("Authorization", "Bearer $apiKey")
                .build()

            client.newCall(request).execute().use { response ->
                if (response.isSuccessful) {
                    println("Group created successfully")
                } else {
                    throw Exception("Failed to create group: ${response.code}")
                }
            }
        }
    }

    companion object {
        private val EMPTY_REQUEST = okhttp3.RequestBody.create(null, ByteArray(0))
    }
}

// Usage
suspend fun main() {
    val client = FacePingClient()
    client.createGroup("my-group")
}

Step 2: Upload Face Image

Add to FacePingClient.kt:

import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File

suspend fun uploadFace(groupName: String, imageFile: File) {
    withContext(Dispatchers.IO) {
        val requestBody = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart(
                "image",
                imageFile.name,
                imageFile.asRequestBody("image/jpeg".toMediaType())
            )
            .build()

        val request = Request.Builder()
            .url("$baseUrl/groups/$groupName/faces")
            .post(requestBody)
            .addHeader("Authorization", "Bearer $apiKey")
            .build()

        client.newCall(request).execute().use { response ->
            if (response.isSuccessful) {
                println("Face uploaded successfully")
            } else {
                throw Exception("Failed to upload face: ${response.code}")
            }
        }
    }
}

// Usage
suspend fun main() {
    val client = FacePingClient()
    val imageFile = File("path/to/face.jpg")
    client.uploadFace("my-group", imageFile)
}

Step 3: Search for Faces

Add to FacePingClient.kt:

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json

@Serializable
data class MatchResult(
    val score: Double
)

@Serializable
data class SearchResponse(
    val matches: List
)

suspend fun searchFaces(groupName: String, imageFile: File): List {
    return withContext(Dispatchers.IO) {
        val requestBody = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart(
                "image",
                imageFile.name,
                imageFile.asRequestBody("image/jpeg".toMediaType())
            )
            .build()

        val request = Request.Builder()
            .url("$baseUrl/groups/$groupName/search")
            .post(requestBody)
            .addHeader("Authorization", "Bearer $apiKey")
            .build()

        client.newCall(request).execute().use { response ->
            if (response.isSuccessful) {
                val result = Json.decodeFromString(
                    response.body?.string() ?: "{}"
                )
                println("Found ${result.matches.size} matches")
                result.matches
            } else {
                throw Exception("Failed to search faces: ${response.code}")
            }
        }
    }
}

// Usage
suspend fun main() {
    val client = FacePingClient()
    val imageFile = File("path/to/search-face.jpg")
    val matches = client.searchFaces("my-group", imageFile)
    matches.forEach { match ->
        println("Match Score: ${match.score}")
    }
}

Security Notes

  • Images are immediately discarded after vector conversion
  • Face vectors cannot be reverse-engineered into images
  • Always use HTTPS for all API calls
  • Store your API keys in environment variables (.env file)

Ready to get started?

Take a look at the API documentation
API docs