Seatmap Pro 1.73.0

Hold a buyer's seats in a server-side session that survives a reload and cannot be double-booked, queue conversions on the GPU, and retire PDF export.

Seatmap Pro 1.73.0

A buyer’s selection can now live on the server. A booking session holds their seats for a set time, survives a page reload, and cannot be sold twice, and the renderer package ships a client so the booking page can drive it from the browser while your server keeps the secret key for the final confirm. Beyond that, image conversions wait their turn for a GPU instead of failing when it is busy, PDF export is retired in favour of SVG, and a self-hosted deployment can say which environment it is. If you self-host, or you call the section photo endpoint directly, the last section is for you.

A buyer’s seats are held on the server

Until now the renderer’s cart lived in the browser. A reload emptied it, the seats came back to the map, and if two buyers reached checkout with the same seat the loser found out when the sale failed. Integrations papered over this with their own lock bookkeeping, and every one of them did it slightly differently.

A booking session replaces that bookkeeping. You open one for an event and get back a session id; from then on that id is the buyer’s cart. Locking seats against it is all-or-nothing. Either every seat and every general-admission place in the request is held, or nothing changes and the answer names exactly what was taken in the meantime, so the map can show the buyer what happened instead of guessing. A seat belongs to one session at a time. The existing lock and sale endpoints respect that too, so a back-office sale can no longer take a seat out from under a buyer who is paying for it.

Sessions have a clock. An active session holds its seats for fifteen minutes by default; checkout freezes the cart and gives the buyer ten more minutes to pay. Confirming converts every held line to sold in one atomic step and stores your order reference. A session nobody confirms simply expires and the seats go back on sale. Both timers are yours to change.

The public session endpoints need no API key. The session id is the credential, so the booking page can open, hold, release and check out from the browser without your secret key ever leaving the server. The renderer package exports a client for exactly that surface:

import { BookingSessionClient, BookingSessionError } from '@seatmap.pro/renderer';

const sessions = new BookingSessionClient({ baseUrl: 'https://booking.seatmap.pro', publicKey });
const { sessionId } = await sessions.create(eventId);

try {
  await sessions.lock(sessionId, { seats: [1001, 1002], groupOfSeats: [{ id: 77, capacity: 2 }] });
} catch (e) {
  if (e instanceof BookingSessionError && e.code === 'SEAT_CONFLICT') {
    showTaken(e.conflicts?.seats ?? []);
  }
}

const frozen = await sessions.checkout(sessionId);
startCountdown(frozen.expiresInSeconds);

After payment, your server confirms the session with the Secret API key and the order is done. Two helpers, selectionFromCart and selectionFromSession, turn the renderer’s cart into a hold and a session into a release, and restoring the map after a reload is a matter of reading the session back and marking its cart on the renderer.

Sessions are off for every organisation until you switch them on with one call to the session configuration endpoint, so nothing changes for an integration that does not use them. The booking sessions guide walks through the whole flow, and the release notes list every endpoint and error code.

Conversions wait for a GPU instead of failing

Backgrounds, previews, thumbnails and section photos are all rendered by the converter, and until now each one was rendered inside the request that asked for it. If the request happened to land on a converter without a GPU, or on one that was busy, the render was slow, fell back to the CPU, or timed out, and which of those you got was luck.

Conversions are now queued. A GPU converter claims each job first; a CPU converter picks it up only when the GPU one is busy or unavailable, and a job whose converter dies mid-render goes back to the queue and is retried. Section photo upload answers immediately with a request id and the editor polls for the result, so a big photo no longer holds a single request open for minutes.

PDF export goes with this change. It is removed from the editor and the API, and the SVG export is unchanged and remains the format to convert from. The converter’s conversion routes now require a shared secret as well, which the Helm chart generates and wires for you, so anything else that calls the converter directly has to send it.

Tell us which environment you are running

A self-hosted deployment can now declare whether it is production, staging or development with one Helm value, instance.environment (unspecified is also accepted and means the same as leaving it unset). The instance information endpoint returns it alongside a new installation id, and error reports tag themselves with it, so the per-service environment values you may have set by hand are no longer needed. The chart checks the value while rendering and refuses a misspelling, so prod or stage fails at upgrade time rather than quietly reporting as undeclared.

Other Improvements

  • Organization settings label the two integration credentials Public API key and Secret API key, and the Booking API reference uses the same names. Nothing about the values or the headers changed, only what they are called. Super admins now see their tenant token where it is expected.
  • The instance information endpoint returns installationId and environment.
  • The periodic diagnostic check-in from a self-hosted editor identifies the deployment precisely and logs a failed delivery at DEBUG level, so blocked egress is diagnosable locally.

Before you upgrade

Self-hosted deployments have six things to look at. Most need no action.

Three migrations run at startup. They add the tables and columns behind booking sessions, one index on the seat inventory table built concurrently, and the tables for a scheduling feature that has no API surface yet. Nothing existing is altered or dropped. If your migration role is restricted per table, the deployment guide lists the grants.

The converter now queues conversions in Redis by default, so a release that runs it needs a Redis, and the chart wires the release’s own. Set converter.config.async.enabled to false to keep rendering inside the request without one.

If editor-service and the converter run in the same Helm release, the shared secret between them is generated and wired for you. If they run as separate releases, give both the same secrets.converter.apiKey before upgrading either, and upgrade the editor first.

PDF export is gone. An integration that downloaded PDFs must switch to the SVG export. And anything that calls POST /api/section-photo/ directly gets a 202 with a request id now and must poll for the result, which the editor already does itself.

If you set instance.environment, use the full value. An abbreviation that installed cleanly before now fails at render time.

Booking sessions themselves need nothing: the endpoints are served, and accept nothing, until an organisation enables public sessions. Operators who do not want them exposed at all can set global.bookingSessions.enabled to false.

The Helm deployment guide lists the new values and the image converter guide the queue settings. The full detail is in the release notes.

Continue reading

All posts →