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

# List Customers

> Get a list of all registered customers

## Description

This endpoint returns a paginated list of all customers registered in the system. You can filter, search and sort the results according to your needs.

## Authentication

<ParamField header="X-API-Key" type="string" required>
  Your LatePoint API Key with read permissions
</ParamField>

## Query Parameters

### Pagination

<ParamField query="page" type="integer" default="1">
  Page number to retrieve
</ParamField>

<ParamField query="per_page" type="integer" default="20">
  Number of customers per page (maximum 100)
</ParamField>

### Filters

<ParamField query="status" type="string">
  Filter by customer status

  **Possible values:**

  * `active` - Active customers
  * `inactive` - Inactive customers
  * `blocked` - Blocked customers
</ParamField>

<ParamField query="created_after" type="string">
  Show only customers created after this date (format: YYYY-MM-DD)
</ParamField>

<ParamField query="created_before" type="string">
  Show only customers created before this date (format: YYYY-MM-DD)
</ParamField>

<ParamField query="has_bookings" type="boolean">
  Filter customers who have or don't have bookings

  * `true` - Only customers with bookings
  * `false` - Only customers without bookings
</ParamField>

### Dynamic Field Filters

<ParamField query="first_name" type="string">
  Filter by customer's first name (partial match)
</ParamField>

<ParamField query="last_name" type="string">
  Filter by customer's last name (partial match)
</ParamField>

<ParamField query="email" type="string">
  Filter by customer's email address (partial match)
</ParamField>

<ParamField query="phone" type="string">
  Filter by customer's phone number (partial match)
</ParamField>

<ParamField query="is_guest" type="boolean">
  Filter by guest status

  * `true` - Only guest customers
  * `false` - Only registered customers
</ParamField>

<ParamField query="wordpress_user_id" type="integer">
  Filter by WordPress user ID (exact match)
</ParamField>

<ParamField query="created_at" type="string">
  Filter by creation date (partial match, format: YYYY-MM-DD)
</ParamField>

<ParamField query="updated_at" type="string">
  Filter by last update date (partial match, format: YYYY-MM-DD)
</ParamField>

### Search

<ParamField query="search" type="string">
  Search customers by first name, last name, or email (partial match)
</ParamField>

## Response

### Successful Response (200 OK)

<ResponseField name="success" type="boolean">
  Always `true` on success
</ResponseField>

<ResponseField name="data" type="array">
  Array of customer objects

  <Expandable title="Customer Structure">
    <ResponseField name="id" type="integer">
      Unique customer ID
    </ResponseField>

    <ResponseField name="first_name" type="string">
      Customer's first name
    </ResponseField>

    <ResponseField name="last_name" type="string">
      Customer's last name
    </ResponseField>

    <ResponseField name="email" type="string">
      Customer's email
    </ResponseField>

    <ResponseField name="phone" type="string">
      Customer's phone number
    </ResponseField>

    <ResponseField name="status" type="string">
      Customer status (e.g. `active`, `pending_verification`, `blocked`)
    </ResponseField>

    <ResponseField name="is_guest" type="string">
      Whether the customer is a guest (`"1"`) or registered (`"0"`)
    </ResponseField>

    <ResponseField name="admin_notes" type="string">
      Internal notes (admin only)
    </ResponseField>

    <ResponseField name="created_at" type="string">
      Customer registration date
    </ResponseField>

    <ResponseField name="updated_at" type="string">
      Last update date
    </ResponseField>

    <ResponseField name="stats" type="object">
      Customer booking statistics (always included)

      <Expandable title="Statistics">
        <ResponseField name="total_bookings" type="string">
          Total number of bookings
        </ResponseField>

        <ResponseField name="completed_bookings" type="integer">
          Number of approved/completed bookings
        </ResponseField>

        <ResponseField name="cancelled_bookings" type="integer">
          Number of cancelled bookings
        </ResponseField>

        <ResponseField name="future_bookings" type="string">
          Number of upcoming bookings
        </ResponseField>

        <ResponseField name="total_spent" type="string">
          Total amount spent by customer
        </ResponseField>

        <ResponseField name="last_booking_date" type="string">
          Date of last booking (YYYY-MM-DD or null)
        </ResponseField>

        <ResponseField name="next_booking_date" type="string">
          Date of next booking (YYYY-MM-DD or null)
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="custom_fields" type="object">
      Customer custom field values (always included, empty array if none)
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pagination" type="object">
  Pagination information

  <Expandable title="Pagination">
    <ResponseField name="page" type="integer">
      Current page
    </ResponseField>

    <ResponseField name="per_page" type="integer">
      Items per page
    </ResponseField>

    <ResponseField name="total" type="integer">
      Total customers matching the query
    </ResponseField>

    <ResponseField name="total_pages" type="integer">
      Total pages
    </ResponseField>

    <ResponseField name="has_next_page" type="boolean">
      Whether a next page exists
    </ResponseField>

    <ResponseField name="has_previous_page" type="boolean">
      Whether a previous page exists
    </ResponseField>
  </Expandable>
</ResponseField>

## Examples

### List All Customers

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://your-site.com/wp-json/latepoint-api/v1/customers" \
    -H "X-API-Key: lp_live_1234567890abcdef"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://your-site.com/wp-json/latepoint-api/v1/customers', {
    headers: {
      'X-API-Key': 'lp_live_1234567890abcdef'
    }
  });

  const customers = await response.json();
  console.log(customers);
  ```

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

  response = requests.get(
      'https://your-site.com/wp-json/latepoint-api/v1/customers',
      headers={
          'X-API-Key': 'lp_live_1234567890abcdef'
      }
  )

  customers = response.json()
  print(customers)
  ```

  ```php PHP theme={null}
  <?php
  $curl = curl_init();

  curl_setopt_array($curl, [
      CURLOPT_URL => 'https://your-site.com/wp-json/latepoint-api/v1/customers',
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
          'X-API-Key: lp_live_1234567890abcdef'
      ]
  ]);

  $response = curl_exec($curl);
  $customers = json_decode($response, true);

  curl_close($curl);
  print_r($customers);
  ?>
  ```
</CodeGroup>

### Search Customers with Dynamic Filters

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://your-site.com/wp-json/latepoint-api/v1/customers?first_name=Carlos&last_name=Lopez&status=active" \
    -H "X-API-Key: lp_live_1234567890abcdef"
  ```

  ```javascript JavaScript theme={null}
  const params = new URLSearchParams({
    first_name: 'Carlos',
    email: 'lopez',
    status: 'active'
  });

  const response = await fetch(`https://your-site.com/wp-json/latepoint-api/v1/customers?${params}`, {
    headers: {
      'X-API-Key': 'lp_live_1234567890abcdef'
    }
  });

  const customers = await response.json();
  console.log(customers);
  ```

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

  params = {
      'first_name': 'Ana',
      'email': 'gmail.com',
      'status': 'active',
      'is_guest': 'false'
  }

  response = requests.get(
      'https://your-site.com/wp-json/latepoint-api/v1/customers',
      headers={'X-API-Key': 'lp_live_1234567890abcdef'},
      params=params
  )

  customers = response.json()
  print(customers)
  ```
</CodeGroup>

### Filter by Phone and Guest Status

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://your-site.com/wp-json/latepoint-api/v1/customers?phone=555&is_guest=true&include=stats" \
    -H "X-API-Key: lp_live_1234567890abcdef"
  ```

  ```javascript JavaScript theme={null}
  // Get guest customers with specific phone pattern
  const params = new URLSearchParams({
    phone: '555',
    is_guest: 'true',
    status: 'active',
    per_page: 50
  });

  const response = await fetch(`https://your-site.com/wp-json/latepoint-api/v1/customers?${params}`, {
    headers: {
      'X-API-Key': 'lp_live_1234567890abcdef'
    }
  });

  const guestCustomers = await response.json();
  console.log(`Guest customers with 555 in phone: ${guestCustomers.data.length}`);
  ```
</CodeGroup>

### Filter by Creation Date

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://your-site.com/wp-json/latepoint-api/v1/customers?created_at=2024-01&has_bookings=true" \
    -H "X-API-Key: lp_live_1234567890abcdef"
  ```

  ```javascript JavaScript theme={null}
  // Get customers created in January 2024 who have bookings
  const params = new URLSearchParams({
    created_at: '2024-01',
    has_bookings: 'true'
  });

  const response = await fetch(`https://your-site.com/wp-json/latepoint-api/v1/customers?${params}`, {
    headers: {
      'X-API-Key': 'lp_live_1234567890abcdef'
    }
  });

  const januaryCustomers = await response.json();
  console.log(`Customers from January 2024: ${januaryCustomers.data.length}`);
  ```
</CodeGroup>

### Paginate Through All Customers

```javascript JavaScript theme={null}
async function getAllCustomers() {
  let allCustomers = [];
  let currentPage = 1;
  let hasNextPage = true;

  while (hasNextPage) {
    const params = new URLSearchParams({ page: currentPage, per_page: 100 });
    const response = await fetch(`https://your-site.com/wp-json/latepoint-api/v1/customers?${params}`, {
      headers: { 'X-API-Key': 'YOUR_API_KEY' }
    });
    const result = await response.json();

    if (result.success) {
      allCustomers = allCustomers.concat(result.data);
      hasNextPage = result.pagination.has_next_page;
      currentPage++;
      console.log(`Page ${currentPage - 1}/${result.pagination.total_pages}`);
    } else {
      break;
    }
  }
  return allCustomers;
}
```

## Example Response

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": "30",
      "first_name": "Carlos",
      "last_name": "Rodriguez",
      "email": "carlos@example.com",
      "phone": "+59887222333",
      "status": "pending_verification",
      "is_guest": "1",
      "notes": "",
      "admin_notes": "",
      "wordpress_user_id": null,
      "created_at": "2025-09-24 06:10:34",
      "updated_at": "2026-01-27 22:23:23",
      "stats": {
        "total_bookings": "3",
        "completed_bookings": 3,
        "cancelled_bookings": 0,
        "future_bookings": "0",
        "total_spent": "46.00",
        "last_booking_date": "2026-03-02",
        "next_booking_date": null
      },
      "custom_fields": {
        "cf_JLIkv6Md": "24"
      }
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 10,
    "total": 29,
    "total_pages": 3,
    "has_next_page": true,
    "has_previous_page": false
  }
}
```

## Error Responses

```json Error 401 - Unauthorized theme={null}
{
  "code": "rest_forbidden",
  "message": "Unauthorized",
  "data": { "status": 401 }
}
```

## Common Use Cases

### Filter by Name and Status

```bash theme={null}
GET /wp-json/latepoint-api/v1/customers?first_name=Carlos&status=active
X-API-Key: YOUR_API_KEY
```

### Search by Email Domain

```bash theme={null}
GET /wp-json/latepoint-api/v1/customers?email=gmail.com&per_page=50
X-API-Key: YOUR_API_KEY
```

### Customers Created This Year

```bash theme={null}
GET /wp-json/latepoint-api/v1/customers?created_after=2025-01-01&per_page=100
X-API-Key: YOUR_API_KEY
```

<Note>
  **Stats and custom fields** are always included in every customer in the response — you do not need to pass any `include` parameter.
</Note>

<Note>
  **Sorting**: Results are always returned sorted by `created_at DESC`. Sorting is not configurable on this endpoint.
</Note>
