> ## 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.

# Sessions

> How sessions bind context to API requests and deliver real-time intelligence

## Why Sessions Matter

In e-commerce, understanding the customer journey transformed how businesses operate. Companies like Amazon don't just track what you buy—they track every click, every search, every item you lingered on. This data powers personalization, recommendation engines, and targeted marketing that drives billions in revenue.

EveryBite brings this same approach to dining—but with a critical difference.

**Traditional loyalty identifies guests *after* they purchase. EveryBite identifies them *before* they browse.**

Sessions are how we understand the guest across every touchpoint—your mobile app, your website, your kiosk, your POS, even voice ordering. When a guest opens your app on Monday, browses your kiosk on Wednesday, and orders through your website on Friday, sessions link all of that behavior into a unified profile.

But we go further. When you create a session, we don't just return a session ID—we return **real-time intelligence** about who this guest is:

* **Identity** — Is this a known guest? A returning visitor? A loyalty member?
* **Segments** — What are their dietary needs, preferences, and behavioral patterns?
* **History** — What have they ordered before? What do they customize? What's their average spend?
* **Recommendations** — What should you show them first?

This is **[GuestIQ](/api/guestiq/overview)**—our real-time guest intelligence platform that delivers actionable insights the moment a guest touches your menu.

This foundation enables everything else:

* **Instant Personalization** — Show relevant dishes from the first screen, not after login
* **Real-time Segmentation** — Know their segments before they place an order
* **Predictive Insights** — Anticipate what a guest wants before they search
* **Loyalty Enrichment** — Feed behavioral data into your CRM in real-time
* **Cross-platform Continuity** — Recognize the same guest across app, web, kiosk, and more

Every runtime API call requires a `sessionId` that binds this context to the request. Just include `X-Session-ID` in your headers, and we handle the rest.

## What Sessions Capture

Each session captures context from the touchpoint and links it to everything else we know about this guest:

```mermaid theme={null}
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#1e40af', 'primaryTextColor': '#ffffff', 'lineColor': '#475569', 'fontFamily': 'system-ui, -apple-system, sans-serif', 'fontSize': '14px', 'clusterBkg': '#ffffff', 'clusterBorder': '#cbd5e1'}}}%%
flowchart LR
    subgraph Platforms[" "]
        direction TB
        App["iOS/Android"] ~~~ Web["Web"] ~~~ Kiosk["Kiosk"] ~~~ POS["POS"] ~~~ Voice["Voice"]
    end

    Session["SESSION"]

    subgraph Profile[" "]
        direction TB
        History["History"] ~~~ Prefs["Preferences"] ~~~ Behavior["Behavior"] ~~~ Loyalty["Loyalty"] ~~~ Insights["Insights"]
    end

    Platforms --> Session --> Profile

    classDef platform fill:#e2e8f0,stroke:#94a3b8,color:#1e293b,stroke-width:1px
    classDef session fill:#1e3a8a,stroke:#1e3a8a,color:#ffffff,stroke-width:2px
    classDef profile fill:#2563eb,stroke:#1d4ed8,color:#ffffff,stroke-width:1px

    class App,Web,Kiosk,POS,Voice platform
    class Session session
    class History,Prefs,Behavior,Loyalty,Insights profile
```

| Context                 | What It Tells Us                                                             |
| ----------------------- | ---------------------------------------------------------------------------- |
| **Platform**            | Where is this guest interacting? iOS, Android, web, kiosk, POS, voice?       |
| **Chain & Location**    | Which restaurant and location are they browsing?                             |
| **Guest Identity**      | Guest (inferred from device) or authenticated (known via Passport)?          |
| **Session Behavior**    | What are they searching for? What filters do they apply? What do they click? |
| **Historical Patterns** | How does this session connect to their past behavior across all platforms?   |
| **Enriched Data**       | What do loyalty data and industry trends tell us about guests like this?     |

This is how we turn individual API calls into a complete understanding of the guest—and why consistent session tracking across all your touchpoints is essential.

## Session Lifecycle

```mermaid theme={null}
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#1e40af', 'primaryTextColor': '#ffffff', 'lineColor': '#475569', 'fontFamily': 'system-ui, -apple-system, sans-serif', 'fontSize': '14px'}}}%%
sequenceDiagram
    participant App as Partner App
    participant API as SmartMenu API

    App->>API: startSession(input: { guestId / passportId / email })
    API-->>App: sessionId

    Note over App,API: All subsequent calls include X-Session-ID header

    App->>API: filterOptions()
    App->>API: search(preferences)
    App->>API: dish(dishId)

    Note over App,API: Session expires after 30 min inactivity
```

## Starting a Session

Initialize a session when a guest begins browsing. Pass a stable guest identifier (or EveryBite Passport ID or email)—we generate a unique session ID that you include on subsequent SmartMenu calls. Chain context comes from your API key.

```graphql theme={null}
mutation StartGuestSession {
  startSession(
    input: {
      guestId: "guest_abc123"
      # OR passportId: "passport_abc"
      # OR email: "guest@example.com"
    }
  ) {
    sessionId
  }
}
```

<Accordion title="Example Response">
  ```json theme={null}
  {
    "data": {
      "startSession": {
        "sessionId": "sess_7f3a9c2e-8b1d-4e5f-a6c0-9d2e8f1a3b5c"
      }
    }
  }
  ```
</Accordion>

The `sessionId` is a UUID we generate—guaranteed unique across all sessions. Store it and include it in your headers for all subsequent API calls:

```http theme={null}
X-Session-ID: sess_7f3a9c2e-8b1d-4e5f-a6c0-9d2e8f1a3b5c
```

That's it. Your session is now active, and guest identity is bound to it. Chain context comes from your API key; restaurant context comes from query arguments like `restaurantId`.

## Using Sessions in Queries

Once you've configured your headers, your GraphQL queries are clean—just the data you want:

```graphql theme={null}
query SearchDishes {
  search(
    preferences: {
      diets: [VEGETARIAN]
    }
  ) {
    matches {
      dish { name }
    }
  }
}
```

<Accordion title="Example Response">
  ```json theme={null}
  {
    "data": {
      "search": {
        "matches": [
          { "dish": { "name": "Garden Salad" } },
          { "dish": { "name": "Mediterranean Quinoa Bowl" } },
          { "dish": { "name": "Veggie Wrap" } },
          { "dish": { "name": "Roasted Vegetable Plate" } }
        ]
      }
    }
  }
  ```
</Accordion>

The session context (chain, location, guest identity) comes from your headers, not the query. This keeps your queries focused on what you're asking for, not repeating context on every call.

## Guest vs Authenticated Sessions

Sessions work differently depending on whether the user is authenticated:

<CardGroup cols={2}>
  <Card title="Guest Sessions" icon="user-secret">
    **No Passport token provided**

    * Sessions tracked by device/browser fingerprint
    * Multiple sessions compiled into inferred profile
    * Behavioral patterns used for personalization
    * Limited cross-device continuity
  </Card>

  <Card title="Authenticated Sessions" icon="user-check">
    **Passport token provided**

    * Sessions tied to verified user identity
    * Complete history preserved
    * Cross-device continuity
    * Loyalty program integration
  </Card>
</CardGroup>

### Guest Session Intelligence

Even without authentication, we compile sessions to understand guest patterns:

```mermaid theme={null}
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#1e40af', 'primaryTextColor': '#ffffff', 'lineColor': '#475569', 'fontFamily': 'system-ui, -apple-system, sans-serif', 'fontSize': '14px'}}}%%
flowchart LR
    S1["Monday<br/>Excluded dairy"] --> Profile["Inferred<br/>Profile"]
    S2["Wednesday<br/>Excluded dairy"] --> Profile
    S3["Friday<br/>Excluded dairy"] --> Profile
    Profile --> Insight["Likely dairy-free"]

    classDef session fill:#3b82f6,stroke:#2563eb,color:#ffffff,stroke-width:1px
    classDef profile fill:#e2e8f0,stroke:#94a3b8,color:#1e293b,stroke-width:1px
    classDef insight fill:#10b981,stroke:#059669,color:#ffffff,stroke-width:2px

    class S1,S2,S3 session
    class Profile profile
    class Insight insight
```

### Authenticated Session Benefits

When you include `passportId` in `startSession`, the session unlocks additional capabilities. Your queries stay the same—the personalization comes from the session context:

```graphql theme={null}
query AuthenticatedSearch {
  search(
    preferences: {
      diets: [VEGETARIAN]
    }
  ) {
    matches {
      dish { name }
      matchStatus  # Now based on Passport preferences
    }
  }
}
```

<Accordion title="Example Response">
  ```json theme={null}
  {
    "data": {
      "search": {
        "matches": [
          { "dish": { "name": "Garden Salad" }, "matchStatus": "MATCH" },
          { "dish": { "name": "Mediterranean Quinoa Bowl" }, "matchStatus": "MATCH" },
          { "dish": { "name": "Grilled Veggie Wrap" }, "matchStatus": "ALMOST_MATCH" }
        ]
      }
    }
  }
  ```
</Accordion>

## Runtime Headers

Once you have a session, your runtime API calls only need three headers:

```http theme={null}
Authorization: pk_your_api_key
Content-Type: application/json
X-Session-ID: sess_7f3a9c2e-8b1d-4e5f-a6c0-9d2e8f1a3b5c
```

| Header          | Required | Description                            |
| --------------- | -------- | -------------------------------------- |
| `Authorization` | Yes      | Your API key                           |
| `Content-Type`  | Yes      | `application/json`                     |
| `X-Session-ID`  | Yes      | Session identifier from `startSession` |

Chain context comes from your API key. Guest identity (and any Passport context) is already bound to your session, so you don't need to pass it on every call.

## When to Start a New Session

Start a new session when:

* User opens your app/website
* User begins a new ordering flow
* Previous session has timed out (30 minutes inactivity)
* User switches to a different restaurant chain

## Best Practices

<CardGroup cols={2}>
  <Card title="One Session Per Flow" icon="arrows-rotate">
    Start a new session when the user begins ordering, not on every page view.
  </Card>

  <Card title="Persist Guest ID" icon="database">
    Store the guest ID locally and reuse it across sessions for better personalization.
  </Card>

  <Card title="Handle Timeout Gracefully" icon="clock">
    If a session expires, start a new one transparently - don't interrupt the user.
  </Card>

  <Card title="Include Location When Known" icon="location-dot">
    Pass `restaurantId` if the user has selected a specific location for better analytics.
  </Card>
</CardGroup>
