MemoryKit

Kotlin SDK

Official Kotlin SDK for MemoryKit. Android, JVM, and server-side.

Coroutines

Every method is suspend fun. Native Kotlin async.

Flow streaming

SSE responses as Flow<SSEEvent> — collect, transform, combine.

globeAndroid + JVM

Android API 21+, JVM 8+, server-side Kotlin.

Installation

dependencies {
    implementation("io.memorykit:memorykit:0.1.0")
}

Includes kotlinx-coroutines, kotlinx-serialization-json, okhttp, and okhttp-sse — no extra dependencies needed.

Quick start

Initialize

import io.memorykit.MemoryKit
 
val mk = MemoryKit(apiKey = "ctx_...")

Store a memory

val memory = mk.memories.create(
    content = "User prefers dark mode and metric units.",
    tags = listOf("preferences"),
    userId = "user_123"
)
val results = mk.memories.search(
    query = "What does the user prefer?",
    limit = 5
)
results.results.forEach { hit ->
    println("[%.2f] %s".format(hit.score, hit.content))
}

Configuration options

import io.memorykit.MemoryKitConfig
 
val mk = MemoryKit(MemoryKitConfig(
    apiKey = "ctx_...",
    baseUrl = "https://api.memorykit.io/v1",
    timeout = 30_000L,     // milliseconds
    maxRetries = 3          // automatic retries on 429/5xx
))

The client implements Closeable. Use .use {} or call mk.close() when done:

MemoryKit(apiKey = "ctx_...").use { mk ->
    mk.memories.create(content = "Hello")
}

Memories

Create and manage

// Create
val memory = mk.memories.create(
    content = "Meeting notes from Q4 planning...",
    title = "Q4 Planning",
    tags = listOf("meetings", "q4"),
    userId = "user_123"
)
 
// List with pagination
val page = mk.memories.list(limit = 20, status = "completed")
page.data.forEach { println(it.title ?: it.id) }
if (page.hasMore) {
    val next = mk.memories.list(cursor = page.cursor)
}
 
// Get by ID
val mem = mk.memories.get("mem_abc123")
 
// Update
mk.memories.update("mem_abc123", title = "Updated Title")
 
// Delete
mk.memories.delete("mem_abc123")

Upload files

File upload is not yet available in the Kotlin SDK. Use the REST API directly with your preferred HTTP client:

import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
 
val client = OkHttpClient()
val file = File("report.pdf")
val body = MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("file", file.name, RequestBody.create("application/pdf".toMediaType(), file))
    .addFormDataPart("title", "Q4 Report")
    .build()
 
val request = Request.Builder()
    .url("https://api.memorykit.io/v1/memories/upload")
    .header("Authorization", "Bearer ctx_...")
    .post(body)
    .build()
 
client.newCall(request).execute()

Supported formats: PDF, DOCX, XLSX, PPTX, TXT, CSV, Markdown, HTML, and JSON. Max 100 MB.

Batch ingest

Up to 100 memories in a single request.

val result = mk.memories.batchIngest(
    items = listOf(
        CreateMemoryRequest(content = "First fact", tags = listOf("facts")),
        CreateMemoryRequest(content = "Second fact", tags = listOf("facts")),
    )
)
println("Accepted: ${result.accepted}")

Search

Combines vector similarity, full-text search, and reranking.

val results = mk.memories.search(
    query = "quarterly revenue targets",
    limit = 10
)
results.results.forEach { hit ->
    println("[%.2f] %s".format(hit.score, hit.title))
}

RAG query

Coming Soonmemories.query() is not available in the current SDK release. Use memories.search() for retrieval. LLM-powered query with answer generation will be available in a future release.

Streaming

Coming Soonmemories.stream() is not available in the current SDK release. Use memories.search() for retrieval. Streaming responses will be available in a future release.

Chats

Coming Soon — Chat methods (chats.create(), chats.sendMessage(), chats.streamMessage(), chats.get()) are not available in the current SDK release. Conversational RAG with chat sessions will be available in a future release.

Users

// Upsert (create or update)
mk.users.upsert(
    id = "user_123",
    name = "Alice",
    email = "alice@example.com"
)
 
// Track events
mk.users.createEvent(
    userId = "user_123",
    type = "page_view"
)
 
// GDPR erasure — delete user and all associated data
mk.users.delete("user_123", cascade = true)

Webhooks

// Subscribe to events
val webhook = mk.webhooks.create(
    url = "https://example.com/webhook",
    events = listOf("memory.completed", "memory.failed")
)
println("Signing secret: ${webhook.secret}")
 
// Test delivery
val test = mk.webhooks.test(webhook.id)
println("Delivered: ${test.success}")

Error handling

All errors extend MemoryKitException with typed subclasses:

import io.memorykit.models.*
 
try {
    val result = mk.memories.search(query = "...")
    result.results.forEach { println(it.content) }
} catch (e: AuthenticationException) {
    // 401 — invalid or expired API key
} catch (e: RateLimitException) {
    // 429 — automatically retried, raised if max retries exceeded
    println("Retry after ${e.retryAfter}s")
} catch (e: NotFoundException) {
    // 404
} catch (e: BadRequestException) {
    // 400/422 — bad request parameters
    println(e.message)
} catch (e: MemoryKitException) {
    // catch-all for other API errors
    println("Error ${e.statusCode}: ${e.message}")
}

Retryable errors (429, 5xx) are automatically retried with exponential backoff up to maxRetries times. You don't need to implement retry logic yourself.

Android usage

class MemoryViewModel : ViewModel() {
    private val mk = MemoryKit(apiKey = BuildConfig.MEMORYKIT_API_KEY)
 
    fun search(text: String) = viewModelScope.launch {
        try {
            val result = mk.memories.search(query = text, limit = 5)
            _results.value = result.results.map { it.content }
        } catch (e: MemoryKitException) {
            _error.value = e.message
        }
    }
 
    override fun onCleared() { mk.close() }
}

Never embed API keys in your APK. Use BuildConfig fields from local.properties or a backend proxy. See Authentication for best practices.

Edit on GitHub

On this page