An **event is a product** flagged as an event (with a date, location, and capacity) and a single non-shippable ticket variant. Tickets are sold through the normal cart and checkout, and `ticketsSold`/attendees are derived from paid orders. Setting `capacity` caps ticket sales by syncing the limit to the ticket variant's stock — once that many tickets are sold, the variant is out of stock and no more can be purchased.

All endpoints require the **Events tool** to be enabled for the store — requests return `404` when it is off. Because events are products, they are **excluded from `GET /api/v1/products` by default**; pass `?includeEvents=true` there to include them, or use the endpoints below.

---

## List Events

```
GET /api/v1/events
```

Returns the store's events with their event metadata and tickets-sold counts (derived from paid orders).

### Query Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | `number` | — | Events per page (1-100) |
| `offset` | `number` | 0 | Number of events to skip |

### Response

```json
{
  "data": [
    {
      "id": "0191abc0-1234-7def-8000-000000000001",
      "name": "Summer Fest",
      "slug": "summer-fest",
      "images": ["https://cdn.store.com/fest.jpg"],
      "event": {
        "enabled": true,
        "startsAt": "2026-07-01T18:00:00.000Z",
        "location": "Berlin",
        "capacity": 500
      },
      "ticketsSold": 142,
      "groups": [
        { "id": "0191abc0-aaaa-7def-8000-000000000010", "name": "Music Festivals", "slug": "music-festivals" }
      ]
    }
  ],
  "total": 1
}
```

---

## Get Event

```
GET /api/v1/events/:idOrSlug
```

Returns a single event by product UUID or URL slug. Returns `404` when the product is not an enabled event.

### Response

```json
{
  "event": {
    "id": "0191abc0-1234-7def-8000-000000000001",
    "name": "Summer Fest",
    "slug": "summer-fest",
    "summary": "An open-air music festival",
    "status": "published",
    "images": ["https://cdn.store.com/fest.jpg"],
    "event": {
      "enabled": true,
      "startsAt": "2026-07-01T18:00:00.000Z",
      "location": "Berlin",
      "capacity": 500
    },
    "groups": [
      { "id": "0191abc0-aaaa-7def-8000-000000000010", "name": "Music Festivals", "slug": "music-festivals" }
    ]
  }
}
```

---

## Create Event

```
POST /api/v1/events
```

Creates an event — internally a product with a single non-shippable ticket variant priced at `price`. Image URLs are downloaded and re-uploaded to the store's CDN. The slug is generated from `name` when omitted and must be unique within the store.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | `string` | Yes | Event display name |
| `price` | `string` | Yes | Ticket price as a decimal string (e.g. `"29.99"`) |
| `slug` | `string` | No | URL-friendly identifier (`^[a-z0-9-]+$`); auto-generated from `name` when omitted |
| `startsAt` | `string` | No | Event start time as an ISO 8601 string |
| `location` | `string` | No | Event location |
| `capacity` | `number` | No | Maximum attendees — caps ticket sales via the ticket variant's stock |
| `description` | `string` | No | Plain text event description |
| `status` | `string` | No | `draft` or `published` (default: `published`) |
| `images` | `string[]` | No | Array of image URLs to upload |
| `collectionIds` | `string[]` | No | Event-group collection UUIDs (must reference `kind="event"` collections in this store) |
| `collectionNames` | `string[]` | No | Event-group names — groups are created automatically if they don't exist |

```bash
curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Summer Fest",
    "price": "29.99",
    "startsAt": "2026-07-01T18:00:00Z",
    "location": "Berlin",
    "capacity": 500,
    "images": ["https://example.com/fest.jpg"],
    "collectionNames": ["Music Festivals"]
  }' \
  https://your-store.yns.store/api/v1/events
```

### Response (201)

```json
{
  "message": "Event created successfully",
  "event": {
    "id": "0191abc0-1234-7def-8000-000000000001",
    "slug": "summer-fest",
    "name": "Summer Fest",
    "status": "published",
    "startsAt": "2026-07-01T18:00:00Z",
    "location": "Berlin",
    "capacity": 500,
    "images": ["https://cdn.store.com/fest-abc123.jpg"],
    "collectionIds": ["0191abc0-aaaa-7def-8000-000000000010"]
  }
}
```

Returns `409` when the slug already exists in the store.

---

## Update Event

```
PATCH /api/v1/events/:idOrSlug
```

Partially updates event metadata. Only the fields you send are changed — omit a field to leave it unchanged, or send `null` to clear it. This endpoint does **not** change the ticket price or variants (use the [Products API](/docs/api-reference/products) for those).

### Request Body

| Field | Type | Description |
|-------|------|-------------|
| `name` | `string` | Event display name |
| `startsAt` | `string \| null` | Event start time (ISO 8601), or `null` to clear |
| `location` | `string \| null` | Event location, or `null` to clear |
| `capacity` | `number \| null` | Maximum attendees (caps ticket sales via stock), or `null` to remove the cap |
| `description` | `string \| null` | Plain text description, or `null` to clear |
| `status` | `string` | `draft` or `published` |
| `images` | `string[]` | Replace the event's images. External URLs are uploaded to the CDN; CDN URLs pass through. |
| `collectionIds` | `string[]` | Event-group collection UUIDs — replaces the event's groups when provided |
| `collectionNames` | `string[]` | Event-group names — groups are created automatically if they don't exist |

```bash
curl -X PATCH \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"capacity": 600, "status": "published"}' \
  https://your-store.yns.store/api/v1/events/summer-fest
```

### Response

```json
{
  "message": "Event updated successfully",
  "event": { "id": "0191abc0-1234-7def-8000-000000000001" }
}
```

Returns `404` when the event does not exist.

---

## Event Attendees

```
GET /api/v1/events/:idOrSlug/attendees
```

Returns the attendee rollup for an event: buyers (name and email) with summed ticket quantities, aggregated from paid orders whose line items reference the event. Returns `404` when the product is not an enabled event.

### Response

```json
{
  "attendees": [
    { "name": "Jane Doe", "email": "jane@example.com", "quantity": 2 },
    { "name": "John Smith", "email": "john@example.com", "quantity": 1 }
  ],
  "totalTickets": 3
}
```

---

## Check-in Roster

```
GET /api/v1/events/:idOrSlug/checkins
```

The organizer's door-scanning roster: every seat for the event with its attendee details and check-in state. Includes unpaid and unlisted seats so staff see everyone.

This response carries attendee emails, so it requires a store API key. It is never reachable with an attendee token.

```bash
curl \
  -H "Authorization: Bearer your_api_key" \
  https://your-store.yns.store/api/v1/events/summer-workshop/checkins
```

### Response

```json
{
  "event": {
    "name": "Summer Workshop",
    "slug": "summer-workshop"
  },
  "total": 42,
  "checkedIn": 17,
  "attendees": [
    {
      "token": "atn_9f2c...",
      "name": "Jane Doe",
      "email": "jane@example.com",
      "orderStatus": "paid",
      "checkedInAt": "2024-06-01T18:04:11.000Z",
      "checkedInBy": "Front desk"
    }
  ]
}
```

Seats are ordered by check-in time (most recent first), then by attendee name. Use `token` with the [attendee check-in endpoint](/docs/api-reference/tickets) to mark someone present.

### Errors

| Status | Meaning |
|--------|---------|
| `404` | Events are not enabled for this store, or no event matches the identifier |

---

## Networking Directory

```
GET /api/v1/events/:idOrSlug/directory
```

The public networking directory for an event: attendees who added a LinkedIn URL and opted in to being listed. Built from paid orders only.

No email address is ever returned by this endpoint — it is safe to render on a public event page.

```bash
curl \
  -H "Authorization: Bearer your_api_key" \
  https://your-store.yns.store/api/v1/events/summer-workshop/directory
```

### Response

```json
{
  "attendees": [
    {
      "name": "Jane Doe",
      "bio": "Ceramics studio owner",
      "linkedinUrl": "https://www.linkedin.com/in/janedoe",
      "photoUrl": "https://cdn.example.com/avatars/jane.jpg"
    }
  ]
}
```

Attendees control their own entry through the [attendee profile endpoint](/docs/api-reference/tickets).

### Errors

| Status | Meaning |
|--------|---------|
| `404` | Events are not enabled for this store, or no event matches the identifier |