Official Bulutklinik API SDK for Java (17+). Built on java.net.http + Jackson.
Covers the patient flow: auth, doctor search, slots, appointments, payments,
and health measures. See DESIGN.md for the full wire contract.
<dependency>
<groupId>com.bulutklinik</groupId>
<artifactId>sdk</artifactId>
<version>0.1.0</version>
</dependency>import com.bulutklinik.sdk.*;
import com.fasterxml.jackson.databind.JsonNode;
BulutklinikClient client = BulutklinikClient.builder()
.environment(Environment.PRODUCTION) // PRODUCTION | TEST | LOCAL
.credentials("clientId", "clientSecret")
.build();
// 1) Log in (tokens are stored automatically)
LoginResult login = client.auth.connect("patient@example.com", "•••••••", "email");
if (login.twoFactorRequired()) {
client.auth.connectWithTwoFactor("123456", login.twoFactorResponse());
}
// 2) Search — returns a Jackson JsonNode (the "data" payload)
JsonNode result = client.doctors.search(new SearchInput(
Map.of("withFreeText", "kardiyoloji"), List.of("slot"), List.of("isInterviewable"), 1, 20));
// 3) Slots, then 4) reserve ("yyyy-MM-dd HH:mm")
Object doctorId = result.get("foundDoctors").get(0).get("doctor_id").asInt();
JsonNode slots = client.slots.schedule(doctorId, "interview");
client.appointments.reserveInterview(doctorId, "2026-06-20 14:30");| Field | Methods |
|---|---|
client.auth |
connect, connectWithTwoFactor, register, refresh, disconnect |
client.doctors |
branches, locations, quickSearch, search, detail |
client.slots |
schedule |
client.appointments |
reserveInterview, addPhysical, cancel |
client.payments |
checkDiscountCode, getCards, saveCard, pay, deleteCard |
client.measures |
addList, add, update, delete, last, list, graph, partnerHealthInformation |
Data methods return com.fasterxml.jackson.databind.JsonNode.
connect/connectWithTwoFactor/registerstore tokens automatically.- On a
401(orresultType 4), the SDK silently refreshes once and retries (thread-safe, single shared refresh). - Inject a custom store with
.tokenStore(...)(implementTokenStore).
All extend BulutklinikException: TransportException and ApiException →
ValidationException (422), AuthenticationException (401 / logout),
AuthorizationException (403), NotFoundException (404), RateLimitException
(429). Details are on ApiException.context().
try {
client.payments.pay(input);
} catch (RateLimitException e) {
System.out.println("retry after " + e.context().retryAfter());
} catch (ValidationException e) {
System.out.println("invalid: " + e.context().data());
}payments.pay returns data containing payment3DUrl on a 3DS flow — a browser
URL to open. The bank → server callback completes the capture.
mvn -B verifyMIT