Skip to main content
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:

Menu Key

App-level, staticIdentifies which brand’s menu data your app can access. Stored in your app configuration.

Guest Preferences

User-level, dynamicThe individual guest’s dietary needs. Passed per-request or loaded from their profile.

Preference Types

Dietary Preferences (Diets)

What type of diet does the guest follow?
guestPreferences: {
  diets: [Vegan, GlutenFree]
}
DietDescription
VeganNo animal products
VegetarianNo meat, may include dairy/eggs
PescatarianNo meat except fish/seafood
GlutenFreeNo gluten-containing ingredients
DairyFreeNo dairy products

Allergen Exclusions

What allergens must be avoided?
guestPreferences: {
  excludeAllergens: [Peanut, Dairy, Egg, Shellfish]
}
AllergenDescription
DairyMilk and milk products
EggEggs and egg products
FishFish
ShellfishShrimp, crab, lobster, etc.
WheatWheat and wheat products
TreeNutAlmonds, walnuts, cashews, etc.
PeanutPeanuts and peanut products
SesameSesame seeds and sesame oil
SoySoybeans and soy products
GlutenGluten proteins
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.

Nutrient Targets

What nutritional goals does the guest have?
guestPreferences: {
  calorieRange: { min: 300, max: 600 },
  nutrientTargets: {
    protein: { min: 20 },        # At least 20g protein
    carbohydrates: { max: 50 },  # No more than 50g carbs
    sodium: { max: 800 }         # Under 800mg sodium
  }
}

Session Tracking

Every API call includes an X-Session-ID header that enables analytics and personalization tracking. Sessions bind important context like restaurant location, chain, platform, and guest identity to every request. See Sessions for details. How session data is used depends on whether the user is anonymous or authenticated:
Sessions are directly tied to the known guest via authentication token. Complete history preserved.

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.
query {
  search(
    preferences: {
      diets: [Vegan]
      excludeAllergens: [Peanut, Dairy]
      calorieRange: { max: 600 }
    }
  ) {
    matches {
      dish { name }
      matchStatus
    }
  }
}
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.

Option 2: From Profile (Authenticated Users)

When you include 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
# Session started with guestId - preferences loaded automatically
query {
  search {
    matches {
      dish { name }
      matchStatus  # Based on their saved preferences
    }
  }
}
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.

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.
# 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:
# With excludeAllergens: [Peanut]
# Dishes containing peanuts are marked as NOT_A_MATCH

2. Match Status Calculation

Every dish gets a matchStatus based on how well it fits the preferences:
StatusMeaning
MATCHFully compatible with all preferences
PARTIAL_MATCHCan be modified to become compatible
NOT_A_MATCHContains excluded allergens or incompatible
See Match Status for details.

Building a Preferences UI

Use the filterOptions query to build your preferences UI dynamically:
query {
  filterOptions {
    diets {
      type
      displayName
      isEnabled  # Is this filter available for this menu?
    }
    allergens {
      type
      displayName
      icon       # Icon URL for UI
      isEnabled
    }
    nutrients {
      type
      displayName
      unit           # "g", "mg", "%DV"
      defaultMin
      defaultMax
      recommendedMin # Suggested healthy range
      recommendedMax
    }
  }
}

Example UI Pattern

Based on our SmartMenu implementation:
Preferences UI
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