VPN Locations
KapeLocationService fetches available VPN server locations from the Low Level SDK and
exposes them as observable StateFlow collections.
Setup
The list is scoped to a VPN protocol, so the service needs to know which one. KapeVpnManager
supplies the user's persisted selection:
val vpnManager = KapeVpnManager(
handle,
protocols = listOf(KapeWireGuardSupport, KapeLightwaySupport, KapeOpenVpnSupport),
)
val locationService = vpnManager.createLocationService()
A consumer that depends on KapeVPN-Discovery alone — no tunnel, so no persisted selection —
passes the protocol itself:
import com.kape.platformsdk.vpn.discovery.KapeLocationService
import com.kape.platformsdk.vpn.discovery.models.KapeVPNProtocol
val locationService = KapeLocationService(handle) { KapeVPNProtocol.OpenVPN }
There is no default on purpose: one would hand every caller the union of all three protocols, and a location that serves only Lightway cannot connect over OpenVPN.
Fetching locations
fetchLocations() is a suspend function that calls the Low Level SDK, maps the results
into KapeServerLocation models, and updates the allLocations and locationsByContinent
state flows. It returns a FetchLocationsResult — no exception is thrown on failure.
Only locations serving the selected protocol come back. The protocol is read once per call and
nothing observes it, so call fetchLocations() again after setSelectedProtocol(...).
import com.kape.platformsdk.vpn.discovery.FetchLocationsResult
when (val result = locationService.fetchLocations()) {
is FetchLocationsResult.Success -> {
// allLocations and locationsByContinent are now populated
}
is FetchLocationsResult.SdkError -> {
val error = result.error // KapeError with domain and message
}
}
Observing locations
Both state flows are empty until the first successful fetchLocations() call.
// Flat list
locationService.allLocations.collect { locations: List<KapeServerLocation> ->
// update your server list UI
}
// Grouped by continent (localized continent name → list of locations)
locationService.locationsByContinent.collect { byContinent: Map<Continent, List<KapeServerLocation>> ->
// render a section per continent
}
KapeServerLocation model
| Property | Type | Description |
|---|---|---|
id | String | Unique location identifier used by the Low Level SDK |
name | String | Human-readable location name (e.g. "New York") |
country | String | ISO 3166-1 alpha-2 country code (e.g. "US") |
continent | String | Localized continent name resolved from country (e.g. "Americas") |
latitude | Double | Geographic latitude |
longitude | Double | Geographic longitude |
rating | KapeLocationRating | Smart location rating; Unknown until smart locations are fetched |
KapeLocationRating
enum class KapeLocationRating { Excellent, Good, Ok, Degraded, Poor, Unknown }
Rating is populated by a future fetchSmartLocations() call. All locations returned by
fetchLocations() have rating Unknown until then.
Fetching endpoints
fetchEndpoints(forLocation:) returns the VPN endpoints the SDK would attempt for a location,
in the same order the tunnel tries them — useful for diagnostics (e.g. pre-blocking specific
hosts to simulate network failures). Requires a prior successful login; the call waits for the handle's
subscription pick to settle.
Pass protocol to narrow the answer to one protocol. It defaults to KapeVPNProtocol.Automatic,
which asks for every protocol the SDK would attempt.
import com.kape.platformsdk.vpn.discovery.FetchEndpointsResult
import com.kape.platformsdk.vpn.discovery.models.KapeVPNProtocol
when (val result = locationService.fetchEndpoints(forLocation = "59")) {
is FetchEndpointsResult.Success -> {
result.endpoints.forEach { endpoint ->
println("${endpoint.host}:${endpoint.port} (${endpoint.protocolName})")
}
}
is FetchEndpointsResult.SdkError -> {
val error = result.error // KapeError with domain and message
}
}
// Only the OpenVPN endpoints
locationService.fetchEndpoints(forLocation = "59", protocol = KapeVPNProtocol.OpenVPN)
A location the backend serves no matching endpoints for yields Success with an empty list, not an
error.
KapeVPNEndpointInfo model
| Property | Type | Description |
|---|---|---|
host | String | Endpoint address — an IP literal, or a hostname for an HTTP proxy |
port | Int | Endpoint port |
protocolName | String | "wireguard", "openvpn", "lightway" or "httpproxy" |
This model describes an endpoint well enough to list, filter or pick one; it is deliberately not
enough to connect with or to build a config file from. For the full OpenVPN payload — the
server-supplied .ovpn contents, MTU, cert DN and XOR value — use
KapeVPNDiscoveryService.