---
title: "Raw map API"
description: "Use SeatLayerView, SeatLayerConfiguration, coroutine commands, and typed flows from the preserved raw-map surface in Android 0.3.4."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.seatlayer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Raw map API

This page covers the preserved raw-map API in
`io.seatlayer:seatlayer-android:0.3.4`. It does not require the Compose
artifact.

## Core types

| Type | Responsibility |
| --- | --- |
| `SeatLayerView` | `FrameLayout` map host with `load`, `controller`, and `destroy` |
| `SeatLayerConfiguration` | Event, locale, currency, selection rules, buyer access, and timeouts |
| `SeatLayerController` | Suspending commands plus ready, bundle, and event flows |
| `BuyerAccessTokenProvider` | Kotlin `fun interface` with a suspending `provide(context)` method |
| `HoldResult` | Opaque hold ID, server expiry, selected seats, and display items |
| `SeatLayerException` | Typed load, access, compatibility, timeout, and command failures |

## Configure buyer access

```kotlin
val configuration = SeatLayerConfiguration(
    event = "ev_your_event_key",
    maxSelection = 6,
    locale = "en",
    currency = "USD",
    buyerAccessTokenProvider = BuyerAccessTokenProvider { context ->
        buyerBackend.mintSeatLayerAccess(context.reason)
    },
)
```

The provider returns `BuyerAccessToken(token, expiresAt)` in memory. Prefer it
to a one-shot token when the screen must renew access without rebuilding the
view.

Mint the native buyer-access session on your backend through
[buyer access sessions](/server-api/buyer-access-sessions), return only its
short-lived token, and treat SDK access details as opaque. The
[tagged configuration declaration](https://github.com/seatlayer/seatlayer-android/blob/v0.3.4/seatlayer/src/main/kotlin/io/seatlayer/android/SeatLayerConfiguration.kt)
lists every field in `0.3.4` for access, selection rules, presentation, deadlines,
and diagnostics.

## Observe lifecycle-aware state

```kotlin
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        launch {
            seatMap.controller.events.collect(::handleSeatLayerEvent)
        }
        launch {
            seatMap.controller.ready.collect(::renderReadyState)
        }
    }
}
```

`ready` contains the current `ReadyInfo?`; `events` emits typed selection,
validity, access, hold, general-admission, seat-hover, error, and unknown-future
events. A raw-map host must explicitly call `controller.hold()` and start
checkout with only `holdId`; no map event is booking authority.

Handle payloads exhaustively where your product has behavior:

```kotlin
when (event) {
    is SeatLayerEvent.SelectionChanged -> renderSelection(event.seats)
    is SeatLayerEvent.SelectionValidityChanged ->
        setContinueEnabled(event.validity.isValid)
    SeatLayerEvent.HoldExpired -> returnBuyerToSelection()
    is SeatLayerEvent.BuyerAccessUnavailable -> showAccessError(event.event)
    is SeatLayerEvent.SelectedObjectsUnavailable ->
        explainUnavailable(event.event.labels)
    is SeatLayerEvent.Error -> showInventoryError(event.error)
    else -> Unit
}
```

See the
[tagged event models](https://github.com/seatlayer/seatlayer-android/blob/v0.3.4/seatlayer/src/main/kotlin/io/seatlayer/android/Models.kt)
for every subtype and payload.

## Common command groups

This is a task map, not an exhaustive replacement for the tagged API.

| Group | `SeatLayerController` methods |
| --- | --- |
| Read | `getSelection`, `getSelectionValidity`, `getCurrentHold`, `getGeneralAdmissionAreas`, `getFloors`, `getViewMode` |
| Select | `selectObjects`, `deselectObjects`, `clearSelection`, `selectCategories`, `deselectCategories`, `setSelectableObjects`, `setMaxSelection`, `setSeatTier` |
| Hold | `hold`, `resumeHold`, `extendHold`, `release`, `releaseLabels`, `bestAvailable`, `holdGeneralAdmission` |
| Access | `refreshAccess` |
| Map | `setFloor`, `setColorblindSafe`, `setViewMode`, `zoomIn`, `zoomOut`, `zoomToFit` |

Use the
[tagged controller source](https://github.com/seatlayer/seatlayer-android/blob/v0.3.4/seatlayer/src/main/kotlin/io/seatlayer/android/SeatLayerController.kt)
for exact parameters, return types, and every method in `0.3.4`. Gate optional
controls with the reported capability information rather than assuming method
presence means the current Event supports it.

Commands are suspending. Catch `SeatLayerException` around the awaited action so
inventory conflict, timeout, incompatibility, or destroyed-session feedback is
attached to the operation that failed.

```kotlin
lifecycleScope.launch {
    try {
        val hold = seatMap.controller.bestAvailable(quantity = 4)
        if (hold != null) checkoutBackend.begin(holdId = hold.holdId)
    } catch (error: SeatLayerException) {
        showInventoryMessage(error.code, error.message)
    }
}
```

## Restore a hold

```kotlin
val restored = seatMap.controller.resumeHold(persistedHoldId)
if (restored == null) returnBuyerToSelection()
```

The server expiry is authoritative. A paused process timer cannot prove that a
hold remains active.

## View ownership and cleanup

- `load(configuration)` prepares the map and returns `ReadyInfo`.
- Commands are sent through `seatMap.controller`, never `seatMap.hold()`.
- `destroy()` permanently releases the view; create a new view for another
  session.
- Give the view a definite size and keep it outside competing gesture parents.

## Related pages

- [Android SDK overview](/buyer-sdk/android)
- [Compose, Views, and headless picker](/buyer-sdk/android/native-picker)
- [Holds and checkout](/buyer-sdk/holds-and-checkout)
- [Lifecycle, Back, and recovery](/buyer-sdk/android#lifecycle-back-and-recovery)
- [Shared troubleshooting matrix](/buyer-sdk/mobile#troubleshooting)
- [Tagged sample](https://github.com/seatlayer/seatlayer-android/tree/v0.3.4/sample)
- [Tagged changelog](https://github.com/seatlayer/seatlayer-android/blob/v0.3.4/CHANGELOG.md)

Source: https://docs.seatlayer.io/buyer-sdk/android/raw-map/index.mdx
