> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uppzy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# M2M Session List

> List all chat sessions for a site with optional filtering by email.

## Overview

This endpoint returns a paginated list of chat sessions for a site. Use it to:

* Retrieve conversation history for a user
* Track session activity over time
* Monitor which sessions have active conversations
* Recover session IDs for follow-up questions

A session groups messages from a single conversation context. You can have multiple sessions per user (e.g., one per channel or topic).

## Authentication

Requires API key in the `X-API-Key` header:

```http theme={null}
X-API-Key: <YOUR_API_KEY>
```

## Query parameters

<ParamField query="email" type="string">
  Filter results to sessions with this user email. Optional.
</ParamField>

<ParamField query="limit" type="integer">
  Maximum number of sessions to return. Default: 50. Maximum: 500.
</ParamField>

<ParamField query="offset" type="integer">
  Number of sessions to skip (for pagination). Default: 0.
</ParamField>

## Request example

<CodeGroup>
  ```bash curl theme={null}
  # List all sessions
  curl --request GET \
    --url "https://api.uppzy.com/api/v1/m2m/sites/<SITE_ID>/sessions" \
    --header "X-API-Key: <YOUR_API_KEY>"

  # List sessions for a specific user
  curl --request GET \
    --url "https://api.uppzy.com/api/v1/m2m/sites/<SITE_ID>/sessions?email=user@example.com" \
    --header "X-API-Key: <YOUR_API_KEY>"

  # Paginate: get second page (limit 50 per page)
  curl --request GET \
    --url "https://api.uppzy.com/api/v1/m2m/sites/<SITE_ID>/sessions?limit=50&offset=50" \
    --header "X-API-Key: <YOUR_API_KEY>"
  ```

  ```javascript JavaScript theme={null}
  // List sessions for a user
  const response = await fetch(
    "https://api.uppzy.com/api/v1/m2m/sites/<SITE_ID>/sessions?" +
      new URLSearchParams({
        email: "user@example.com",
        limit: 50,
      }).toString(),
    {
      headers: {
        "X-API-Key": process.env.UPPZY_API_KEY,
      },
    }
  );

  const data = await response.json();
  console.log(`Found ${data.sessions.length} sessions`);
  ```

  ```python Python theme={null}
  import requests
  import os

  response = requests.get(
      f"https://api.uppzy.com/api/v1/m2m/sites/<SITE_ID>/sessions",
      headers={"X-API-Key": os.environ["UPPZY_API_KEY"]},
      params={
          "email": "user@example.com",
          "limit": 50,
          "offset": 0,
      },
  )

  response.raise_for_status()
  data = response.json()
  print(f"Found {len(data['sessions'])} sessions")
  ```
</CodeGroup>

## Response schema

<ResponseField name="sessions" type="array of objects">
  Array of session objects.
</ResponseField>

<ResponseField name="sessions[].id" type="string">
  The session ID.
</ResponseField>

<ResponseField name="sessions[].email" type="string">
  The user's email address associated with this session.
</ResponseField>

<ResponseField name="sessions[].visitor_id" type="string">
  A unique identifier for the widget visitor (if chat came from the embedded widget).
</ResponseField>

<ResponseField name="sessions[].message_count" type="integer">
  Total number of messages in this session (both user and assistant).
</ResponseField>

<ResponseField name="sessions[].created_at" type="string (ISO 8601 timestamp)">
  When the session was first created.
</ResponseField>

<ResponseField name="sessions[].updated_at" type="string (ISO 8601 timestamp)">
  When the last message was sent in this session.
</ResponseField>

<ResponseField name="sessions[].closed_at" type="string (ISO 8601 timestamp)">
  When the session was closed. `null` if the session is still active.
</ResponseField>

<ResponseField name="pagination" type="object">
  Pagination metadata.
</ResponseField>

<ResponseField name="pagination.limit" type="integer">
  The limit used in the request.
</ResponseField>

<ResponseField name="pagination.offset" type="integer">
  The offset used in the request.
</ResponseField>

<ResponseField name="pagination.total" type="integer">
  Total number of sessions matching the filter (if any).
</ResponseField>

## Response example

<ResponseExample>
  ```json theme={null}
  {
    "sessions": [
      {
        "id": "sess_550e8400e29b41d4a716446655440000",
        "email": "user@example.com",
        "visitor_id": "visitor_abc123",
        "message_count": 8,
        "created_at": "2024-06-13T10:00:00Z",
        "updated_at": "2024-06-13T14:30:00Z",
        "closed_at": null
      },
      {
        "id": "sess_660f9511f3ac52e5b827557766551111",
        "email": "user@example.com",
        "visitor_id": "visitor_def456",
        "message_count": 3,
        "created_at": "2024-06-12T09:15:00Z",
        "updated_at": "2024-06-12T09:20:00Z",
        "closed_at": "2024-06-12T09:21:00Z"
      }
    ],
    "pagination": {
      "limit": 50,
      "offset": 0,
      "total": 2
    }
  }
  ```
</ResponseExample>

## Error responses

### 400 Bad Request

Invalid query parameters.

```json theme={null}
{
  "error": "invalid limit or offset"
}
```

### 401 Unauthorized

API key is missing, invalid, expired, or revoked.

```json theme={null}
{
  "error": "invalid_api_key"
}
```

### 403 Forbidden

The API key's plan does not include M2M API access.

```json theme={null}
{
  "error": "api_access_not_available_on_plan"
}
```

### 404 Not Found

The site does not exist.

```json theme={null}
{
  "error": "site not found"
}
```

### 500 Internal Server Error

An unexpected error occurred.

## Implementation tips

### Pagination

For sites with many sessions, use pagination to avoid large responses:

```javascript theme={null}
async function getAllSessions(siteId, email = null) {
  const allSessions = [];
  let offset = 0;
  const limit = 100;
  let hasMore = true;

  while (hasMore) {
    const params = new URLSearchParams({ limit, offset });
    if (email) params.append("email", email);

    const response = await fetch(
      `https://api.uppzy.com/api/v1/m2m/sites/${siteId}/sessions?${params}`,
      {
        headers: {
          "X-API-Key": process.env.UPPZY_API_KEY,
        },
      }
    );

    const data = await response.json();
    allSessions.push(...data.sessions);

    hasMore = allSessions.length < data.pagination.total;
    offset += limit;
  }

  return allSessions;
}
```

### Finding a session by email

Retrieve all sessions for a user:

```javascript theme={null}
async function getSessionsForUser(siteId, email) {
  const response = await fetch(
    `https://api.uppzy.com/api/v1/m2m/sites/${siteId}/sessions?email=${encodeURIComponent(email)}`,
    {
      headers: {
        "X-API-Key": process.env.UPPZY_API_KEY,
      },
    }
  );

  const data = await response.json();
  return data.sessions;
}

// Usage
const sessions = await getSessionsForUser(siteId, "user@example.com");
console.log(`User has ${sessions.length} conversations`);

// Find the most recent active session
const activeSession = sessions
  .filter((s) => s.closed_at === null)
  .sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at))[0];

if (activeSession) {
  // Use this session for follow-up questions
  console.log(`Latest session ID: ${activeSession.id}`);
}
```

### Analytics: session activity

Analyze session patterns:

```javascript theme={null}
function analyzeSessionActivity(sessions) {
  const stats = {
    totalSessions: sessions.length,
    activeSessions: sessions.filter((s) => s.closed_at === null).length,
    closedSessions: sessions.filter((s) => s.closed_at !== null).length,
    avgMessagesPerSession:
      sessions.reduce((sum, s) => sum + s.message_count, 0) /
      sessions.length,
    mostActiveSession: sessions.reduce((max, s) =>
      s.message_count > max.message_count ? s : max
    ),
  };

  return stats;
}
```

### Session timeout strategy

Manually close stale sessions using the [session close endpoint](/api-reference/endpoint/m2m-chat-session-close):

```javascript theme={null}
async function closeStaleSession(siteId, sessionId) {
  const response = await fetch(
    `https://api.uppzy.com/api/v1/m2m/sites/${siteId}/chat/session/close`,
    {
      method: "POST",
      headers: {
        "X-API-Key": process.env.UPPZY_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        session_id: sessionId,
      }),
    }
  );

  return response.json();
}
```

## Related endpoints

* [M2M Chat (Sync)](/api-reference/endpoint/m2m-chat-sync) — Send a message in a session
* [M2M Chat (Async)](/api-reference/endpoint/m2m-chat-async) — Async message in a session
* [M2M Chat Feedback](/api-reference/endpoint/m2m-chat-feedback) — Rate a response
* [M2M Site Statistics](/api-reference/endpoint/m2m-site-statistics) — Session metrics
