# Showings API

Schedule, manage, and track property showings programmatically. Useful for PMS integrations and scheduling bots.

## List Showings

```
GET /api/v1/showings
```

Returns a paginated list of showings, ordered by start time.

**Query Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `page` | number | Page number (default: 1) |
| `limit` | number | Items per page (default: 20) |
| `propertyId` | uuid | Filter by property |
| `contactId` | uuid | Filter by contact |
| `status` | string | `pending`, `confirmed`, `completed`, or `cancelled` |
| `startAfter` | datetime | Only showings starting after this time (ISO 8601) |
| `startBefore` | datetime | Only showings starting before this time (ISO 8601) |

**Response:**

```json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "type": "showing",
      "propertyId": "660e8400-e29b-41d4-a716-446655440000",
      "contactId": "770e8400-e29b-41d4-a716-446655440000",
      "title": "Showing: 123 Main St",
      "description": "First showing for Jane Smith",
      "startTime": "2026-02-15T14:00:00Z",
      "endTime": "2026-02-15T14:30:00Z",
      "timeZone": "America/New_York",
      "location": "123 Main St, Apt 4B",
      "status": "confirmed",
      "notes": null,
      "source": "internal",
      "reminderSentAt": null,
      "createdAt": "2026-02-10T10:00:00Z",
      "updatedAt": "2026-02-10T10:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 12,
    "totalPages": 1
  }
}
```

## Schedule a Showing

```
POST /api/v1/showings
```

**Request Body:**

```json
{
  "propertyId": "660e8400-e29b-41d4-a716-446655440000",
  "contactId": "770e8400-e29b-41d4-a716-446655440000",
  "title": "Showing: 123 Main St",
  "startTime": "2026-02-15T14:00:00Z",
  "endTime": "2026-02-15T14:30:00Z",
  "timeZone": "America/New_York",
  "location": "123 Main St, Apt 4B",
  "notes": "Prospect requested ground-floor unit"
}
```

**Required:** `propertyId`, `contactId`, `title`, `startTime`, `endTime`

Returns `201 Created` with `{ "data": <showing> }` and a `Location: /api/v1/showings/:id` header. Supports `Idempotency-Key`.

## Get Showing

```
GET /api/v1/showings/:id
```

## Update Showing

```
PATCH /api/v1/showings/:id
```

Reschedule, update status, or add notes. Send only the fields you want to change.

```json
{
  "startTime": "2026-02-16T10:00:00Z",
  "endTime": "2026-02-16T10:30:00Z",
  "status": "confirmed"
}
```

## Cancel Showing

```
DELETE /api/v1/showings/:id
```

Sets the showing status to `cancelled`. Returns `204 No Content`.

## Check Availability

```
GET /api/v1/showings/availability
```

Returns available 1-hour time slots (9am–5pm) minus existing calendar bookings. Useful for building scheduling UIs or letting AI agents find open slots.

**Query Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `propertyId` | uuid | Filter by property (optional) |
| `preferredDate` | date | Single date to check (YYYY-MM-DD) |
| `dateFrom` | date | Start of range (YYYY-MM-DD) |
| `dateTo` | date | End of range (YYYY-MM-DD, defaults to dateFrom + 7 days) |

If no date params are provided, returns slots for the next 7 days.

**Response:**

```json
{
  "data": {
    "dateRange": {
      "from": "2026-03-15T00:00:00.000Z",
      "to": "2026-03-22T00:00:00.000Z"
    },
    "availableSlots": [
      {
        "date": "2026-03-15",
        "start": "2026-03-15T14:00:00.000Z",
        "end": "2026-03-15T15:00:00.000Z"
      }
    ],
    "existingEventCount": 3
  }
}
```
