Kotlin / JVM SDK
Ultra high-performance Kotlin SDK for the Linkit API — coroutines, OkHttp, kotlinx.serialization, first-class Java interop, Maven Central distribution.
Kotlin / JVM SDK
Package
sa.linkit:linkit-sdk · Kotlin 2.1 · OkHttp · kotlinx.serialization · Coroutines · Maven Central
Installation
dependencies {
implementation("sa.linkit:linkit-sdk:0.1.0")
}dependencies {
implementation 'sa.linkit:linkit-sdk:0.1.0'
}<dependency>
<groupId>sa.linkit</groupId>
<artifactId>linkit-sdk</artifactId>
<version>0.1.0</version>
</dependency>Quick Start — Kotlin
Initialize the Client
import sa.linkit.client.LinkitClient
val client = LinkitClient.quickSetup("https://linkit.works/api/v1", "your-jwt-token")Create a SKU with the Fluent Builder
import sa.linkit.client.SkuCreateBuilder
val sku = client.skus.create(
SkuCreateBuilder()
.withIvId("SKU-001")
.inBranch("BR-RYD")
.forProduct("PROD-001")
.withPrice(29.99)
.withQty(500.0)
.build()
)Health Check
val health = client.health.check()
println("Status: ${health.status}")Clean Up
client.close()Quick Start — Java
First-Class Java Interop
Every service has *Blocking() wrappers for Java. Factory methods use @JvmStatic. No Kotlin knowledge required for Java callers.
Initialize the Client
import sa.linkit.client.LinkitClient;
LinkitClient client = LinkitClient.quickSetup("https://linkit.works/api/v1", "your-jwt-token");Create a SKU (Blocking)
import sa.linkit.client.SkuCreateBuilder;
import sa.linkit.models.SkuResponse;
SkuResponse sku = client.getSkus().createBlocking(
new SkuCreateBuilder()
.withIvId("SKU-001")
.inBranch("BR-RYD")
.forProduct("PROD-001")
.withPrice(29.99)
.build()
);Health Check (Blocking)
SystemHealthResponse health = client.getHealth().checkBlocking();
System.out.println("Status: " + health.getStatus());Clean Up
client.close();Configuration
val client = LinkitClient.create(LinkitConfiguration(
baseUrl = "https://linkit.works/api/v1",
jwtToken = "your-jwt-token",
timeoutMs = 30_000L,
maxRetries = 3,
retryBaseDelayMs = 1_000L,
retryMaxDelayMs = 30_000L,
circuitBreakerThreshold = 5,
circuitBreakerRecoveryMs = 60_000L,
maxConcurrentRequests = 10,
))LinkitClient client = LinkitClient.create(new LinkitConfiguration(
"https://linkit.works/api/v1",
"your-jwt-token",
30000L, 3, 1000L, 30000L, 5, 60000L, 10,
"LinkitKotlinSDK/0.1.0"
));Services Reference
Every service has both suspend (Kotlin) and Blocking (Java) variants:
| Service | Kotlin (suspend) | Java (blocking) | Description |
|---|---|---|---|
client.skus | create(), getById(), update(), updateStock(), deleteById(), list() | createBlocking(), getByIdBlocking(), ... | Per-branch inventory |
client.products | create(), getById(), update(), deleteById(), list() | *Blocking() wrappers | Product catalog |
client.branches | create(), getById(), update(), deleteById(), list() | *Blocking() wrappers | Physical locations |
client.customers | create(), getById(), update(), deleteById(), list(), lookupByEmail(), lookupByPhone(), search(), createAddress(), updateAddress(), deleteAddress(), createGroup(), updateGroup(), deleteGroup() | *Blocking() wrappers | Customer profiles |
client.orders | getById(), list(), updateStatus() | *Blocking() wrappers | Order management |
client.offers | create(), getById(), update(), updateStatus(), deleteById(), list(), bulkUpsert() | *Blocking() wrappers | Promotions & discounts |
client.brands | create(), getById(), update(), deleteById(), list() | *Blocking() wrappers | Brand management |
client.categories | create(), getById(), update(), deleteById(), list() | *Blocking() wrappers | Product categories |
client.generics | create(), getById(), update(), deleteById(), list() | *Blocking() wrappers | Generic entities |
client.health | check(), ping() | checkBlocking(), pingBlocking() | System health |
client.integrations | list(), getById(), execute(), enable(), disable() | *Blocking() wrappers | Platform connections |
Builders
SkuCreateBuilder
val request = SkuCreateBuilder()
.withIvId("SKU-001")
.inBranch("BR-RYD")
.forProduct("PROD-001")
.withBarcode("5901234123457")
.withPrice(29.99)
.withQty(500.0)
.withAvailable(true)
.withAmazonSku("AMZ-W001")
.build() // throws LinkitValidationException on errorProductCreateBuilder
val request = ProductCreateBuilder()
.withIvId("PROD-001")
.withNameEn("Premium Widget")
.withNameAr("ودجت فاخر")
.withAveragePrice(149.99)
.withEnabled(true)
.build()BranchCreateBuilder
val request = BranchCreateBuilder()
.withIvId("BR-RYD")
.withNameEn("Riyadh Main Store")
.withNameAr("متجر الرياض الرئيسي")
.withLocation(24.7136, 46.6753)
.withStatus(BranchStatus.PUBLISHED)
.withEmail("riyadh@linkit.sa")
.build()Error Handling
try {
val sku = client.skus.getById("nonexistent")
} catch (e: LinkitNotFoundException) {
println("Not found: ${e.resourceType}")
} catch (e: LinkitRateLimitException) {
println("Rate limited — retry after ${e.retryAfterMs}ms")
} catch (e: LinkitValidationException) {
e.validationErrors.forEach { println(" ${it.field}: ${it.message}") }
} catch (e: LinkitApiException) {
println("API error ${e.statusCode}: ${e.userFriendlyMessage}")
}try {
SkuResponse sku = client.getSkus().getByIdBlocking("nonexistent");
} catch (LinkitNotFoundException e) {
System.out.println("Not found: " + e.getResourceType());
} catch (LinkitRateLimitException e) {
System.out.println("Rate limited — retry after " + e.getRetryAfterMs() + "ms");
} catch (LinkitApiException e) {
System.out.println("API error " + e.getStatusCode() + ": " + e.getUserFriendlyMessage());
}Exception Hierarchy
| Exception | Status | Description |
|---|---|---|
LinkitException | — | Base exception |
LinkitInitializationException | — | Bad configuration |
LinkitApiException | Any | API error response |
LinkitAuthenticationException | 401 | Invalid credentials |
LinkitAuthorizationException | 403 | Insufficient permissions |
LinkitNotFoundException | 404 | Resource not found |
LinkitValidationException | 400 | Validation failed |
LinkitConflictException | 409 | State conflict |
LinkitRateLimitException | 429 | Rate limit exceeded |
LinkitServerException | 5xx | Server-side error |
LinkitSerializationException | — | JSON parse failure |
Performance Architecture
OkHttp 4.12
HTTP/2 multiplexing, connection pooling, interceptor pipeline, automatic GZIP.
kotlinx.serialization
Compile-time code generation — zero reflection, zero runtime overhead, full tree-shakeability.
Kotlin Coroutines
Structured concurrency with suspend functions. Non-blocking I/O with configurable dispatchers.
Thread-Safe Resilience
AtomicInteger + AtomicReference circuit breaker. java.util.concurrent.Semaphore rate limiter. Lock-free where possible.