Use this page for exact trusted Performance Group operations. Start with the inventory model comparison if you are deciding between an Event, Performance Group, and Season. Follow the end-to-end integration for the full transaction and the buyer picker for UI configuration.
The Performance Groups API coordinates assigned-seat inventory for a run of two to eight compatible Events. Your existing checkout stays in control: you decide the package and price, take payment, create the order, and issue tickets. Use Performance Groups for one multi-date purchase, not a recurring subscription or flexible season membership. A renewable season catalogue with Plan publication and same-seat renewal is handled by the Seasons API instead.
Every route on this page uses a matching sk_test_… or sk_live_… secret key.
Keep that key on your server. Browser access uses the short-lived group token
minted below and is consumed only by PerformanceGroupPicker.
Choose REST or a server SDK
The REST examples on this page are the canonical wire contract. Each official server SDK exposes the same trusted workflow through one resource; choose the package that matches your backend. Before adopting a package release, check the operation support matrix: Live means the published package was verified, while RC means the matching source has passed its release checks but a public package has not yet been verified.
| Backend | Resource |
|---|---|
| Node.js | seatlayer.performanceGroups |
| Python | seatlayer.performance_groups |
| PHP | $seatlayer->performanceGroups |
| Java | seatlayer.performanceGroups() |
| Go | client.PerformanceGroups |
| Ruby | client.performance_groups |
| .NET | client.PerformanceGroups |
The resource creates and manages the group, mints the buyer token, reads the
trusted hold, and confirms the booking. It never gives a server SDK access to
the browser-only /pub/performance-groups/* routes.
API map
| Task | Method and route |
|---|---|
| List or filter groups | GET /v1/performance-groups |
| Create a run | POST /v1/performance-groups |
| Read one run | GET /v1/performance-groups/:groupKey |
| Discard an unused draft | DELETE /v1/performance-groups/:groupKey |
| Activate / close it | POST /:groupKey/activate · POST /:groupKey/close |
| Recover lifecycle progress | GET /:groupKey/lifecycle/:operationId |
| Mint / list / revoke browser sessions | /buyer-access-sessions |
| Inspect the opaque group hold | GET /:groupKey/holds/:operationId |
| Commit inventory and recover booking | POST /holds/:operationId/book · GET /bookings/:bookActionId |
The browser-only descriptor, chart, availability, hold, release, extension, and
operation routes are SDK implementation details. Use PerformanceGroupPicker;
do not call /pub/performance-groups/* from your application.
To list groups, use workspaceId, externalRef, state, limit, and
cursor as needed. The response is { performanceGroups, nextCursor }; pass
the opaque nextCursor back as cursor until it is null. DELETE succeeds
only for a draft; once a group is active, close it and let existing operations
drain instead of trying to replace its dates.
Create a run
POST /v1/performance-groups HTTP/1.1
Authorization: Bearer sk_test_••••••••
Idempotency-Key: production-opening-weekend
Content-Type: application/json
{
"name": "Opening weekend",
"externalRef": "run_2026_opening_weekend",
"eventKeys": ["ev_friday", "ev_saturday", "ev_sunday"],
"inclusionMode": "flexible_dates"
}name is required and limited to 120 characters. externalRef is optional,
stable within the organization, and limited to 128 characters. eventKeys must
contain two to eight distinct compatible Events.
inclusionMode is optional:
| Value | Hold rule |
|---|---|
fixed |
Default. Every activated member must be included in each group hold. |
flexible_dates |
The buyer SDK may hold one or more activated members when a partial seat is unavailable on other dates. |
This policy is stored on the group and returned as inclusionMode in group,
descriptor, operation, and trusted hold projections. It cannot be changed by a
buyer request. Omitting it preserves the behavior of existing integrations.
The server validates organization, workspace, mode, chart snapshot, inventory
model, venue, timezone, currency, sale ownership, start times, and assigned-seat
compatibility before it creates a draft group. 201 returns
{ performanceGroup }, including chronological performances and revision.
Use the same idempotency key when
retrying a lost create response. 409 can
mean an Event already belongs to another group or the external reference is
already in use.
Every compatibility refusal answers error: "incompatible_performances" and
names the specific reason in code: currency_mismatch, chart_mismatch,
invalid_event_count, and so on. It is the one create failure in this API
where the two fields differ, so branch on error to recognise the umbrella and
read code for what to correct. The status follows the reason: 404 when a
performance is unknown, 422 for a malformed set, 409 for a field the
performances cannot safely share. Refusals raised by the route itself
(invalid_name, external_ref_exists) keep the usual
error === code shape.
Activate and close
POST /v1/performance-groups/pg_opening_weekend/activate
Authorization: Bearer sk_test_••••••••
Content-Type: application/json
{ "expectedRevision": 1 }Activation revalidates compatibility and locks the member Events against unsafe
chart or lifecycle changes. A final response contains the active group. A
recoverable 202 includes Location, Retry-After, the current group, and a
lifecycleOperation; poll that location until it is terminal.
Close uses the same body and recovery behavior:
POST /v1/performance-groups/pg_opening_weekend/close
Authorization: Bearer sk_test_••••••••
Content-Type: application/json
{ "expectedRevision": 2 }Closing stops new group holds, lets accepted holds finish or expire, then releases the member locks only after drain proof. There is no reopen. Do not use close as a shortcut to change the dates in a buyer’s existing offer.
Mint browser access
POST /v1/performance-groups/pg_opening_weekend/buyer-access-sessions
Authorization: Bearer sk_test_••••••••
Content-Type: application/json
{
"allowedOrigin": "https://tickets.example.com",
"includePublic": true,
"expiresInSeconds": 1800,
"maxQuantity": 4,
"buyerRef": "buyer_8372"
}allowedOrigin and includePublic are required. The token applies to the
whole active group and is checked on every browser request. expiresInSeconds
is 60 to 43,200; maxQuantity is one to 100 or omitted; buyer and partner
references are opaque values up to 120 characters.
For private sales, pass channelIdsByEvent with an array for each member Event:
{
"allowedOrigin": "https://members.example.com",
"includePublic": false,
"channelIdsByEvent": {
"ev_friday": ["chn_members"],
"ev_saturday": ["chn_members"],
"ev_sunday": ["chn_members"]
}
}The 201 response reveals token only once, alongside sessionId, expiresAt,
and performanceGroupKey. Store the session ID for audit/revocation, return
only token and expiry to the browser, and never automatically retry a response
whose token delivery is uncertain.
Use GET /v1/performance-groups/:groupKey/buyer-access-sessions?limit=50 to
list non-secret session metadata and
DELETE /v1/performance-groups/:groupKey/buyer-access-sessions/:sessionId to
revoke a session immediately.
Inspect the group hold
The browser handoff supplies operationId and holdId. The server-inspection
route is addressed by the operation identity:
GET /v1/performance-groups/pg_opening_weekend/holds/pghop_01J8…
Authorization: Bearer sk_test_••••••••The response contains { hold } with one group hold identity, its common expiry,
selection mode, inclusion mode, group revision, currency, and chronological
allocations. For fixed, allocations contain every group member. For
flexible_dates, they contain only the dates selected and held by the buyer.
Each
allocation includes its Event key/name/time and authoritative inventory line
items. Child hold IDs never appear.
Calculate the commercial order from this trusted allocation list, not from the
browser’s performanceKeys. Booking commits all selected allocations together.
Inspect immediately before your payment decision. 404 means the group,
operation, or hold is not available to this tenant/mode; 409 performance_group_integrity_error is a support escalation, not a reason to
charge or retry with altered IDs.
Book one group hold
POST /v1/performance-groups/pg_opening_weekend/holds/pghop_01J8…/book
Authorization: Bearer sk_test_••••••••
Content-Type: application/json
{
"bookActionId": "pg-book:order_1842",
"bookingRef": "order_1842"
}bookActionId and bookingRef are both required stable identifiers. Reuse the
same pair for every retry of this commercial order. 200 with booking.state: "booked" is final. 202 with booking.state: "book_pending" includes a
Location and Retry-After; poll
GET /v1/performance-groups/:groupKey/bookings/:bookActionId until terminal.
409 book_failed is terminal and may require payment compensation or support
because a child performance can already have settled. Do not create a new action
ID to force another booking attempt.
The terminal booking response or booking poll is checkout authority. The current public operation registry declares no group-specific completion webhook, so do not delay fulfilment waiting for one. Reconcile underlying Event inventory through the documented Event webhook catalog and deduplicate every occurrence.
Error and recovery rules
| Situation | Correct response |
|---|---|
403 buyer_access_mode_mismatch |
Use a test key for a test group and a live key for a live group. |
404 not_found |
Treat as unknown/cross-tenant/mode-mismatched; never reveal more detail to a buyer. |
409 lifecycle pending or revision conflict |
Reload the group and follow the existing lifecycle operation; do not overwrite a revision. |
incompatible_performances (404/409/422) |
Read code for the reason and correct the Event setup before creating a new group. |
202 lifecycle or booking |
Poll the supplied Location using Retry-After. |
| Lost browser hold response | Let PerformanceGroupPicker recover the same operation. |
| Lost server booking response | Retry only with the same bookActionId and bookingRef. |
Next: end-to-end integration and Performance Group picker.