# Brand Customers

Manage customers associated with a brand. Create new customers, load (create or update) customers in bulk, and retrieve paginated customer lists with keyset-based cursor pagination.

### Create Customer

Customer creation (`POST /brands/{brandId}/customers`) is documented in [Customers → Manage Customers](https://developers.innovorder.io/docs/customers/customers-manage.md), which covers both the standard (free-text) and hierarchy-based (guest group) payloads with a full field reference.

### Bulk Loading & Listing

### `PUT /brands/{brandId}/customers/loader` - Create or Update Customer

Create a new customer or update an existing one. Used for bulk data loading and synchronization. The unicity field determines whether to match on email or studentNumber.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| brandId | string | Yes | The unique identifier of the brand. |
| notifyPOS | boolean | No | Whether to notify POS devices of the change (query parameter). |
| unicityField | string | No | Field used for unicity check: "email" or "studentNumber" (query parameter). |
| autoImportGuestHierarchy | boolean | No | Whether to auto-import guest hierarchy (query parameter). |

#### Request Body

```json
{
  "email": "john.doe@example.com",
  "firstName": "John",
  "lastName": "Doe",
  "phone": "+33612345678",
  "defaults": {
    "email": "default@example.com",
    "password": "DefaultP@ss",
    "firstName": "Default",
    "lastName": "User"
  },
  "student": {
    "studentNumber": "STU-2025-001",
    "accountPaymentType": "PREPAYMENT"
  }
}
```

##### Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| email | string | "john.doe@example.com" | Email address. |
| firstName | string | "John" | The first name value. |
| lastName | string | "Doe" | The last name value. |
| phone | string | "+33612345678" | Phone number. |
| defaults | object | {…} | Object containing defaults fields. |
| defaults.email | string | "default@example.com" | Email address. |
| defaults.password | string | "DefaultP@ss" | The password value. |
| defaults.firstName | string | "Default" | The first name value. |
| defaults.lastName | string | "User" | The last name value. |
| student | object | {…} | Object containing student fields. |
| student.studentNumber | string | "STU-2025-001" | The student number value. |
| student.accountPaymentType | string | "PREPAYMENT" | The account payment type value. |

#### Response

```json
{
  "status": 200,
  "code": "customer_create_or_update_succeed",
  "message": "Customer has been successfully loaded.",
  "data": {
    "customerId": 50001,
    "email": "john.doe@example.com",
    "firstName": "John",
    "lastName": "Doe"
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "customer\_create\_or\_update\_succeed" | Machine-readable application code for the result. |
| message | string | "Customer has been successfully loaded." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.customerId | integer | 50001 | Identifier of the customer. |
| data.email | string | "john.doe@example.com" | Email address. |
| data.firstName | string | "John" | The first name value. |
| data.lastName | string | "Doe" | The last name value. |

### `GET /brands/{brandId}/customers` - List Customers (Paginated)

Retrieve customers for a brand updated since a given date. Uses keyset-based cursor pagination for efficient iteration over large datasets.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| brandId | integer | Yes | The unique identifier of the brand. |
| sinceUtc | string | Yes | Date in UTC (YYYY-MM-DD format). Only customers updated since this date are returned (query parameter). |
| cursor | string | No | Cursor for keyset pagination. Use the value from the previous response to get the next page (query parameter). |
| limit | integer | No | Maximum number of results per page. Defaults to 100 (query parameter). |

#### Response

```json
{
  "status": 200,
  "code": "success",
  "data": [
    {
      "id": 50001,
      "email": "john.doe@example.com",
      "firstName": "John",
      "lastName": "Doe",
      "phone": "+33612345678",
      "brandId": 100
    }
  ],
  "pagination": {
    "nextCursor": "eyJpZCI6NTAwMDF9"
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "success" | Machine-readable application code for the result. |
| data | array | \[…\] | Endpoint-specific response payload. |
| data\[\] | object | {…} | Endpoint-specific response payload. |
| data\[\].id | integer | 50001 | The id value. |
| data\[\].email | string | "john.doe@example.com" | Email address. |
| data\[\].firstName | string | "John" | The first name value. |
| data\[\].lastName | string | "Doe" | The last name value. |
| data\[\].phone | string | "+33612345678" | Phone number. |
| data\[\].brandId | integer | 100 | Identifier of the brand. |
| pagination | object | {…} | Object containing pagination fields. |
| pagination.nextCursor | string | "eyJpZCI6NTAwMDF9" | Cursor to use when retrieving the next page. |

### `GET /brands/{brandId}/customers/paymentTypes/{paymentType}/count` - Get Customer Count by Payment Type

Retrieve the number of customers for a brand filtered by their payment type (e.g., PREPAYMENT, POSTPAYMENT, CASH).

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| brandId | integer | Yes | The unique identifier of the brand. |
| paymentType | string | Yes | The account payment type: PREPAYMENT, POSTPAYMENT, or CASH. |

#### Response

```json
{
  "status": 200,
  "code": "customer_count_by_payment_type_found",
  "message": "The customer count by paymentType from a brand have been found",
  "data": {
    "count": 342
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "customer\_count\_by\_payment\_type\_found" | Machine-readable application code for the result. |
| message | string | "The customer count by paymentType from a brand have been found" | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.count | integer | 342 | Total number of matching records. |

### Student Entities

Retrieve student entity hierarchies (sections, classes, groups) configured for a brand. These are used in collective catering contexts to organize customers into groups with specific pricing rules and entrance fees.

### `GET /brands/{brandId}/students_entities` - Get All Student Entities

Retrieve the distinct student entity values (classes, sections, sub-sections, tariff codes) used by the customers of the brand, including disabled and archived customers, plus the class &gt; section &gt; sub-section tree in the entities field.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| brandId | integer | Yes | The unique identifier of the brand. |

#### Response

```json
{
  "status": 200,
  "code": "students_entities_found",
  "message": "Student entities found",
  "data": {
    "sections": [
      "Sciences",
      "Lettres"
    ],
    "subSections": [
      "Groupe A"
    ],
    "classes": [
      "L3 Informatique"
    ],
    "tariffCodes": [
      "T1"
    ],
    "entities": [
      {
        "name": "L3 Informatique",
        "children": [
          {
            "name": "Sciences",
            "children": [
              {
                "name": "Groupe A",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "students\_entities\_found" | Machine-readable application code for the result. |
| message | string | "Student entities found" | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.sections | array | \[…\] | List of sections entries. |
| data.sections\[\] | string | "Sciences" | The sections value. |
| data.subSections | array | \[…\] | List of sub sections entries. |
| data.subSections\[\] | string | "Groupe A" | The sub sections value. |
| data.classes | array | \[…\] | List of classes entries. |
| data.classes\[\] | string | "L3 Informatique" | The classes value. |
| data.tariffCodes | array | \[…\] | List of tariff codes entries. |
| data.tariffCodes\[\] | string | "T1" | The tariff codes value. |
| data.entities | array | \[…\] | List of entities entries. |
| data.entities\[\] | object | {…} | Object containing entities fields. |
| data.entities\[\].name | string | "L3 Informatique" | The name value. |
| data.entities\[\].children | array | \[…\] | List of children entries. |
| data.entities\[\].children\[\] | object | {…} | Object containing children fields. |
| data.entities\[\].children\[\].name | string | "Sciences" | The name value. |
| data.entities\[\].children\[\].children | array | \[…\] | List of children entries. |
| data.entities\[\].children\[\].children\[\] | object | {…} | Object containing children fields. |
| data.entities\[\].children\[\].children\[\].name | string | "Groupe A" | The name value. |
| data.entities\[\].children\[\].children\[\].children | array | \[\] | List of children entries. |

The active-only variant, `GET /brands/{brandId}/active_students_entities`, returns the same structure restricted to enabled, non-archived customers. It is documented in [Customers → Hierarchy & Groups](https://developers.innovorder.io/docs/customers/customers-hierarchy-groups.md) as part of the hierarchy traversal workflow.
