Skip to main content
GET
/
api
/
public
/
v2
/
products
/
{productId}
/
seatmap
curl --location 'https://www.headout.com/api/public/v2/products/<PRODUCT_ID>/seatmap/'
<html>

<head>
    <meta name="robots" content="noindex" />
    <link rel="stylesheet" href="https://assets.headout.com/mufasa/static/css/seatmap/fonts-730bdf39.css"
        type="text/css" />
    <link rel="stylesheet" href="https://assets.headout.com/mufasa/static/css/seatmap/seatmap-c6eb6f29.css"
        type="text/css" />
</head>

<body>
    <script type="text/javascript">
        window.partialView = [];
      window.svgUrl = "https://assets.headout.com/seatmap/venue/3314/live/inhouse-seatmap.svg";
      window.svgBackgroundUrl = "https://assets.headout.com/seatmap/venue/3314/live/seatmap-background.svg";
      window.tourGroupId = "3023";
      window.environmentDomainName = "headout.com";
      window.showList = false;
      window.environment = "PRODUCTION";
      window.includeExtraCharges = true;
      window.isB2B = true;
      window.parentOrigin = "https://example.com";
    </script>
    <div id="discountLegend" class="discount-legend" style="visibility: hidden">
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path
                d="M8.19296 3.13399C8.52311 2.46514 9.47688 2.46514 9.80704 3.13399L11.1083 5.77021C11.2393 6.03557 11.4923 6.21958 11.7852 6.26238L14.6966 6.68793C15.4345 6.79579 15.7286 7.70284 15.1944 8.22319L13.0891 10.2737C12.8768 10.4805 12.7799 10.7785 12.83 11.0706L13.3267 13.9664C13.4528 14.7017 12.681 15.2623 12.0207 14.9151L9.41891 13.5468C9.15666 13.4089 8.84334 13.4089 8.58109 13.5468L5.97927 14.9151C5.319 15.2623 4.54721 14.7017 4.67331 13.9664L5.16998 11.0706C5.22007 10.7785 5.12318 10.4805 4.91089 10.2737L2.80561 8.22319C2.27138 7.70284 2.56548 6.79579 3.3034 6.68793L6.21483 6.26238C6.50765 6.21958 6.76071 6.03557 6.8917 5.7702L8.19296 3.13399Z"
                fill="#FF007A" />
        </svg>
        <span class="discount-legend-text">Discounted Seats</span>
    </div>

    <div id="zoomControls" class="zoom-controls no-display">
        <div class="zoom-increase">
            <div class="tooltip">
                <span>Zoom In</span>
            </div>
            <div class="zoom-svg">
                <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
                    viewBox="0 0 31.444 31.444" style="enable-background: new 0 0 31.444 31.444" xml:space="preserve">
                    <path
                        d="M1.119,16.841c-0.619,0-1.111-0.508-1.111-1.127c0-0.619,0.492-1.111,1.111-1.111h13.475V1.127
                                C14.595,0.508,15.103,0,15.722,0c0.619,0,1.111,0.508,1.111,1.127v13.476h13.475c0.619,0,1.127,0.492,1.127,1.111
                                c0,0.619-0.508,1.127-1.127,1.127H16.833v13.476c0,0.619-0.492,1.127-1.111,1.127c-0.619,0-1.127-0.508-1.127-1.127V16.841H1.119z" />
                </svg>
            </div>
        </div>
        <div class="zoom-decrease">
            <div class="tooltip">
                <span>Zoom Out</span>
            </div>
            <div class="zoom-svg">
                <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
                    viewBox="0 0 31.427 31.427" style="enable-background: new 0 0 31.427 31.427" xml:space="preserve">
                    <path d="M1.111,16.832C0.492,16.832,0,16.325,0,15.706c0-0.619,0.492-1.111,1.111-1.111H30.3
                                c0.619,0,1.127,0.492,1.127,1.111c0,0.619-0.508,1.127-1.127,1.127H1.111z" />
                </svg>
            </div>
        </div>
        <div class="zoom-reset no-display">
            <div class="tooltip">
                <span>Reset Zoom</span>
            </div>
            <div class="zoom-svg">
                <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
                    viewBox="0 0 34.652 34.652" style="enable-background: new 0 0 34.652 34.652" xml:space="preserve">
                    <g>
                        <g>
                            <path d="M15.529,32.855C6.966,32.855,0,25.889,0,17.326C0,8.763,6.966,1.797,15.529,1.797
                                        c8.563,0,15.529,6.967,15.529,15.529c0,0.49-0.397,0.888-0.888,0.888c-0.49,0-0.888-0.397-0.888-0.888
                                        c0-7.584-6.17-13.755-13.754-13.755c-7.585,0-13.755,6.171-13.755,13.755c0,7.584,6.17,13.754,13.755,13.754
                                        c4.852,0,9.397-2.601,11.862-6.787c0.249-0.423,0.793-0.562,1.215-0.314c0.422,0.248,0.562,0.792,0.315,1.215
                                        C26.139,29.919,21.007,32.855,15.529,32.855z" />
                        </g>
                        <g>
                            <path d="M30.17,18.214c-0.153,0-0.309-0.04-0.45-0.123l-5.561-3.284c-0.422-0.249-0.562-0.793-0.313-1.215
                                        c0.25-0.422,0.794-0.562,1.216-0.312l4.852,2.865l3.123-4.473c0.281-0.402,0.834-0.5,1.235-0.22c0.402,0.28,0.5,0.833,0.22,1.235
                                        l-3.594,5.146C30.726,18.08,30.451,18.214,30.17,18.214z" />
                        </g>
                    </g>
                </svg>
            </div>
        </div>
    </div>

    <div id="seatmap"></div>
    <script type="text/javascript" src="https://assets.headout.com/mufasa/static/js/seatmap/seatmap-WrQZGe4-.js">
    </script>
</body>

</html>
For products with inventorySelectionType: SEATMAP. Returns an HTML page that renders the Headout-hosted seat selection UI. Embed this endpoint as an iframe in your integration. Domain whitelisting required — contact the Headout partnerships team to register your domain. The seatmap iframe is a Headout-hosted, fully interactive seat selection UI. Embed it to support seatmap products without building custom seat selection. The endpoint returns a rendered HTML page — not a JSON payload. No API key is required; access is controlled by domain allowlisting.

Domain whitelisting

The iframe enforces an allowlist of permitted embedding domains. Before going live, contact the Headout partnerships team and provide the domain(s) you intend to embed the iframe on. Headout will add your domain to ALLOWED_DOMAINS.
  • Requests from domains not on the allowlist return 403 Forbidden.
  • The allowlist is matched against the browser-sent Referer header.
  • Ensure the page embedding the iframe does not apply a Referrer-Policy of no-referrer or strict-origin-when-cross-origin — either setting suppresses the header and every embed request will return 403.
  • Subdomains of a whitelisted domain are automatically permitted — whitelisting example.com also allows www.example.com.
  • The iframe sets a Content-Security-Policy: frame-ancestors response header scoped to your domain to prevent embedding from unauthorised origins.

Embedding

Add the iframe to your page with the product ID substituted in the src URL:
<iframe
  title="Seatmap"
  id="seatmap-iframe"
  src="https://www.headout.com/api/public/v2/products/3023/seatmap/"
  width="100%"
  height="100%"
></iframe>
Replace 3023 with the actual product ID. The iframe container must have a defined height — height="100%" requires the parent element to have an explicit height set, otherwise the iframe collapses to 0px and nothing renders.

postMessage events

The iframe communicates with the parent page via window.postMessage. All messages in both directions are JSON-stringified in the following envelope:
{ "type": "eventName", "data": { ... } }
Parse incoming messages with JSON.parse(event.data).

Initialisation sequence

The iframe does not load seats automatically. After embedding, you must complete the handshake and pass the selected show slot. 1. Send init once the iframe has loaded
const iframe = document.getElementById('seatmap-iframe');
iframe.addEventListener('load', () => {
  iframe.contentWindow.postMessage(
    JSON.stringify({ type: 'init' }),
    'https://www.headout.com'
  );
});
2. Listen for iframeInitCompleted, then send initPlugin
const iframe = document.getElementById('seatmap-iframe');
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://www.headout.com') return;
  let msg;
  try { msg = JSON.parse(event.data); } catch { return; }
  const { type } = msg;

  if (type === 'iframeInitCompleted') {
    iframe.contentWindow.postMessage(
      JSON.stringify({
        type: 'initPlugin',
        data: {
          options: {
            date: '2026-06-15',         // yyyy-MM-dd from Availabilities response
            time: '19:30:00',           // HH:mm:ss from Availabilities response
            currencyCode: 'GBP',
            deviceType: 'DESKTOP',      // 'DESKTOP' (default) | 'MOBILE'
          },
        },
      }),
      'https://www.headout.com'
    );
  }
});
OptionTypeRequiredDescription
datestringYesSelected show date in yyyy-MM-dd format (from Availabilities response)
timestringYesSelected show time in HH:mm:ss format (from Availabilities response)
currencyCodestringYesCurrency code for pricing (e.g. GBP, USD)
deviceTypestringNoControls layout — DESKTOP (default) or MOBILE
Without initPlugin the map renders empty — no seats will be displayed.

Outbound events

All outbound events follow the envelope { "type": "...", "data": { ... } }.

Map lifecycle

TypeDataWhen
initializingSeatmapStartedMap has begun rendering after initPlugin. Show a loading state.
initializingSeatmapCompletedMap is fully rendered and interactive. Hide the loading state.

Seat events

TypeDataWhen
onSeatAdded{ seat }A single seat was added to the selection.
onSeatRemoved{ seat }A single seat was removed from the selection.
onSeatSelectionChanged{ seats }Fires on every seat add or remove — reflects the full current selection.
onSeatSelectionSubmitted{ seats }User confirmed their selection — use these seats for Validate and Booking.
Handling onSeatSelectionSubmitted:
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://www.headout.com') return;
  let msg;
  try { msg = JSON.parse(event.data); } catch { return; }
  const { type, data } = msg;

  if (type === 'onSeatSelectionSubmitted') {
    const { seats } = data;
    // Pass seats to the Validate endpoint, then proceed to Booking
  }
});

Inventory events

Emitted on initial seatmap load (after initPlugin) and on every subsequent setInventorySlot call.
TypeDataWhen
inventoryUpdateStartedInventory fetch has begun. Show a loading state.
inventoryUpdateCompletedInventory loaded and map is ready. Hide the loading state.

Price filter events

TypeDataWhen
onPriceFilterClick{ filters }User clicked a price filter option.
applyFilterClicked{ numberOfPricesSelected }User applied the selected price filters (mobile).
clearFilterClickedUser cleared all applied filters (mobile).
priceListOpenedPrice filter list opened (mobile).
priceListClosedPrice filter list closed (mobile).
priceListClickedPrice list was clicked (mobile).

Zoom events

TypeDataWhen
onZoomLevelChangedZoom level changed.
onZoomInButtonClickZoom in button clicked.
onZoomOutButtonClickZoom out button clicked.
onZoomResetButtonClickZoom reset button clicked.

Other

TypeDataWhen
log{ data }Internal debug message from the iframe.

Seat object

Each item in the seats array (from onSeatAdded, onSeatRemoved, onSeatSelectionChanged, and onSeatSelectionSubmitted) has the following shape:
FieldTypeDescription
idstringSVG seat identifier. Pass as ids in selectSeats and as id in addSeat / removeSeat.
seatCodestringPass as inventorySeatIds in the Validate and Booking requests.
inventorySlotIdstringPass as inventoryId in the Validate and Booking requests.
pricenumberPer-seat price in the selected currency.
originalPricenumberPre-discount price.
currencystringLocal currency symbol (e.g. £).
discountedbooleantrue if a discount is applied to this seat.
seatNumberstringSeat number — use for display purposes.
seatRowstringRow identifier — use for display purposes.
seatSectionstringSection name — use for display purposes.
colorstringHex color assigned to this seat’s price tier — use for display matching.
descriptionstringSeat or category description — use for display purposes.
remainingnumberSeats remaining in this category.
maxAvailablenumberMaximum seats bookable per transaction in this category.

Inbound commands

The parent can send commands to the iframe after initialisation:
TypeDataDescription
setInventorySlot{ options: { date, time, currencyCode } }Update the show slot without re-embedding. date format is yyyy-MM-dd, time format is HH:mm:ss. Triggers inventoryUpdateStarted / inventoryUpdateCompleted.
selectSeats{ ids: string[] }Pre-select seats by seat id.
addSeat{ id: string }Add a seat by seat id.
removeSeat{ id: string }Remove a seat by seat id.

Security

The iframe only accepts messages originating from the whitelisted parentOrigin. Send all messages to https://www.headout.com as the target origin and ensure your domain is registered in ALLOWED_DOMAINS.

Next steps

Once onSeatSelectionSubmitted fires, pass the returned seat data to Validate to confirm availability, then proceed to Booking.
curl --location 'https://www.headout.com/api/public/v2/products/<PRODUCT_ID>/seatmap/'
<html>

<head>
    <meta name="robots" content="noindex" />
    <link rel="stylesheet" href="https://assets.headout.com/mufasa/static/css/seatmap/fonts-730bdf39.css"
        type="text/css" />
    <link rel="stylesheet" href="https://assets.headout.com/mufasa/static/css/seatmap/seatmap-c6eb6f29.css"
        type="text/css" />
</head>

<body>
    <script type="text/javascript">
        window.partialView = [];
      window.svgUrl = "https://assets.headout.com/seatmap/venue/3314/live/inhouse-seatmap.svg";
      window.svgBackgroundUrl = "https://assets.headout.com/seatmap/venue/3314/live/seatmap-background.svg";
      window.tourGroupId = "3023";
      window.environmentDomainName = "headout.com";
      window.showList = false;
      window.environment = "PRODUCTION";
      window.includeExtraCharges = true;
      window.isB2B = true;
      window.parentOrigin = "https://example.com";
    </script>
    <div id="discountLegend" class="discount-legend" style="visibility: hidden">
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path
                d="M8.19296 3.13399C8.52311 2.46514 9.47688 2.46514 9.80704 3.13399L11.1083 5.77021C11.2393 6.03557 11.4923 6.21958 11.7852 6.26238L14.6966 6.68793C15.4345 6.79579 15.7286 7.70284 15.1944 8.22319L13.0891 10.2737C12.8768 10.4805 12.7799 10.7785 12.83 11.0706L13.3267 13.9664C13.4528 14.7017 12.681 15.2623 12.0207 14.9151L9.41891 13.5468C9.15666 13.4089 8.84334 13.4089 8.58109 13.5468L5.97927 14.9151C5.319 15.2623 4.54721 14.7017 4.67331 13.9664L5.16998 11.0706C5.22007 10.7785 5.12318 10.4805 4.91089 10.2737L2.80561 8.22319C2.27138 7.70284 2.56548 6.79579 3.3034 6.68793L6.21483 6.26238C6.50765 6.21958 6.76071 6.03557 6.8917 5.7702L8.19296 3.13399Z"
                fill="#FF007A" />
        </svg>
        <span class="discount-legend-text">Discounted Seats</span>
    </div>

    <div id="zoomControls" class="zoom-controls no-display">
        <div class="zoom-increase">
            <div class="tooltip">
                <span>Zoom In</span>
            </div>
            <div class="zoom-svg">
                <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
                    viewBox="0 0 31.444 31.444" style="enable-background: new 0 0 31.444 31.444" xml:space="preserve">
                    <path
                        d="M1.119,16.841c-0.619,0-1.111-0.508-1.111-1.127c0-0.619,0.492-1.111,1.111-1.111h13.475V1.127
                                C14.595,0.508,15.103,0,15.722,0c0.619,0,1.111,0.508,1.111,1.127v13.476h13.475c0.619,0,1.127,0.492,1.127,1.111
                                c0,0.619-0.508,1.127-1.127,1.127H16.833v13.476c0,0.619-0.492,1.127-1.111,1.127c-0.619,0-1.127-0.508-1.127-1.127V16.841H1.119z" />
                </svg>
            </div>
        </div>
        <div class="zoom-decrease">
            <div class="tooltip">
                <span>Zoom Out</span>
            </div>
            <div class="zoom-svg">
                <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
                    viewBox="0 0 31.427 31.427" style="enable-background: new 0 0 31.427 31.427" xml:space="preserve">
                    <path d="M1.111,16.832C0.492,16.832,0,16.325,0,15.706c0-0.619,0.492-1.111,1.111-1.111H30.3
                                c0.619,0,1.127,0.492,1.127,1.111c0,0.619-0.508,1.127-1.127,1.127H1.111z" />
                </svg>
            </div>
        </div>
        <div class="zoom-reset no-display">
            <div class="tooltip">
                <span>Reset Zoom</span>
            </div>
            <div class="zoom-svg">
                <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
                    viewBox="0 0 34.652 34.652" style="enable-background: new 0 0 34.652 34.652" xml:space="preserve">
                    <g>
                        <g>
                            <path d="M15.529,32.855C6.966,32.855,0,25.889,0,17.326C0,8.763,6.966,1.797,15.529,1.797
                                        c8.563,0,15.529,6.967,15.529,15.529c0,0.49-0.397,0.888-0.888,0.888c-0.49,0-0.888-0.397-0.888-0.888
                                        c0-7.584-6.17-13.755-13.754-13.755c-7.585,0-13.755,6.171-13.755,13.755c0,7.584,6.17,13.754,13.755,13.754
                                        c4.852,0,9.397-2.601,11.862-6.787c0.249-0.423,0.793-0.562,1.215-0.314c0.422,0.248,0.562,0.792,0.315,1.215
                                        C26.139,29.919,21.007,32.855,15.529,32.855z" />
                        </g>
                        <g>
                            <path d="M30.17,18.214c-0.153,0-0.309-0.04-0.45-0.123l-5.561-3.284c-0.422-0.249-0.562-0.793-0.313-1.215
                                        c0.25-0.422,0.794-0.562,1.216-0.312l4.852,2.865l3.123-4.473c0.281-0.402,0.834-0.5,1.235-0.22c0.402,0.28,0.5,0.833,0.22,1.235
                                        l-3.594,5.146C30.726,18.08,30.451,18.214,30.17,18.214z" />
                        </g>
                    </g>
                </svg>
            </div>
        </div>
    </div>

    <div id="seatmap"></div>
    <script type="text/javascript" src="https://assets.headout.com/mufasa/static/js/seatmap/seatmap-WrQZGe4-.js">
    </script>
</body>

</html>

Path Parameters

productId
integer
required

Product ID of the seatmap product.

Response

Seat selection HTML page rendered successfully.