# Events

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## GET /events

**List events**

`operationId: EventsController_getEvents`

Lists events with optional filters and offset paging.

Events are **created and edited through the repository API**, not here — this controller only reads them and drives their lifecycle.

#### Signature

```http
GET /events (status?: string, type?: string, fromDate?: string, toDate?: string, limit?: integer, offset?: integer) -> Events
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Use `POST /repository/create` with an event datatype to create one.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{id}`
- `POST /repository/create`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `status` | query | string | — |  |
| `type` | query | string | — |  |
| `fromDate` | query | string | — | Lower bound on event date. |
| `toDate` | query | string | — | Upper bound on event date. |
| `limit` | query | integer | — | How many to return. |
| `offset` | query | integer | — | Offset paging — this module uses `offset`, not `page`. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Events |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{id}

**Get an event**

`operationId: EventsController_getEvent`

Fetches one event with its configuration and stats.

#### Signature

```http
GET /events/{id} (id: string) -> The event
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Event not found | No event has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/{id}/publish`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The event |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Event not found — No event has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{id}/publish

**Publish an event**

`operationId: EventsController_publishEvent`

Makes an event public and opens ticket sales. The point at which customers can find and buy — check ticket types and pricing before publishing.

#### Signature

```http
POST /events/{id}/publish (id: string) -> The published event
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Event not found | No event has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/{id}/live`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The published event |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Event not found — No event has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{id}/live

**Mark an event live**

`operationId: EventsController_setEventLive`

Marks the event as happening now — the state check-in expects. Doors are open.

#### Signature

```http
POST /events/{id}/live (id: string) -> The event
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Event not found | No event has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/checkin`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The event |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Event not found — No event has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{id}/complete

**Complete an event**

`operationId: EventsController_completeEvent`

Closes an event that has finished. Final attendance figures settle at this point.

#### Signature

```http
POST /events/{id}/complete (id: string) -> The event
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Event not found | No event has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/checkin-stats`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The event |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Event not found — No event has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{id}/cancel

**Cancel an event**

`operationId: EventsController_cancelEvent`

Cancels an event.

Cancelling does **not** automatically refund tickets — issue those separately, per ticket or per booking, so the refund route and amount stay under your control.

#### Signature

```http
POST /events/{id}/cancel (id: string, body) -> The cancelled event
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Ticket holders are not refunded by this. Use the ticket or booking refund endpoints.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Event not found | No event has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/refund`
- `POST /events/bookings/{bookingId}/refund`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Event id. |

### Request body

Optional cancellation details.

```json
{
  "reason": "Venue unavailable"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The cancelled event |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Event not found — No event has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/tickets

**List event tickets**

`operationId: EventsController_getEventTickets`

The tickets issued for an event, filterable by status and type.

#### Signature

```http
GET /events/{eventId}/tickets (eventId: string, status?: string, ticketType?: string, limit?: integer) -> Tickets
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/tickets/lookup/{eventId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `status` | query | string | — |  |
| `ticketType` | query | string | — |  |
| `limit` | query | integer | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Tickets |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{eventId}/tickets

**Issue a ticket**

`operationId: EventsController_issueTicket`

Issues a single ticket for an event directly, bypassing the purchase flow. For manual issuance where payment is handled elsewhere.

#### Signature

```http
POST /events/{eventId}/tickets (eventId: string, body) -> The issued ticket
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket type not found | No ticket type has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/comp`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Request body

The ticket to issue.

```json
{
  "ticketTypeId": "TT-general",
  "holderEmail": "ada@example.com",
  "holderName": "Ada Lovelace"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The issued ticket |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket type not found — No ticket type has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/purchase

**Purchase tickets**

`operationId: EventsController_purchaseTickets`

The customer purchase path. Validates each line before issuing anything — the ticket type must be active, within its sale window, and have enough left.

Each check has its own message naming the ticket type, so a failure tells the customer exactly which line is the problem and why.

#### Signature

```http
POST /events/tickets/purchase (body) -> The purchased tickets
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Availability is checked at purchase time — a type shown as available when the page loaded can sell out before submission.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket type not found | No ticket type has that id. | Check the id against the corresponding list endpoint. |
| `400` | INVALID_QUANTITY | Quantity must be at least 1 | A line has a quantity below 1. | Remove the line rather than sending zero. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/ticket-types`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to buy, and for whom.

```json
{
  "eventId": "EVT-4821",
  "items": [
    {
      "ticketTypeId": "TT-general",
      "quantity": 2
    }
  ],
  "holderEmail": "ada@example.com",
  "holderName": "Ada Lovelace"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The purchased tickets |
| `400` | Quantity must be at least 1 — A line has a quantity below 1. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket type not found — No ticket type has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/comp

**Issue complimentary tickets**

`operationId: EventsController_issueTicketsWithoutPayment`

Issues tickets without payment — guest list, press, staff. Sale windows and pricing do not apply, but availability still does.

#### Signature

```http
POST /events/tickets/comp (body) -> The issued tickets
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Comps still consume availability — they reduce what is left to sell.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket type not found | No ticket type has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/purchase`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Who to issue to.

```json
{
  "eventId": "EVT-4821",
  "ticketTypeId": "TT-general",
  "quantity": 2,
  "holderEmail": "press@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The issued tickets |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket type not found — No ticket type has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/pre-generate

**Pre-generate tickets**

`operationId: EventsController_preGenerateTickets`

Creates a batch of unassigned tickets in advance — printed passes or wristbands produced before anyone has bought one.

Each carries a scannable code but no holder. `activate` assigns one to a person at the point of sale.

#### Signature

```http
POST /events/tickets/pre-generate (body) -> The generated tickets
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Generated tickets are inactive until assigned — an unactivated code will not pass check-in.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/activate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

How many to generate.

```json
{
  "eventId": "EVT-4821",
  "ticketTypeId": "TT-general",
  "quantity": 500
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The generated tickets |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/{ticketId}/activate

**Activate a pre-generated ticket**

`operationId: EventsController_activateTicket`

Assigns a pre-generated ticket to a holder and makes it valid — the counter action when someone buys a physical pass on the door.

#### Signature

```http
POST /events/tickets/{ticketId}/activate (ticketId: string, body) -> The activated ticket
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/pre-generate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |

### Request body

Who it belongs to, and how they paid.

```json
{
  "holderEmail": "ada@example.com",
  "holderName": "Ada Lovelace",
  "payment": {
    "amount": 45,
    "method": "card",
    "ref": "ch_3PabcXYZ"
  }
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The activated ticket |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/tickets/{ticketId}/qr

**Get a ticket QR code**

`operationId: EventsController_getTicketWithQR`

Returns the ticket with its scannable QR payload — what a holder shows at the door. The payload is the credential, so treat it as a secret.

#### Signature

```http
GET /events/tickets/{ticketId}/qr (ticketId: string) -> The ticket and its QR payload
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Anyone with the QR payload can be admitted — do not share ticket images publicly.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/validate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The ticket and its QR payload |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/validate

**Validate a ticket**

`operationId: EventsController_validateTicket`

Checks whether a scanned QR payload is a valid ticket, **without** admitting anyone. Use `checkin` to actually record entry.

#### Signature

```http
POST /events/tickets/validate (body) -> Validation result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Read-only. It does not consume the ticket or record attendance.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/checkin`
- `POST /events/verify-scan`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The scanned payload.

```json
{
  "qrPayload": "EVT4821-9K2M4H"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Validation result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/{ticketId}/transfer

**Transfer a ticket**

`operationId: EventsController_transferTicket`

Moves a ticket to a different holder. The code stays valid; the name on it changes.

#### Signature

```http
POST /events/tickets/{ticketId}/transfer (ticketId: string, body) -> The transferred ticket
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/cancel`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |

### Request body

The new holder.

```json
{
  "holderEmail": "grace@example.com",
  "holderName": "Grace Hopper"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The transferred ticket |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/{ticketId}/cancel

**Cancel a ticket**

`operationId: EventsController_cancelTicket`

Cancels a ticket so it will not admit anyone, keeping the record. Set `silent` to skip notifying the holder.

Cancelling does not refund — issue that separately.

#### Signature

```http
POST /events/tickets/{ticketId}/cancel (ticketId: string, body) -> The cancelled ticket
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- No refund is issued. Use `refund` for that.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/refund`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |

### Request body

Optional cancellation details.

```json
{
  "reason": "Duplicate purchase"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The cancelled ticket |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /events/tickets/{ticketId}

**Delete a ticket**

`operationId: EventsController_deleteTicket`

Deletes a ticket outright. Cancelling preserves the record of what was sold — prefer that unless the ticket was issued in error.

#### Signature

```http
DELETE /events/tickets/{ticketId} (ticketId: string, body) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Unusually, this `DELETE` accepts a body.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/cancel`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |

### Request body

Optional details.

```json
{
  "reason": "Issued in error"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/{ticketId}/refund

**Refund a ticket**

`operationId: EventsController_refundTicket`

Refunds a ticket through the payment route it was bought with, and invalidates it.

#### Signature

```http
POST /events/tickets/{ticketId}/refund (ticketId: string, body) -> The refund result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/bookings/{bookingId}/refund`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |

### Request body

Refund details.

```json
{
  "amount": 45,
  "reason": "Event cancelled"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The refund result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/bookings/{bookingId}/cancel

**Cancel a booking**

`operationId: EventsController_cancelBooking`

Cancels a whole booking — every ticket bought together — rather than one at a time.

#### Signature

```http
POST /events/bookings/{bookingId}/cancel (bookingId: string, body) -> The cancelled booking
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Booking not found | No booking has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/bookings/{bookingId}/refund`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking id. |

### Request body

Optional cancellation details.

```json
{
  "reason": "Customer request"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The cancelled booking |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/bookings/{bookingId}/refund

**Refund a booking**

`operationId: EventsController_refundPurchase`

Refunds an entire booking in one operation, rather than refunding each ticket separately.

#### Signature

```http
POST /events/bookings/{bookingId}/refund (bookingId: string, body) -> The refund result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Booking not found | No booking has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/refund`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking id. |

### Request body

Refund details.

```json
{
  "reason": "Event cancelled"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The refund result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/fulfill

**Fulfil tickets**

`operationId: EventsController_fulfillTicket`

Marks tickets as fulfilled — delivered to the holder, physically or by email.

#### Signature

```http
POST /events/tickets/fulfill (body) -> The fulfilment result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/tickets`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Which tickets to fulfil.

```json
{
  "ticketIds": [
    "TKT-9912",
    "TKT-9913"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The fulfilment result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/tickets/lookup/{eventId}

**Look up a ticket**

`operationId: EventsController_lookupForFulfillment`

Finds a ticket for an event by holder details — the door-staff lookup when someone arrives without their code.

#### Signature

```http
GET /events/tickets/lookup/{eventId} (eventId: string, email?: string, name?: string) -> Matching tickets
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/checkin`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `bookingId` | query | string | yes |  |
| `email` | query | string | — | Holder email. |
| `confirmationCode` | query | string | yes |  |
| `name` | query | string | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Matching tickets |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/tickets/{ticketId}/perks

**Get ticket perks**

`operationId: EventsController_getTicketPerks`

The perks attached to a ticket — meals, merchandise, lounge access — and which have been claimed.

#### Signature

```http
GET /events/tickets/{ticketId}/perks (ticketId: string) -> The ticket's perks
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/perks/{perkId}/claim`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The ticket's perks |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/{ticketId}/perks/{perkId}/claim

**Claim a perk**

`operationId: EventsController_claimPerk`

Records that a holder claimed a perk, so it cannot be claimed twice. The scan at the merchandise desk.

#### Signature

```http
POST /events/tickets/{ticketId}/perks/{perkId}/claim (ticketId: string, perkId: string) -> The claim result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Perk not found | No perk has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/perks/{perkId}/fulfill`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |
| `perkId` | path | string | yes | Perk id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The claim result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Perk not found — No perk has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/{ticketId}/perks/{perkId}/fulfill

**Fulfil a perk**

`operationId: EventsController_fulfillPerk`

Marks a claimed perk as actually handed over — the second half of claim, for perks collected later than they are claimed.

#### Signature

```http
POST /events/tickets/{ticketId}/perks/{perkId}/fulfill (ticketId: string, perkId: string) -> The fulfilment result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Perk not found | No perk has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/perks/{perkId}/claim`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |
| `perkId` | path | string | yes | Perk id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The fulfilment result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Perk not found — No perk has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/tickets/{ticketId}/badge

**Get a ticket badge**

`operationId: EventsController_generateBadge`

The printable badge for a ticket holder — name, role and access level.

#### Signature

```http
GET /events/tickets/{ticketId}/badge (ticketId: string) -> The badge
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/{ticketId}/badge/printed`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |
| `perkId` | query | string | yes |  |
| `claimIndex` | query | string | yes |  |
| `templateId` | query | string | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The badge |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/tickets/{ticketId}/badge/printed

**Mark a badge as printed**

`operationId: EventsController_markBadgePrinted`

Records that a badge has been printed, so registration desks do not print duplicates and reprints are visible.

#### Signature

```http
POST /events/tickets/{ticketId}/badge/printed (ticketId: string) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/tickets/{ticketId}/badge`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ticketId` | path | string | yes | Ticket id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/ticket-types

**Get ticket types**

`operationId: EventsController_getTicketTypes`

The ticket types for an event — tiers, prices, sale windows and availability. What a purchase flow reads to build its options.

#### Signature

```http
GET /events/{eventId}/ticket-types (eventId: string) -> Ticket types
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/tickets/purchase`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Ticket types |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/sessions

**List sessions**

`operationId: EventsController_getEventSessions`

The sessions in an event's programme.

#### Signature

```http
GET /events/{eventId}/sessions (eventId: string) -> Sessions
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/schedule`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `day` | query | string | yes |  |
| `track` | query | string | yes |  |
| `type` | query | string | yes |  |
| `status` | query | string | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Sessions |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{eventId}/sessions

**Create a session**

`operationId: EventsController_createSession`

Adds a session to an event — a talk, workshop or track slot within the programme.

#### Signature

```http
POST /events/{eventId}/sessions (eventId: string, body) -> The created session
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/schedule`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Request body

The session to create.

```json
{
  "title": "Opening keynote",
  "startDate": "2026-09-15T09:00:00.000Z",
  "endDate": "2026-09-15T10:00:00.000Z",
  "room": "Main hall"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The created session |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/schedule

**Get the event schedule**

`operationId: EventsController_getSchedule`

The programme arranged as a schedule — sessions ordered by time and room, ready to render as an agenda.

#### Signature

```http
GET /events/{eventId}/schedule (eventId: string) -> The schedule
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/sessions`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The schedule |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /events/sessions/{sessionId}

**Update a session**

`operationId: EventsController_updateSession`

Updates a session. Attendees who already planned around it are not notified — announce a moved session yourself.

#### Signature

```http
PUT /events/sessions/{sessionId} (sessionId: string, body) -> The updated session
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Session not found | No session has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `DELETE /events/sessions/{sessionId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `sessionId` | path | string | yes | Session id. |

### Request body

Fields to change.

```json
{
  "room": "Auditorium B"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated session |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Session not found — No session has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /events/sessions/{sessionId}

**Delete a session**

`operationId: EventsController_deleteSession`

Removes a session from the programme.

#### Signature

```http
DELETE /events/sessions/{sessionId} (sessionId: string) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Session not found | No session has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `PUT /events/sessions/{sessionId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `sessionId` | path | string | yes | Session id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Session not found — No session has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/checkin

**Check someone in**

`operationId: EventsController_checkIn`

Admits a ticket holder by scanning their code, recording who validated it and where.

`zone` and `checkpoint` record the physical location, and `sessionId` scopes the check-in to one session for events that track per-session attendance.

The validator is taken from the authenticated caller, falling back to `system` — so a shared scanner account produces an audit trail that cannot identify the person who scanned.

**A refused scan is still a `201`** with `success: false` and a `reason` to show at the door — ticket not found or invalid, a different event, already used with re-entry off, re-entry limit reached, ticket type not accepted at the event's scan point for this `checkpoint`, a perk at that checkpoint not available on the ticket, or no access to this zone. Every refusal is logged as a denied check-in. Imported tickets are recognised by their code even without a signing secret.

#### Signature

```http
POST /events/checkin (body) -> The check-in result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Branch on `success`, not on the HTTP status.
- Sign scanners in as identifiable users — the validator recorded is whoever the token belongs to.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/verify-scan`
- `POST /events/checkout`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The scan.

```json
{
  "code": "EVT4821-9K2M4H",
  "zone": "main-hall",
  "checkpoint": "north-entrance"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The check-in result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/verify-scan

**Verify a scan without admitting**

`operationId: EventsController_verifyScan`

Checks a scanned code and reports whether it would be admitted, **without recording a check-in**.

Use it for a door display that shows the holder's name and access level before staff wave them through.

#### Signature

```http
POST /events/verify-scan (body) -> Verification result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Records nothing. Attendance is only counted by `checkin`.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/checkin`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The scan to verify.

```json
{
  "code": "EVT4821-9K2M4H",
  "zone": "vip-lounge"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Verification result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/checkout

**Check someone out**

`operationId: EventsController_checkOut`

Records a holder leaving a zone — what keeps live occupancy accurate for venues with capacity limits.

#### Signature

```http
POST /events/checkout (body) -> The check-out result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Occupancy figures drift high if people leave without being checked out.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/occupancy`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Who is leaving, and from where.

```json
{
  "ticketId": "TKT-9912",
  "zone": "main-hall"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The check-out result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Ticket not found — No ticket has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/occupancy

**Get live occupancy**

`operationId: EventsController_getZoneOccupancy`

How many people are currently inside, by zone — the number a capacity limit is enforced against. Accurate only insofar as check-outs are recorded.

#### Signature

```http
GET /events/{eventId}/occupancy (eventId: string) -> Live occupancy
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/checkout`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Live occupancy |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/checkin-stats

**Get check-in statistics**

`operationId: EventsController_getCheckInStats`

Attendance figures for an event — how many of those who bought actually turned up, and when they arrived.

#### Signature

```http
GET /events/{eventId}/checkin-stats (eventId: string) -> Check-in statistics
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/occupancy`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `day` | query | string | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Check-in statistics |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/participants

**List participants**

`operationId: EventsController_getEventParticipants`

The event's participants, filterable by type, role, status and whether they are featured.

#### Signature

```http
GET /events/{eventId}/participants (eventId: string, type?: string, role?: string, status?: string, featured?: boolean, limit?: integer, offset?: integer) -> Participants
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `PUT /events/participants/{participantId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `type` | query | string | — |  |
| `role` | query | string | — |  |
| `status` | query | string | — |  |
| `featured` | query | boolean | — | Only featured participants. |
| `limit` | query | integer | — | How many to return. |
| `offset` | query | integer | — | Offset paging — this module uses `offset`, not `page`. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Participants |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{eventId}/participants

**Add a participant**

`operationId: EventsController_createParticipant`

Adds a participant — a speaker, sponsor, exhibitor or performer. Distinct from a ticket holder: participants are part of the programme rather than the audience.

#### Signature

```http
POST /events/{eventId}/participants (eventId: string, body) -> The created participant
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | EVENT_ID_REQUIRED | Event ID is required | The event id is missing. | Supply it in the path. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/participants`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Request body

The participant to add.

```json
{
  "customer": "cus_4821",
  "type": "speaker",
  "role": "keynote",
  "featured": true
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The created participant |
| `400` | Event ID is required — The event id is missing. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /events/participants/{participantId}

**Update a participant**

`operationId: EventsController_updateParticipant`

Updates a participant's details or role.

#### Signature

```http
PUT /events/participants/{participantId} (participantId: string, body) -> The updated participant
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Participant not found | No participant has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/participants/{participantId}/confirm`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `participantId` | path | string | yes | Participant id. |

### Request body

Fields to change.

```json
{
  "role": "panellist",
  "featured": false
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated participant |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Participant not found — No participant has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /events/participants/{participantId}

**Delete a participant**

`operationId: EventsController_deleteParticipant`

Removes a participant entirely. Cancel instead to keep the record of who was booked.

#### Signature

```http
DELETE /events/participants/{participantId} (participantId: string) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Participant not found | No participant has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/participants/{participantId}/cancel`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `participantId` | path | string | yes | Participant id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Participant not found — No participant has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/participants/{participantId}/confirm

**Confirm a participant**

`operationId: EventsController_confirmParticipant`

Confirms a participant's attendance — they have accepted and can be listed publicly.

#### Signature

```http
POST /events/participants/{participantId}/confirm (participantId: string) -> The confirmed participant
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Participant not found | No participant has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/participants/{participantId}/cancel`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `participantId` | path | string | yes | Participant id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The confirmed participant |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Participant not found — No participant has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/participants/{participantId}/cancel

**Cancel a participant**

`operationId: EventsController_cancelParticipant`

Records that a participant has withdrawn. The record is kept, so the programme history shows who was booked.

#### Signature

```http
POST /events/participants/{participantId}/cancel (participantId: string) -> The cancelled participant
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Participant not found | No participant has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `DELETE /events/participants/{participantId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `participantId` | path | string | yes | Participant id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The cancelled participant |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Participant not found — No participant has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{eventId}/credentials/import

**Import credentials**

`operationId: EventsController_importCredentials`

Imports a list of credential codes — pre-printed wristbands or access cards produced by a third party — so they can be assigned to holders.

#### Signature

```http
POST /events/{eventId}/credentials/import (eventId: string, body) -> The import result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/{eventId}/credentials/import-range`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Request body

The codes to import.

```json
{
  "codes": [
    "WB-0001",
    "WB-0002"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The import result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{eventId}/credentials/import-range

**Import a credential range**

`operationId: EventsController_importCredentialRange`

Imports a contiguous range of credential codes by prefix and bounds, rather than listing each one — for a sequential batch of wristbands.

#### Signature

```http
POST /events/{eventId}/credentials/import-range (eventId: string, body) -> The import result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Check the range before importing — a wrong bound creates thousands of unusable credentials.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/{eventId}/credentials/import`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Request body

The range to import.

```json
{
  "prefix": "WB-",
  "from": 1,
  "to": 500,
  "padding": 4
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The import result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/credentials/assign

**Assign a credential**

`operationId: EventsController_assignCredential`

Links an imported credential code to a ticket or participant, so scanning the wristband identifies the holder.

#### Signature

```http
POST /events/credentials/assign (body) -> The assignment result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/credentials/{code}/revoke`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to assign to whom.

```json
{
  "code": "WB-0001",
  "ticketId": "TKT-9912"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The assignment result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/credentials/{code}/revoke

**Revoke a credential**

`operationId: EventsController_revokeCredential`

Invalidates a credential — lost, stolen, or handed to the wrong person. It stops working at every checkpoint immediately.

#### Signature

```http
POST /events/credentials/{code}/revoke (code: string) -> The revocation result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Credential not found | No credential has that id. | Check the id against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/credentials/assign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `code` | path | string | yes | Credential code. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The revocation result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Credential not found — No credential has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/credentials

**List credentials**

`operationId: EventsController_getCredentials`

The credentials imported for an event, and who each is assigned to.

#### Signature

```http
GET /events/{eventId}/credentials (eventId: string) -> Credentials
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/credentials/assign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `status` | query | string | yes |  |
| `batchId` | query | string | yes |  |
| `limit` | query | number | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Credentials |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{eventId}/media/upload

**Upload event media**

`operationId: EventsController_uploadEventMedia`

Uploads photos or video to an event's shared gallery.

#### Signature

```http
POST /events/{eventId}/media/upload (eventId: string, body) -> The uploaded media
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /events/{eventId}/media/upload/{guestId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Request body

Multipart form with the media.

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The uploaded media |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{eventId}/media/upload/{guestId}

**Upload media as a guest**

`operationId: EventsController_uploadGuestMedia`

Uploads media attributed to a specific guest — how a shared event gallery collects photos from attendees and keeps track of who contributed what.

#### Signature

```http
POST /events/{eventId}/media/upload/{guestId} (eventId: string, guestId: string, body) -> The uploaded media
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/media/guest/{guestId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `guestId` | path | string | yes | Guest identifier. |

### Request body

Multipart form with the media.

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The uploaded media |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/media

**Get event media**

`operationId: EventsController_getEventMedia`

All media uploaded for an event.

#### Signature

```http
GET /events/{eventId}/media (eventId: string) -> Event media
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/media/guests`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `page` | query | number | yes |  |
| `signed` | query | string | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Event media |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/media/guest/{guestId}

**Get a guest's media**

`operationId: EventsController_getGuestMedia`

The media one guest contributed.

#### Signature

```http
GET /events/{eventId}/media/guest/{guestId} (eventId: string, guestId: string) -> The guest's media
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/media`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |
| `guestId` | path | string | yes | Guest identifier. |
| `page` | query | number | yes |  |
| `signed` | query | string | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The guest's media |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /events/{eventId}/media/guests

**List media contributors**

`operationId: EventsController_getEventGuests`

The guests who have uploaded media to an event.

#### Signature

```http
GET /events/{eventId}/media/guests (eventId: string) -> Contributors
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/media/guest/{guestId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Contributors |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /events/{eventId}/media/share

**Share event media**

`operationId: EventsController_shareMedia`

Shares event media — generating a link or distributing it to attendees.

Photos of attendees are personal data, and guests uploading to a shared gallery may not expect wider distribution. Check what consent was given before sharing beyond the event.

#### Signature

```http
POST /events/{eventId}/media/share (eventId: string, body) -> The share result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Attendee photos are personal data — confirm consent before distributing them.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /events/{eventId}/media`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `eventId` | path | string | yes | Event id. |

### Request body

What to share, and with whom.

```json
{
  "mediaIds": [
    "MED-4821"
  ],
  "recipients": [
    "ada@example.com"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The share result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

