# Events · Attendee

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

**Browse events**

`operationId: EventsClientController_getEvents`

The public event listing — what an attendee sees. Only events that have been published appear here.

#### Signature

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

#### Access

Public — no credentials required.

#### Errors

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

#### See also

- `GET /client/events/{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. |
| `type` | query | string | — |  |
| `fromDate` | query | string | — |  |
| `toDate` | query | string | — |  |
| `limit` | query | integer | — |  |
| `offset` | query | integer | — | Offset paging. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Published events |
| `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 /client/events/tickets/mine

**Get my tickets**

`operationId: EventsClientController_getMyTickets`

The signed-in attendee's tickets, optionally narrowed to one event.

Declared **before** `GET /client/events/{eventId}` so the bare `:eventId` route does not swallow it — the controller notes this explicitly, and reordering the handlers would break it.

#### Signature

```http
GET /client/events/tickets/mine (eventId?: string) -> The attendee's tickets
```

#### Access

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

#### Notes

- Scoped to the caller — an anonymous request returns nothing useful.

#### Errors

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

#### See also

- `GET /client/events/booking`

### 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` | query | string | — | Restrict to one event. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The attendee's 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 /client/events/booking

**Look up a booking**

`operationId: EventsClientController_getBooking`

Retrieves a booking from the buyer's email plus the booking id — the "find my tickets" flow for someone who bought without an account.

Those two values are the only credential, so anyone holding both can read the booking. Rate-limit any public form built on it.

#### Signature

```http
GET /client/events/booking (email?: string, bookingId?: string) -> The booking and its tickets
```

#### Access

Public — no credentials required.

#### Notes

- Unauthenticated. Email plus booking id is enough to read someone's tickets.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Booking not found | No booking matches. | Check the identifier. |

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

#### See also

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

### 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. |
| `email` | query | string | yes | Buyer email. |
| `bookingId` | query | string | yes | Booking id from the confirmation. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The booking and its tickets |
| `404` | Booking not found — No booking matches. |
| `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 /client/events/{eventId}

**Get an event**

`operationId: EventsClientController_getEvent`

The public detail page for one event.

This route is declared **after** `tickets/mine` and `booking` deliberately: Nest matches in registration order, so a bare `:eventId` placed earlier would swallow those paths.

#### Signature

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

#### Access

Public — no credentials required.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Event not found | No event matches. | Check the identifier. |

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

#### See also

- `GET /client/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. |
| `eventId` | path | string | yes | Event id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The event |
| `404` | Event not found — No event matches. |
| `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 /client/events/tickets/{ticketId}

**Get a ticket**

`operationId: EventsClientController_getTicket`

Fetches one of the caller's tickets. Only the holder gets it: a ticket whose `holderEmail` is not the signed-in customer's answers `404`, the same as a missing one.

#### Signature

```http
GET /client/events/tickets/{ticketId} (ticketId: string) -> The 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 matches. | Check the identifier. |

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

#### See also

- `GET /client/events/tickets/{ticketId}/qr`

### 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 |
| `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 matches. |
| `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 /client/events/tickets/{ticketId}/qr

**Get a ticket QR code**

`operationId: EventsClientController_getTicketQR`

Returns the scannable QR payload for one of the caller's tickets — what the holder shows at the door. **The payload admits whoever presents it**, so it is only returned to the ticket's holder; anyone else gets `404`.

#### Signature

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

#### Access

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

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket not found | No ticket matches. | Check the identifier. |

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

#### See also

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

### 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 matches. |
| `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 /client/events/tickets/{ticketId}/transfer

**Transfer a ticket**

`operationId: EventsClientController_transferTicket`

Transfers one of the caller's tickets to someone else — the attendee-initiated handover when they can no longer attend. Only the current holder may; anyone else gets `404`.

#### Signature

```http
POST /client/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 matches. | Check the identifier. |

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

#### See also

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

### 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 matches. |
| `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 /client/events/tickets/{ticketId}/perks

**Get ticket perks**

`operationId: EventsClientController_getTicketPerks`

The perks included with a ticket and which have been claimed — what the holder is entitled to.

#### Signature

```http
GET /client/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 matches. | Check the identifier. |

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

#### See also

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

### 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 matches. |
| `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 /client/events/{eventId}/ticket-types

**Get ticket types**

`operationId: EventsClientController_getTicketTypes`

The ticket tiers on sale for an event, with prices and availability — what a purchase form is built from.

#### Signature

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

#### Access

Public — no credentials required.

#### Errors

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

#### See also

- `POST /client/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 |
| `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 /client/events/tickets/purchase

**Purchase tickets**

`operationId: EventsClientController_purchaseTickets`

The public purchase path. Availability, sale windows and per-type limits are all validated here, so a ticket type that looked available when the page loaded can still be refused.

Payment can be supplied inline via `paymentRef`, or the purchase can be created first and confirmed afterwards with `confirm-order` once the gateway settles.

#### Signature

```http
POST /client/events/tickets/purchase (body) -> The booking and its tickets
```

#### Access

Public — no credentials required.

#### Notes

- Unauthenticated. The `email` supplied becomes the only key to the booking afterwards.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket type not found | No ticket type matches. | Check the identifier. |
| `400` | NOT_AVAILABLE | <ticket type> is not available / is not on sale yet / sale has ended | The ticket type is inactive or outside its sale window. | The message names the ticket type and the reason — show it to the buyer. |

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

#### See also

- `POST /client/events/tickets/confirm-order`
- `GET /client/events/booking`

### 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. |
| `x-client-host` | header | string | yes |  |

### Request body

What to buy, and for whom.

```json
{
  "eventId": "EVT-4821",
  "email": "ada@example.com",
  "name": "Ada Lovelace",
  "items": [
    {
      "ticketTypeId": "TT-general",
      "quantity": 2
    }
  ],
  "paymentRef": "pi_3PabcXYZ",
  "paymentGateway": "stripe"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The booking and its tickets |
| `400` | <ticket type> is not available / is not on sale yet / sale has ended — The ticket type is inactive or outside its sale window. |
| `404` | Ticket type not found — No ticket type matches. |
| `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 /client/events/tickets/confirm-order

**Confirm a ticket order**

`operationId: EventsClientController_confirmOrder`

Confirms payment against a booking created earlier — the second half of a redirect-based checkout, called when the customer returns from the gateway.

The payment reference is taken on trust from an unauthenticated caller, so verify it with the provider before relying on it.

#### Signature

```http
POST /client/events/tickets/confirm-order (body) -> The confirmed booking
```

#### Access

Public — no credentials required.

#### Notes

- Unauthenticated and unverified — confirm with the gateway rather than trusting the reference.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Booking not found | No booking matches. | Check the identifier. |

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

#### See also

- `POST /client/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

The booking and the payment that settled it.

```json
{
  "bookingId": "BKG-4821",
  "paymentRef": "pi_3PabcXYZ",
  "paymentGateway": "stripe"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The confirmed booking |
| `404` | Booking not found — No booking matches. |
| `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 /client/events/stripe/config

**Get the Stripe configuration**

`operationId: EventsClientController_getStripeConfig`

The public Stripe configuration a browser needs to render payment elements. Contains no secrets.

#### Signature

```http
GET /client/events/stripe/config () -> Stripe client configuration
```

#### Access

Public — no credentials required.

#### Errors

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

#### See also

- `POST /client/events/stripe/intent`

### 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. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Stripe client configuration |
| `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 /client/events/stripe/intent

**Create a Stripe PaymentIntent**

`operationId: EventsClientController_stripePaymentIntent`

Creates a PaymentIntent for a ticket purchase and returns its client secret for the browser SDK to confirm.

#### Signature

```http
POST /client/events/stripe/intent (body) -> The PaymentIntent, including `client_secret`
```

#### Access

Public — no credentials required.

#### Notes

- Unauthenticated — validate the amount server-side against the ticket types rather than trusting the client.

#### Errors

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

#### See also

- `POST /client/events/tickets/confirm-order`

### 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

Intent details.

```json
{
  "eventId": "EVT-4821",
  "amount": 9000,
  "currency": "USD",
  "email": "ada@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The PaymentIntent, including `client_secret` |
| `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 /client/events/stripe/checkout-session

**Create a Stripe Checkout session**

`operationId: EventsClientController_stripeCheckoutSession`

Creates a hosted Stripe Checkout session for a ticket purchase and returns the URL to redirect the buyer to.

#### Signature

```http
POST /client/events/stripe/checkout-session (body) -> The session, including its redirect URL
```

#### Access

Public — no credentials required.

#### Errors

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

#### See also

- `GET /client/events/stripe/config`

### 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

Session details.

```json
{
  "eventId": "EVT-4821",
  "items": [
    {
      "ticketTypeId": "TT-general",
      "quantity": 2
    }
  ],
  "successUrl": "https://events.example.com/thanks",
  "cancelUrl": "https://events.example.com/tickets"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The session, including its redirect URL |
| `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 /client/events/tickets/register

**Register for an event**

`operationId: EventsClientController_registerTickets`

Registration for free events — issues tickets without a payment step. Use `purchase` where money is involved.

#### Signature

```http
POST /client/events/tickets/register (body) -> The registration and its tickets
```

#### Access

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

#### Notes

- Unauthenticated — rate-limit it, or a free event can be filled with fake registrations.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Ticket type not found | No ticket type matches. | Check the identifier. |

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

#### See also

- `POST /client/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 is registering.

```json
{
  "eventId": "EVT-4821",
  "email": "ada@example.com",
  "name": "Ada Lovelace",
  "items": [
    {
      "ticketTypeId": "TT-free",
      "quantity": 1
    }
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The registration and its 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 matches. |
| `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 /client/events/{eventId}/sessions

**Get event sessions**

`operationId: EventsClientController_getEventSessions`

The sessions in an event's public programme.

#### Signature

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

#### Access

Public — no credentials required.

#### Errors

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

#### See also

- `GET /client/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 |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Sessions |
| `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 /client/events/{eventId}/schedule

**Get the event schedule**

`operationId: EventsClientController_getSchedule`

The programme as an agenda, ordered by time and room.

#### Signature

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

#### Access

Public — no credentials required.

#### Errors

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

#### See also

- `GET /client/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 |
| `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 /client/events/{eventId}/participants

**Get event participants**

`operationId: EventsClientController_getEventParticipants`

The publicly listed speakers, sponsors and exhibitors. Only confirmed participants appear.

#### Signature

```http
GET /client/events/{eventId}/participants (eventId: string) -> Participants
```

#### Access

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

#### Errors

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

#### See also

- `GET /client/events/participation/mine`

### 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 | yes |  |
| `role` | query | string | yes |  |
| `featured` | query | boolean | yes |  |

### 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. |

## GET /client/events/participation/mine

**Get my participation invitations**

`operationId: EventsClientController_getMyParticipation`

The events the caller has been invited to take part in as a speaker, sponsor or exhibitor — their side of the programme.

#### Signature

```http
GET /client/events/participation/mine () -> Participation records
```

#### Access

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

#### Errors

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

#### See also

- `PUT /client/events/participation/{participantId}/respond`

### 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` | query | string | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Participation records |
| `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 /client/events/participation/{participantId}/respond

**Respond to a participation invitation**

`operationId: EventsClientController_respondToInvite`

Accepts or declines an invitation to take part. Accepting confirms the participant, which is what makes them appear in the public listing.

#### Signature

```http
PUT /client/events/participation/{participantId}/respond (participantId: string, body) -> The updated participation record
```

#### Access

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

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Participant not found | No participant matches. | Check the identifier. |

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

#### See also

- `GET /client/events/participation/mine`

### 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 | Participation record id. |

### Request body

The response.

```json
{
  "response": "accept"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated participation record |
| `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 matches. |
| `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 /client/events/{eventId}/media

**Get event media**

`operationId: EventsClientController_getEventMedia`

The publicly visible media for an event — the shared gallery attendees can browse.

#### Signature

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

#### Access

Public — no credentials required.

#### Errors

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

#### See also

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

### 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 |
| `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 /client/events/{eventId}/media/guest/{guestId}

**Get a guest's media**

`operationId: EventsClientController_getGuestMedia`

The media one guest contributed to an event gallery.

#### Signature

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

#### Access

Public — no credentials required.

#### Errors

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

#### See also

- `GET /client/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 |
| `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 /client/events/{eventId}/media/upload

**Upload media to an event**

`operationId: EventsClientController_uploadEventMedia`

Uploads a photo or video to an event's shared gallery.

Needs a signed-in caller. Anything accepted here becomes part of the event gallery, so moderate what is uploaded.

#### Signature

```http
POST /client/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 /client/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 /client/events/{eventId}/media/upload/{guestId}

**Upload media as a guest**

`operationId: EventsClientController_uploadGuestMedia`

Uploads media attributed to a named guest, so a shared gallery can show who contributed what.

#### Signature

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

#### Access

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

#### Notes

- The guest id is not verified — attribution is on trust.

#### Errors

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

#### See also

- `GET /client/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. |

