Release 1.71.0
Important Release Documents
Release Notes - Seatmap Platform
Version 1.71.0 - 2026-08-13
Release Focus: A release built around richer section data and a faster, more granular booking API. Sections can now carry photos, attached in the editor and delivered to the booking renderer for each ticketing site to present in its own design. The booking renderer loads prices and availability separately so a repeat load pays the full cost only for the part that actually changes, the public booking API prices whole sections, rows and general admission areas in a single call, and exposes every seat of an event through one paginated endpoint. Venue background processing is several times faster, the booking renderer transfers 43 percent less over the wire, and the schema editor fixes a run of pricing, undo and background defects.
MetaTitle: Release 1.71.0: Section Photos & Booking API - Seatmap.pro
MetaDescription: Seatmap 1.71.0 adds section photos, loads prices and availability separately, prices sections in one call, and speeds up venue background processing.
New in the schema editor
Photos on a section (SEAT-1134)
A section can now carry photos — the view from the section, its entrance, its amenities — attached in the editor and delivered with the schema to the booking renderer. Up to ten photos per section, on both seated and general admission sections, each with an optional caption, ordered by drag. Uploads are stored as optimized webp with a thumbnail variant, and the photos survive save, reload and a pull from the venue library.
The renderer does not draw the photos. It hands them to the host page on ISection.photos, in onSectionClick, onSectorClick and onSectionsSelectionChange, so each ticketing site renders the gallery in its own design. Sections without photos change nothing in the booking payload.
Photos belong to the venue schema rather than to an event, so a section shows the same photos across every event on that schema.
New in the booking API
The renderer loads prices and availability separately (SEAT-1117)
GET /api/public/v1.0/event/prices/ answers two questions in one response: which price applies to each seat, and which seats are still free. The two change at very different rates, so a single seat being held meant the whole response had to be built again and none of it could be reused between requests.
The booking renderer now reads the two apart, over a pair of endpoints reserved for it. The half that answers which price applies where is revalidated rather than re-sent, and is invalidated by a price change rather than by a timer, so a price edited in the editor applies to the very next load. The half that answers what is no longer for sale stays small and is read fresh every time. On a hundred-thousand-seat event a repeat load transfers and parses a small fraction of what the single response cost.
These two endpoints are an internal contract between the renderer and the service, and their shape follows the renderer without notice. GET /api/public/v1.0/event/prices/ remains the supported way to read an event’s prices and availability directly: it is unchanged and keeps working, in both shape and ordering. An up-to-date renderer falls back to it if either of the pair fails, so it still works against an older backend.
Assign prices to whole sections, rows and areas in one call (SEAT-1138)
POST /api/private/v2.0/event/{eventId}/prices/assignments/areas/ prices whole sections, rows, general admission areas and individual seats in a single request. The target kind is resolved from the schema, so a caller sends object ids without saying whether each one is a section, a row or a GA area, and a section of several thousand seats is priced in one call instead of one call per seat. The response reports the resolved kind and the number of seats updated for each target.
For a general admission area the request may also carry a quantity; sending the price alone re-targets the existing assignment and leaves live inventory untouched. Individual seat entries are applied last, so they override the price of the area they belong to within the same request.
The existing per-seat assignment endpoint is unchanged.
One call for every seat of an event (SEAT-1139)
GET /api/private/v2.0/events/{id}/seats/ returns one flat record per seat of an event, carrying the seat, its row and its section by both identifier and label, together with the state and price the seat holds for that event. It replaces the previous approach of combining a schema-scoped seat listing with a renderer payload and reassembling the records by identifier.
State is reported as ACTIVE for a seat on sale, LOCKED for a seat held, SOLD for a seat bought and BLOCKED for a seat withdrawn from sale. A seat with no price assigned for the event reports no state and is not available.
The response is paginated and can be sorted by any field it returns. It can be narrowed with sectionId and rowId. Passing lastUpdated returns only the seats changed at or after that point, so an integration can poll for changes rather than re-reading the whole venue; echo the largest updatedAt of the previous response back verbatim, as both values are local date-times on the service clock and carry no offset. A seat whose price is removed altogether stops appearing rather than being reported as a change, so a periodic full read is still worth doing.
Row and section labels come from the names shown in the editor. General admission areas are not part of this response, which covers numbered seats only.
What’s fixed in the editor
Address search when creating a venue (SEAT-1141)
Typing an address into the venue dialog returns suggestions again, and the locality and time zone of a new venue are filled from the selected address. When the address service cannot be reached, the dialog now shows a message saying so and inviting the address to be entered by hand, instead of leaving the suggestion list silently empty.
Renaming a pricing zone is saved (SEAT-1125)
Editing a pricing zone in Pricing Zones mode now loads the zone’s current name into the dialog and saves the new one. Previously the dialog opened with an empty name field and closed on Save without storing anything, so the change was gone on reopen. A save that fails now reports the error instead of closing the dialog as though it had worked.
Capacity-only changes on a priced section can be saved (SEAT-1161)
Changing only the capacity of a section that already had a price assigned left the editor looking unchanged: the Save button stayed disabled, and the new capacity was lost as soon as the schema was reloaded. Capacity is now recognised as a change on its own, so the edit enables Save and survives a reload. Changing the price itself, or pricing a section for the first time, was unaffected.
Uploaded background artwork keeps its styling (SEAT-1145)
An uploaded SVG background that sets styling on the drawing’s root element now keeps that styling when the schema is reloaded and saved again. Outline-style floor plans exported from design tools, where the shapes carry a stroke and no fill of their own, previously turned solid black after a save. Root-level text styling and marker settings are preserved on the same path.
Backgrounds saved in the affected state do not repair themselves, because the original styling is no longer present in the stored drawing. Uploading the SVG again restores the artwork, and it now survives every later save.
Pricing scopes on the canvas pill in Prices mode (SEAT-1153)
Switching the editor to Prices mode now replaces the canvas pill’s editing chips with the pricing scopes: Edit, Pricing and Pricing Zones. The two scopes can be selected from the pill or with the 3 and 4 keys, and Edit returns to whichever layer was open before pricing was entered. The pill previously kept showing the Seats and Artwork chips in Prices mode, so moving between the pricing scopes was only possible by keyboard.
Selecting a general admission section no longer blocks seat selection (SEAT-1162)
In Prices mode, clicking a general admission section switched the editor to section selection and kept the section active, so picking seats afterwards required extra deselection steps — and for GA sections bound to an SVG background element, seat, row and rubber-band selection stopped responding entirely until the section was deselected.
Clicking a GA section now only selects it, opening the quantity and pricing panel while the seat tool stays active. Selecting seats afterwards works in one click and moves the pricing panel to the picked seats, for both drawn GA shapes and GA sections bound to a background SVG.
Switching organization clears the canvas and its undo history (SEAT-1159)
Switching to another organization left the canvas holding the schema that was open before the switch — its seats, sections and settings stayed on screen, and undo kept reaching back through edits made in the organization the user had just left. The editor now starts empty after an organization switch, with an undo history that begins at that point.
Clearing an empty selection no longer consumes an undo step (SEAT-1160)
Pressing Escape, or clicking an empty part of the canvas, registered as an editing step even when there was nothing selected to clear. Doing so after an undo discarded the redo that was waiting, and doing it repeatedly pushed older edits off the end of the undo history until they could no longer be reached. Clearing a selection is now recorded only when it actually changes the selection.
Previews for venues copied from the library (SEAT-1137)
A venue copied from the library now generates its background image and preview thumbnail on its own, so copied schemas show artwork in the venue list and everywhere else a preview is used. Previously a copied schema stayed without a preview until it was opened and saved by hand. Schemas copied before this release keep their empty previews until they are saved once in the editor, which regenerates the artwork.
What’s fixed in the booking renderer
Seatmaps stay usable when a background image cannot be uploaded (SEAT-1147)
When a venue background image cannot be handed to the GPU — for example artwork the browser refuses to let WebGL read, or an image beyond the device’s texture limits — the renderer now draws the seatmap without its background instead of failing partway through. Seats, rows, labels and selection stay interactive, and the map no longer reports a background as ready when the upload did not complete.
Queued drawing work is also discarded once a map has been torn down or its GPU context has been lost, so a map closing mid-render no longer raises an error. Most affected are older mobile Safari versions and in-app browsers, where the browser is most likely to reject the upload.
Backgrounds the browser will not let the renderer read (SEAT-1135)
Preparing the softened backdrop behind a seatmap requires reading the background image back off a canvas, which the browser refuses for artwork served from another origin without the headers that permit it. That refusal stopped the map from drawing. The renderer now keeps the background as it is and carries on, so the seatmap draws and stays interactive. Backgrounds served from the same origin, or with those headers present, are softened exactly as before.
Sections with no seats no longer break the outline layer (SEAT-1157)
A section that carried no seats produced an outline rectangle with unusable geometry, and the result was reused for the rest of the session. Once a section had been measured while its seats were absent — during an event that is still loading, or one whose seat data never arrives — it stayed unmeasured even after the seats became available. Such a section now produces no outline at all until it has seats to measure, and is measured correctly the first time they arrive. Sections with seats are unchanged.
What’s fixed in the booking API
Correct row labels from the seats endpoint (SEAT-1132)
Rows returned by the booking seats endpoint now carry the row’s own label, so a section comes back with rows named “1”, “2”, “3” as they appear in the editor. Previously every row in a section reported the same shared prefix, which made rows indistinguishable to integrators reading that endpoint. Integrators who worked around this by ignoring the row name can now rely on it. The renderer payload is unaffected.
What’s fixed in background conversion
Conversion continues when the GPU is unavailable (SEAT-1163)
With converter.gpu.enabled turned on, GPU rasterization now runs as its own replica alongside a software one. Background and thumbnail conversion continues at software speed whenever the node stops offering the GPU device — most often after a kernel upgrade changes the graphics driver — and resumes on the GPU as soon as the device is offered again. Installations that leave converter.gpu.enabled off are unaffected.
Performance
Faster venue background processing (SEAT-1127)
Converting a venue background is several times faster. A large floor plan that previously took over two and a half minutes now completes in well under a minute, and faster still where the service has a GPU available to it. Uploading artwork for a new venue, and regenerating it after an edit, are correspondingly quicker.
Backgrounds regenerated after this change are not byte-identical to the ones they replace: the rendering differs very slightly at the antialiasing level. The visible result is unchanged.
Smaller renderer bundle (SEAT-1155)
The booking and admin renderer bundles are substantially smaller. The booking renderer now ships 897,767 bytes, or 238,522 compressed, down from 1,503,522 and 417,874 — a 43 percent reduction over the wire. Neither the renderer API nor the embed snippet changes, so pages that load the renderer simply transfer less.
Affected products
- editor-client
- editor-service
- booking-client
- booking-service
- converter-service
- db-migrations
- deployment
Upgrade
This release is backwards compatible. No existing endpoint, renderer method or configuration value changes meaning, and GET /api/public/v1.0/event/prices/ keeps working alongside the new pair.
Two database migrations run on startup. One backfills section coordinates; the other adds an index to the seat state table and is created concurrently, so the table stays readable and writable while it runs, but the migration takes longer on a large installation. Allow for that before upgrading a large deployment.
The editor service and the booking service must share one Redis instance, otherwise a price changed in the editor will not refresh what the booking endpoints serve. The charts deploy a single Redis, which already satisfies this.
Section photos are stored in object storage, so the S3 settings must be configured before the feature is used.
The converter image is now built on a Debian base. GPU rasterization is off by default and enabled with converter.gpu.enabled in the Helm chart; leave it off unless the node exposes a GPU through a device plugin, since a plain device mount silently falls back to software rendering. Turning it on creates a second converter deployment, {release}-converter-gpu, alongside the existing one, so allow for the extra pod when sizing the node. The converter Service selects its pods by a new label in this release, so the upgrade leaves it without an endpoint until the first replacement pod is ready.
Deployments whose Google API key is restricted by referrer should set secrets.google.serverApiKey as well, so address search has a key it can use for server-to-server calls. Left empty it falls back to the existing key, which needs no action where that key is unrestricted.
Full details in the Deployment Guide.
Booking renderer
npm install @seatmap.pro/renderer@1.71.0
New renderer surface in this release: ISection.photos, carrying a section’s photos with their captions and order, delivered in onSectionClick, onSectorClick and onSectionsSelectionChange. Sections without photos are unchanged. No existing renderer method signatures or configuration options changed.
Additional Documentation
- Backend API Changes — bulk area pricing, the per-seat event endpoint, and the positional array layouts
- Renderer API Changes —
ISection.photos, the smaller bundle, and the split price fetch - Deployment Guide