---
title: "Raw map"
description: "Use SeatLayerView and SeatLayerController from Flutter 0.7.2 when your application intentionally owns every buyer control and hold transition."
---

> 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

`SeatLayerView` is the low-level Flutter map. It remains source-compatible with
the original `0.2.x` surface inside `seatlayer: 0.7.2`.

Choose it only when your app will own confirmation, cart, hold timing,
validation messages, test-mode disclosure, required attribution, recovery, and
checkout. If you want a different arrangement without reimplementing those
rules, use [`SeatLayerPickerScope`](/buyer-sdk/flutter/custom-layout) instead.

## Create and own the controller

```dart title="raw_seat_map.dart"
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:seatlayer/seatlayer.dart';

class RawSeatMap extends StatefulWidget {
  const RawSeatMap({super.key});

  @override
  State<RawSeatMap> createState() => _RawSeatMapState();
}

class _RawSeatMapState extends State<RawSeatMap> {
  final controller = SeatLayerController();
  StreamSubscription<void>? holdExpired;

  @override
  void initState() {
    super.initState();
    holdExpired = controller.onHoldExpired.listen((_) {
      returnBuyerToSelection();
    });
  }

  @override
  void dispose() {
    holdExpired?.cancel();
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SeatLayerView(
      controller: controller,
      configuration: SeatLayerConfiguration(
        event: 'ev_your_event_key',
        publicKey: 'pk_test_your_public_key',
        currency: 'USD',
      ),
      onReady: (info) => debugPrint('SeatLayer mode: ${info.mode.raw}'),
      onLoadError: showLoadError,
    );
  }
}
```

The controller and configuration are required. Keep one controller for the
mounted view lifecycle, and give the map a definite height or full-screen
parent.

For gated inventory, replace `publicKey` with the renewable provider:

```dart
final configuration = SeatLayerConfiguration(
  event: 'ev_private',
  buyerAccessTokenProvider: (request) =>
      buyerBackend.mintSeatLayerAccess(request.reason),
);
```

Your backend creates the native buyer-access session through
[buyer access sessions](/server-api/buyer-access-sessions), returns only its
short-lived token to the authenticated app, and treats SDK access details as
opaque. It never exposes a SeatLayer secret.

### Configuration map

| Concern | `SeatLayerConfiguration` fields |
| --- | --- |
| Identity and access | `event`, `publicKey`, `buyerAccessToken`, `buyerAccessTokenProvider` |
| Selection policy | `maxSelection`, `selectedObjects`, `selectableObjects`, `numberOfPlacesToSelect`, `selectionValidators` |
| Presentation | `locale`, `messages`, `currency`, `colorblindSafe`, `initialView`, `showsWebSeatTooltip` |
| Operations | `commandTimeout`, `handshakeTimeout`, `hostInfo` |

See the
[complete tagged constructor and field documentation](https://github.com/seatlayer/seatlayer-flutter/blob/v0.7.2/lib/src/seat_layer_configuration.dart)
for types, defaults, and validation.

## Common command groups

This table is a task-oriented map, not a substitute for the complete tagged API.

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

Use the
[tagged `SeatLayerController` source](https://github.com/seatlayer/seatlayer-flutter/blob/v0.7.2/lib/src/seat_layer_controller.dart)
for exact parameters, return types, and every method in `0.7.2`. Feature controls
should also respect reported capability state; a public method does not prove a
particular Event supports the operation.

Commands return `Future`s and throw `SeatLayerError` at the awaited call site.

```dart
try {
  final hold = await controller.hold();
  if (hold != null) {
    await checkoutBackend.begin(holdId: hold.holdId);
  }
} on SeatLayerError catch (error) {
  showInventoryMessage(error.code, error.message);
}
```

## Typed streams

Important streams include `onReady`, `onSelectionChanged`,
`onSelectionValidityChanged`, `onHold`, `onHoldRestored`, `onHoldExpired`,
`onBuyerAccessExpired`, `onBuyerAccessUnavailable`,
`onSelectedObjectsUnavailable`, `onGAClick`, `onSeatHover`, `onError`, and
`onUnknownEvent`.

Subscribe once, retain each `StreamSubscription`, and cancel it from `dispose`.
Unknown future enum values and events remain inspectable rather than crashing an
older application.

| Stream | Payload and host responsibility |
| --- | --- |
| `onSelectionChanged` | Full current `List<SelectedSeat>`; replace local selection rather than appending |
| `onSelectionValidityChanged` | `SelectionValidity`; enable host confirmation only when the configured rules are satisfied |
| `onHold`, `onHoldRestored`, `onHoldExpired` | Authoritative hold changes; expiry carries no reusable local hold |
| `onBuyerAccessExpired`, `onBuyerAccessUnavailable` | Refresh outcome or access refusal; never silently widen private inventory |
| `onSelectedObjectsUnavailable` | Labels and reason for inventory that must be removed from host UI |
| `onError`, `onUnknownEvent` | Typed operational failure or forward-compatible raw event for diagnostics |

## Raw-map responsibilities

The complete picker normally owns these behaviors. A raw integration must
provide them explicitly:

- selection confirmation and validation feedback;
- general-admission quantity and tier selection;
- test-mode disclosure and required attribution;
- hold countdown, server-authoritative expiry, resume, and release;
- background/foreground reconciliation;
- unavailable-inventory recovery;
- gesture-safe overlays and accessible controls;
- back-navigation behavior; and
- secure checkout handoff.

Do not duplicate venue behavior by forwarding touch coordinates or placing the
map inside another pan/zoom surface. Use typed commands and let the canvas own
its gestures.

## Security boundary

`HoldResult` contains a display-oriented view of a temporary hold. Send only
`holdId` plus your own order context to your backend. The backend inspects the
hold, calculates the authoritative price, takes payment, and reuses the same
`bookingRef` for retries.

## Related pages

- [Flutter quick start](/buyer-sdk/flutter)
- [Picker architecture](/buyer-sdk/flutter/architecture)
- [Build a custom picker layout](/buyer-sdk/flutter/custom-layout)
- [Lifecycle and recovery](/buyer-sdk/flutter/lifecycle-and-recovery)
- [Shared troubleshooting matrix](/buyer-sdk/mobile#troubleshooting)
- [Tagged runnable example](https://github.com/seatlayer/seatlayer-flutter/tree/v0.7.2/example)
- [Tagged changelog](https://github.com/seatlayer/seatlayer-flutter/blob/v0.7.2/CHANGELOG.md)

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