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

# Guest Preferences

> How personalization works in the SmartMenu API

Guest Preferences represent an individual user's dietary needs, restrictions, and nutritional goals. Pass these with your queries to get personalized results and match status calculations.

## The Two-Layer Model

EveryBite uses a two-layer approach to personalization:

<CardGroup cols={2}>
  <Card title="Chain & API Key" icon="key">
    **App-level, static**

    Identifies which restaurant chain's menu data your app can access via the `Authorization` API key header.
  </Card>

  <Card title="Guest Preferences" icon="user">
    **User-level, dynamic**

    The individual guest's dietary needs. Passed per-request as `preferences` or loaded from their profile.
  </Card>
</CardGroup>

## Preference Types

### Dietary Preferences (Diets)

What type of diet does the guest follow?

```graphql theme={null}
preferences: {
  diets: [VEGETARIAN]
}
```

| Diet          | Description                              |
| ------------- | ---------------------------------------- |
| `VEGAN`       | No animal products                       |
| `VEGETARIAN`  | No meat or fish (may include dairy/eggs) |
| `PESCATARIAN` | Fish but no other meat                   |

### Allergen Exclusions

What allergens must be avoided?

```graphql theme={null}
preferences: {
  excludeAllergens: [PEANUT, DAIRY, EGG, SHELLFISH]
}
```

| Allergen    | Description                             |
| ----------- | --------------------------------------- |
| `DAIRY`     | Milk and milk products                  |
| `EGG`       | Eggs and egg products                   |
| `FISH`      | Fish                                    |
| `SHELLFISH` | Shrimp, crab, lobster, etc.             |
| `TREE_NUT`  | Almonds, walnuts, cashews, etc.         |
| `PEANUT`    | Peanuts and peanut products             |
| `WHEAT`     | Wheat and gluten-containing ingredients |
| `SOY`       | Soybeans and soy products               |
| `SESAME`    | Sesame seeds and sesame oil             |

<Warning>
  Allergen exclusion is critical for guest safety. Our system flags allergens with a confidence score. Always display appropriate warnings and encourage guests to verify with restaurant staff.
</Warning>

### Nutrient Targets

What nutritional goals does the guest have?

```graphql theme={null}
preferences: {
  calorieRange: { min: 300, max: 600 },
  nutrientRanges: {
    protein: { min: 20 },        # At least 20g protein
    carbohydrates: { max: 50 },  # No more than 50g carbs
    fatTotal: { max: 30 }        # No more than 30g total fat
  }
}
```

## Session Tracking

Every API call can include an `X-Session-ID` header that enables analytics and personalization tracking. Sessions bind guest identity and behavioral context to every request; chain context comes from your API key, and restaurant context is provided via query arguments like `restaurantId`. See [Sessions](/docs/concepts/sessions) for details.

How session data is used depends on whether the user is anonymous or authenticated:

<Tabs>
  <Tab title="Authenticated User">
    ```mermaid theme={null}
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2563EB', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1D4ED8', 'lineColor': '#64748b'}}}%%
    flowchart TD
        S1["Session A"] --> User["Known Guest<br/>(Authenticated)"]
        S2["Session B"] --> User
        S3["Session C"] --> User

        classDef session fill:#3B82F6,stroke:#2563EB,color:#fff,stroke-width:1px
        classDef user fill:#1D4ED8,stroke:#1e40af,color:#fff,stroke-width:2px

        class S1,S2,S3 session
        class User user
    ```

    Sessions are directly tied to the known guest via authentication token. Complete history preserved.
  </Tab>

  <Tab title="Anonymous User">
    ```mermaid theme={null}
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2563EB', 'primaryTextColor': '#fff', 'primaryBorderColor': '#1D4ED8', 'lineColor': '#64748b'}}}%%
    flowchart TD
        S1["Session A"] --> Infer["Inferred Profile"]
        S2["Session B"] --> Infer
        S3["Session C"] --> Infer

        classDef session fill:#3B82F6,stroke:#2563EB,color:#fff,stroke-width:1px
        classDef inferred fill:#e2e8f0,stroke:#94a3b8,color:#334155,stroke-width:1px

        class S1,S2,S3 session
        class Infer inferred
    ```

    Sessions are compiled using device fingerprinting and behavioral patterns to build an inferred profile.
  </Tab>
</Tabs>

## Passing Preferences

### Option 1: Per-Request (Anonymous Users)

Pass preferences directly with each query. For anonymous users, we track sessions and use behavioral patterns to build an inferred profile over time.

```graphql theme={null}
query {
  search(
    preferences: {
      diets: [VEGETARIAN]
      excludeAllergens: [PEANUT, DAIRY]
      calorieRange: { max: 600 }
    }
  ) {
    matches {
      dish { name }
      matchStatus
    }
  }
}
```

<Info>
  **Session intelligence**: Even without authentication, we compile sessions from the same device/browser to understand preference patterns. A guest who consistently excludes dairy across multiple sessions may see dairy-free options surfaced more prominently.
</Info>

### Option 2: From Profile (Authenticated Users)

When you include a stable identifier like `guestId` in `startSession`, preferences are loaded from the guest's saved profile. All sessions are tied directly to this known user, enabling:

* Persistent preferences across devices
* Complete dining history
* Loyalty program integration

```graphql theme={null}
# Session started with guestId - preferences loaded automatically
query {
  search {
    matches {
      dish { name }
      matchStatus  # Based on their saved preferences
    }
  }
}
```

<Info>
  With GuestIQ, preferences are set once and work everywhere. A guest sets "I'm allergic to peanuts" in their profile, and it's applied at every participating restaurant. All session data is associated with their verified identity.
</Info>

### Option 3: Combined (Profile + Overrides)

Start with saved preferences but add request-specific filters. The authenticated user's session still tracks these temporary overrides for analytics.

```graphql theme={null}
# Session started with guestId - add per-request overrides
query {
  search(
    preferences: {
      # These override/extend saved preferences for this request
      calorieRange: { max: 400 }  # Stricter than usual today
    }
  ) {
    matches {
      dish { name }
      matchStatus
    }
  }
}
```

## How Preferences Affect Results

When you pass preferences, two things happen:

### 1. Filtering

Dishes that don't meet criteria are filtered out or flagged:

```graphql theme={null}
# With excludeAllergens: [PEANUT]
# Dishes containing peanuts are marked as NOT_MATCH
```

### 2. Match Status Calculation

Every dish gets a `matchStatus` based on how well it fits the preferences:

| Status         | Meaning                                                    |
| -------------- | ---------------------------------------------------------- |
| `MATCH`        | Fully compatible with all preferences                      |
| `ALMOST_MATCH` | Partial match with exceptions (e.g., removable ingredient) |
| `NOT_MATCH`    | Contains excluded allergens or is otherwise incompatible   |

See [Match Status](/docs/concepts/match-status) for details.

## Building a Preferences UI

Use the `filterOptions` query to build your preferences UI dynamically:

```graphql theme={null}
query {
  filterOptions {
    diets {
      type
      displayName
      description
      isEnabled  # Is this filter available for this chain's SmartMenu widget?
    }
    allergens {
      type
      displayName
      icon       # Icon or emoji identifier for UI
      isEnabled
    }
    nutrients {
      type
      displayName
      unit           # e.g. "kcal", "g", "mg"
      defaultMin
      defaultMax
    }
  }
}
```

### Example UI Pattern

Based on our SmartMenu implementation:

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/everybite/images/smartmenu-screenshots/02-preferences-dietary-allergens-nutrients.png" alt="Preferences UI" />
</Frame>

Components:

* **Diet toggles** - Buttons for Vegan, Vegetarian, etc.
* **Allergen checkboxes** - Multi-select for allergens to exclude
* **Nutrient sliders** - Range inputs for calories, protein, etc.
* **Active filter chips** - Show selected filters with remove buttons
