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

# Get Customer Recommendations

> Four recommendation blocks for one known customer, built from their cart, browsing and purchase history, with a checkpoint on each block saying how much of it is personalized.

## Overview

Send who the customer is, and Glood looks up their history server-side and returns four blocks:

| Block | Built from | Algorithm |
| - | - | - |
| `cart` | Products in the customer's cart | Frequently bought together |
| `browsing_history` | Products the customer viewed | Similar products |
| `purchase_history` | Products the customer bought | Cross-sell |
| `trending` | Nothing customer-specific | Trending |

No `product_ids` are needed: each block is anchored on the customer's own two most recent
products for that signal. This makes the endpoint a fit for marketing emails, CRM and CDP syncs,
account pages, and any surface that knows the customer but not the product they are looking at.
For recommendations around specific products, use [Query recommendations](/api-reference/recommendations/headless/recommendations).

Every block always comes back filled. When a customer has too little data for a block, Glood
tops it up with trending products, and the block's [checkpoint](#checkpoints) tells you how
much of it is personalized.

You can ask for [only some of the blocks](#choosing-blocks), or for
[the checkpoints alone](#checkpoints-only) to decide what to show before fetching products.

## Identifying the customer

Send **at least one** of these. A request with none of them is rejected with `400`.

| Field | Notes |
| - | - |
| `customer_id` | Shopify customer ID, numeric (`9155793715519`) or GID (`gid://shopify/Customer/9155793715519`), as a string or a number. |
| `email` | Case and surrounding whitespace are ignored. Also matched against the Shopify customer record and against orders, so guest checkouts are found. |
| `phone` | Formatting is ignored (`+1 (555) 010-9999` matches `+15550109999`). Matched against orders too. |

<Tip>
  Send `customer_id` whenever you have it. A customer usually browses on several devices, and
  `customer_id` reaches all of them. `email` alone reaches only the devices where an email was
  captured, plus the customer's orders.
</Tip>

<Warning>
  Send one customer's identifiers per request. Identifiers are combined with OR, so an `email`
  for one customer and a `phone` for another would merge both customers' histories.
</Warning>

Anonymous `client_id` / `user_id` are not accepted here (`400`). For anonymous shoppers, use
[Query recommendations](/api-reference/recommendations/headless/recommendations).

An identifier that matches nobody is not an error: you get `200` with
`customer.identified: false` and three blocks filled from trending.

## What each signal contains

| Signal | Source |
| - | - |
| Browsing history | Products viewed, across every matched device, newest first. |
| Cart | `cart_product_ids` if you send it. Otherwise the customer's add-to-cart history, minus anything bought since. |
| Purchase history | Orders from the last 365 days (cancelled orders excluded), plus purchases tracked on the storefront. |

Each signal keeps at most 10 products. Products that no longer exist in the catalogue are
skipped when choosing a block's anchors.

### Sending the live cart

If your storefront knows the current cart, send it as `cart_product_ids`: up to 10 product IDs,
as an array or a comma-separated string. It **replaces** Glood's add-to-cart history, which
cannot see removals. Send `[]` for an empty cart. Leave the field out only when you don't know
the cart.

## What is never recommended

* Products the customer has bought.
* Products in the customer's cart.
* Products and tags the merchant excluded in Glood settings.
* A block's own anchor products.
* The same product twice in one response. Blocks claim products in order: `cart`, then
  `browsing_history`, then `purchase_history`, then `trending`. The trending block shows the
  shop's top trending products before any of them are used to top up other blocks.

## Choosing blocks

Send `blocks` to get only some of the blocks, for example `["cart", "trending"]`. Valid names
are `cart`, `browsing_history`, `purchase_history` and `trending`. Leave it out to get all four.

* The response contains only the blocks you asked for, always in the order above, whatever
  order you send them in.
* A block you did not ask for is not computed and claims no products. So a block can contain a
  product that, in a full response, an earlier block would have taken.
* Without `trending`, short blocks are topped up from the very top of the trending list.
* `customer.signals` always reports all three signals.

## Checkpoints only

Add `?checkpoints_only=true` to the URL to get every block's `checkpoint`, and `customer`,
without the products. Each block then has `recommendation_serve_id`, `recommendation_type` and
`checkpoint` only. Use it to decide which blocks to show, or whether a customer has enough data
for a personalized campaign, before you fetch any products.

The checkpoints are the same as in a full response for the same request: Glood still builds
the blocks to count their products. The response is smaller, but the request costs the same.
It combines with `blocks`.

## Context

`context` is an optional list of free-form labels for where the recommendations will be
shown, for example `["email", "win_back"]`: up to 20 strings of up to 200 characters each. It
does not change which products are returned.

## Checkpoints

Every block carries a `checkpoint`:

| Field | Meaning |
| - | - |
| `status` | `personalized`: every product came from the customer's data. `partial`: some did, the rest are trending. `fallback`: none did, all are trending. `trending`: the trending block itself. |
| `reason` | Why a block is short of personalized products, or `null`. `no_customer_data`: the customer has no usable data for this signal. `insufficient_results`: there was data, but it produced fewer than `max_recommendations` products not already shown in an earlier block. `error`: this block failed and was filled from trending, while the rest of the response is unaffected. |
| `uses_customer_data` | `true` when at least one product came from the customer's data. Always `false` on the trending block. |
| `anchor_product_ids` | The customer's products this block was computed from (at most 2). |
| `personalized_count` | The **first** `personalized_count` entries of `recommendations` are personalized. |
| `fallback_count` | The remaining entries are trending products. |
| `filled_from` | `"trending"` when `fallback_count > 0`, otherwise `null`. |

`customer.signals` reports how much history was found for each signal (`count`, capped at 10),
and `customer.signals.cart.source` says whether the cart came from your request (`request`) or
from Glood's tracking (`pixel`).

<Tip>
  You can render every block as-is. Use the checkpoint to label it (for example "Picked for you"
  only when `status` is `personalized`), to show only the first `personalized_count` products,
  or to measure how often customers have enough data.
</Tip>

## Sales channels

Send `publication_ids` to return only products published on those sales channels, as on the
other headless recommendation endpoints. See [Filter by Sales Channel](/guides/product-filtering/filter-by-sales-channel).

## Errors

| Status | When |
| - | - |
| `400` | No usable `customer_id`, `email` or `phone`; an unknown field (such as `client_id`, or `publicationIds` instead of `publication_ids`); `max_recommendations` outside 1–50; more than 10 `cart_product_ids`; a `blocks` list that is empty, repeats a block or names an unknown one; a `context` that is not a list of strings, or has more than 20 entries or one over 200 characters; a `publication_ids` value the shop has not configured; a `checkpoints_only` that is not `true` or `false`; or the shop has no active plan. |
| `401` | Missing or invalid storefront token, or missing `x-shop`. |
| `429` | Rate limit exceeded for the shop. |

## Examples

<CodeGroup>
  ```bash Known customer theme={null}
  curl -sS -X POST 'https://storefront.glood.ai/api/storefront/v3/headless/recommendations/customer' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <shop-storefront-token>' \
    -H 'x-shop: shop.myshopify.com' \
    -d '{
      "customer_id": "9155793715519",
      "email": "shopper@example.com",
      "max_recommendations": 4,
      "view": "product_ids"
    }'
  ```

  ```bash With the live cart theme={null}
  curl -sS -X POST 'https://storefront.glood.ai/api/storefront/v3/headless/recommendations/customer' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <shop-storefront-token>' \
    -H 'x-shop: shop.myshopify.com' \
    -d '{
      "email": "shopper@example.com",
      "cart_product_ids": [9311227838783, 9311227904319],
      "max_recommendations": 8
    }'
  ```

  ```bash Some blocks theme={null}
  curl -sS -X POST 'https://storefront.glood.ai/api/storefront/v3/headless/recommendations/customer' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <shop-storefront-token>' \
    -H 'x-shop: shop.myshopify.com' \
    -d '{
      "email": "shopper@example.com",
      "blocks": ["browsing_history", "trending"],
      "context": ["email", "win_back"],
      "view": "product_ids"
    }'
  ```

  ```bash Checkpoints only theme={null}
  curl -sS -X POST 'https://storefront.glood.ai/api/storefront/v3/headless/recommendations/customer?checkpoints_only=true' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <shop-storefront-token>' \
    -H 'x-shop: shop.myshopify.com' \
    -d '{
      "customer_id": "9155793715519"
    }'
  ```

  ```bash Edge endpoint theme={null}
  curl -sS -X POST 'https://edge.glood.ai/api/edge/storefront/v3/headless/recommendations/customer' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer <shop-storefront-token>' \
    -H 'x-shop: shop.myshopify.com' \
    -d '{
      "customer_id": "9155793715519",
      "view": "product_ids"
    }'
  ```
</CodeGroup>

<ResponseExample>
  ```json 200 - product_ids view theme={null}
  {
    "status": "ok",
    "serve_id": "4f2e9c1a-7d3b-4b8e-9a51-2c6f0d8e1b77",
    "customer": {
      "identified": true,
      "signals": {
        "browsing_history": { "available": true, "count": 6 },
        "cart": { "available": true, "count": 1, "source": "pixel" },
        "purchase_history": { "available": false, "count": 0 }
      }
    },
    "blocks": {
      "cart": {
        "recommendation_serve_id": "9a1c2b3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
        "recommendation_type": "bought_together",
        "checkpoint": {
          "status": "personalized",
          "reason": null,
          "uses_customer_data": true,
          "anchor_product_ids": [9311227904319],
          "personalized_count": 4,
          "fallback_count": 0,
          "filled_from": null
        },
        "recommendations": [
          { "product_id": 9311227838783 },
          { "product_id": 9311227871551 },
          { "product_id": 9311227937087 },
          { "product_id": 9311227969855 }
        ]
      },
      "browsing_history": {
        "recommendation_serve_id": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
        "recommendation_type": "similar_products",
        "checkpoint": {
          "status": "partial",
          "reason": "insufficient_results",
          "uses_customer_data": true,
          "anchor_product_ids": [9311228002623, 9311228035391],
          "personalized_count": 2,
          "fallback_count": 2,
          "filled_from": "trending"
        },
        "recommendations": [
          { "product_id": 9311228068159 },
          { "product_id": 9311228100927 },
          { "product_id": 9311228264767 },
          { "product_id": 9311228297535 }
        ]
      },
      "purchase_history": {
        "recommendation_serve_id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
        "recommendation_type": "cross_sell",
        "checkpoint": {
          "status": "fallback",
          "reason": "no_customer_data",
          "uses_customer_data": false,
          "anchor_product_ids": [],
          "personalized_count": 0,
          "fallback_count": 4,
          "filled_from": "trending"
        },
        "recommendations": [
          { "product_id": 9311228330303 },
          { "product_id": 9311228363071 },
          { "product_id": 9311228395839 },
          { "product_id": 9311228428607 }
        ]
      },
      "trending": {
        "recommendation_serve_id": "3d4e5f6a-7b8c-4d9e-8f0a-2b3c4d5e6f7a",
        "recommendation_type": "trending",
        "checkpoint": {
          "status": "trending",
          "reason": null,
          "uses_customer_data": false,
          "anchor_product_ids": [],
          "personalized_count": 0,
          "fallback_count": 0,
          "filled_from": null
        },
        "recommendations": [
          { "product_id": 9311228133695 },
          { "product_id": 9311228166463 },
          { "product_id": 9311228199231 },
          { "product_id": 9311228231999 }
        ]
      }
    }
  }
  ```

  ```json 200 - product_details view (one block shown) theme={null}
  {
    "status": "ok",
    "serve_id": "4f2e9c1a-7d3b-4b8e-9a51-2c6f0d8e1b77",
    "customer": { "identified": true, "signals": { "...": "..." } },
    "blocks": {
      "cart": {
        "recommendation_serve_id": "9a1c2b3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
        "recommendation_type": "bought_together",
        "checkpoint": {
          "status": "personalized",
          "reason": null,
          "uses_customer_data": true,
          "anchor_product_ids": [9311227904319],
          "personalized_count": 1,
          "fallback_count": 0,
          "filled_from": null
        },
        "recommendations": [
          {
            "product_id": 9311227838783,
            "title": "Classic Cotton T-Shirt",
            "handle": "classic-cotton-t-shirt",
            "price": 1025,
            "compare_at_price": null,
            "image": {
              "id": "gid://shopify/ProductImage/123456",
              "url": "https://cdn.shopify.com/s/files/1/example/products/t-shirt.jpg",
              "altText": "Classic Cotton T-Shirt",
              "width": 1600,
              "height": 1600
            },
            "tags": "cotton, casual, bestseller",
            "product_type": "T-Shirt",
            "vendor": "Example Co",
            "options": [
              { "id": 123, "name": "Title", "position": 1, "values": ["Default Title"] }
            ],
            "variants": [
              {
                "variant_id": 48328566276415,
                "title": "Default Title",
                "display_name": "Classic Cotton T-Shirt - Default Title",
                "price": "1025.00",
                "compare_at_price": null,
                "sku": "",
                "position": 1,
                "is_in_stock": true,
                "available_for_sale": true,
                "sellable_online_quantity": 50,
                "selected_options": [{ "name": "Title", "value": "Default Title" }]
              }
            ],
            "metafields": []
          }
        ]
      },
      "browsing_history": { "...": "..." },
      "purchase_history": { "...": "..." },
      "trending": { "...": "..." }
    }
  }
  ```

  ```json 200 - ?checkpoints_only=true theme={null}
  {
    "status": "ok",
    "serve_id": "5a3f0d2b-8e4c-4c9f-a062-3d7e1f9c2c88",
    "customer": {
      "identified": true,
      "signals": {
        "browsing_history": { "available": true, "count": 6 },
        "cart": { "available": true, "count": 1, "source": "pixel" },
        "purchase_history": { "available": false, "count": 0 }
      }
    },
    "blocks": {
      "cart": {
        "recommendation_serve_id": "6b4a1e3c-9f5d-4da0-b173-4e8f2a0d3d99",
        "recommendation_type": "bought_together",
        "checkpoint": {
          "status": "personalized",
          "reason": null,
          "uses_customer_data": true,
          "anchor_product_ids": [9311227904319],
          "personalized_count": 10,
          "fallback_count": 0,
          "filled_from": null
        }
      },
      "browsing_history": {
        "recommendation_serve_id": "7c5b2f4d-0a6e-4eb1-8284-5f9a3b1e4eaa",
        "recommendation_type": "similar_products",
        "checkpoint": {
          "status": "partial",
          "reason": "insufficient_results",
          "uses_customer_data": true,
          "anchor_product_ids": [9311228002623, 9311228035391],
          "personalized_count": 6,
          "fallback_count": 4,
          "filled_from": "trending"
        }
      },
      "purchase_history": {
        "recommendation_serve_id": "8d6c3a5e-1b7f-4fc2-9395-6a0b4c2f5fbb",
        "recommendation_type": "cross_sell",
        "checkpoint": {
          "status": "fallback",
          "reason": "no_customer_data",
          "uses_customer_data": false,
          "anchor_product_ids": [],
          "personalized_count": 0,
          "fallback_count": 10,
          "filled_from": "trending"
        }
      },
      "trending": {
        "recommendation_serve_id": "9e7d4b6f-2c80-4ad3-8406-7b1c5d3a6acc",
        "recommendation_type": "trending",
        "checkpoint": {
          "status": "trending",
          "reason": null,
          "uses_customer_data": false,
          "anchor_product_ids": [],
          "personalized_count": 0,
          "fallback_count": 0,
          "filled_from": null
        }
      }
    }
  }
  ```

  ```json 400 - no customer identifier theme={null}
  {
    "errors": [
      {
        "message": "one of customer_id, email or phone is required",
        "path": [],
        "type": "customer.identity",
        "context": {
          "label": "value",
          "value": {
            "max_recommendations": 4,
            "view": "product_details",
            "blocks": ["cart", "browsing_history", "purchase_history", "trending"]
          }
        }
      }
    ]
  }
  ```
</ResponseExample>


## OpenAPI

````yaml POST /api/storefront/v3/headless/recommendations/customer
openapi: 3.0.1
info:
  title: Glood.AI API Reference
  description: Glood.AI API Reference
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://storefront.glood.ai
security:
  - bearerAuth: []
paths:
  /api/storefront/v3/headless/recommendations/customer:
    post:
      description: >-
        Four recommendation blocks for one known customer (cart → frequently
        bought together, browsing history → similar products, purchase history →
        cross-sell, and trending), each with a checkpoint saying how much of it
        came from the customer's own data. Blocks short of customer data are
        topped up with trending products. Also served on edge at
        `https://edge.glood.ai/api/edge/storefront/v3/headless/recommendations/customer`.
      parameters:
        - name: x-shop
          in: header
          description: Shopify store URL
          required: true
          schema:
            type: string
            example: shop.myshopify.com
        - name: checkpoints_only
          in: query
          required: false
          description: >-
            `true` returns every block's `checkpoint` (and `customer`) without
            the products: each block has no `recommendations`. The checkpoints
            equal those of a full response for the same request; Glood still
            builds the blocks to count them.
          schema:
            type: boolean
            default: false
      requestBody:
        description: Request body
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HeadlessCustomerRecommendationsRequest'
            examples:
              knownCustomer:
                summary: Known customer (send every identifier you have)
                value:
                  customer_id: '9155793715519'
                  email: shopper@example.com
                  max_recommendations: 4
                  view: product_ids
              liveCart:
                summary: With the live cart
                value:
                  email: shopper@example.com
                  cart_product_ids:
                    - 9311227838783
                    - 9311227904319
                  max_recommendations: 8
              csvCart:
                summary: Live cart as a CSV string
                value:
                  phone: '+15550109999'
                  cart_product_ids: 9311227838783,9311227904319
              emptyCart:
                summary: Cart known to be empty
                value:
                  customer_id: '9155793715519'
                  cart_product_ids: []
              someBlocks:
                summary: Some blocks, with context
                value:
                  email: shopper@example.com
                  blocks:
                    - browsing_history
                    - trending
                  context:
                    - email
                    - win_back
                  view: product_ids
      responses:
        '200':
          description: The requested blocks (all four by default), each with a checkpoint
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HeadlessCustomerRecommendationsResponse'
              example:
                status: ok
                serve_id: 4f2e9c1a-7d3b-4b8e-9a51-2c6f0d8e1b77
                customer:
                  identified: true
                  signals:
                    browsing_history:
                      available: true
                      count: 6
                    cart:
                      available: true
                      count: 1
                      source: pixel
                    purchase_history:
                      available: false
                      count: 0
                blocks:
                  cart:
                    recommendation_serve_id: 9a1c2b3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d
                    recommendation_type: bought_together
                    checkpoint:
                      status: personalized
                      reason: null
                      uses_customer_data: true
                      anchor_product_ids:
                        - 9311227904319
                      personalized_count: 4
                      fallback_count: 0
                      filled_from: null
                    recommendations:
                      - product_id: 9311227838783
                      - product_id: 9311227871551
                      - product_id: 9311227937087
                      - product_id: 9311227969855
                  browsing_history:
                    recommendation_serve_id: 1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e
                    recommendation_type: similar_products
                    checkpoint:
                      status: partial
                      reason: insufficient_results
                      uses_customer_data: true
                      anchor_product_ids:
                        - 9311228002623
                        - 9311228035391
                      personalized_count: 2
                      fallback_count: 2
                      filled_from: trending
                    recommendations:
                      - product_id: 9311228068159
                      - product_id: 9311228100927
                      - product_id: 9311228264767
                      - product_id: 9311228297535
                  purchase_history:
                    recommendation_serve_id: 2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f
                    recommendation_type: cross_sell
                    checkpoint:
                      status: fallback
                      reason: no_customer_data
                      uses_customer_data: false
                      anchor_product_ids: []
                      personalized_count: 0
                      fallback_count: 4
                      filled_from: trending
                    recommendations:
                      - product_id: 9311228330303
                      - product_id: 9311228363071
                      - product_id: 9311228395839
                      - product_id: 9311228428607
                  trending:
                    recommendation_serve_id: 3d4e5f6a-7b8c-4d9e-8f0a-2b3c4d5e6f7a
                    recommendation_type: trending
                    checkpoint:
                      status: trending
                      reason: null
                      uses_customer_data: false
                      anchor_product_ids: []
                      personalized_count: 0
                      fallback_count: 0
                      filled_from: null
                    recommendations:
                      - product_id: 9311228133695
                      - product_id: 9311228166463
                      - product_id: 9311228199231
                      - product_id: 9311228231999
        '400':
          description: >-
            Validation error, unconfigured publication_ids, or a shop without an
            active plan
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HeadlessQueryRecommendationsError'
              example:
                errors:
                  - message: one of customer_id, email or phone is required
                    path: []
                    type: customer.identity
                    context:
                      label: value
                      value:
                        max_recommendations: 4
                        view: product_details
        '401':
          description: Missing or invalid storefront token, or missing x-shop
        '429':
          description: Rate limit exceeded for the shop
components:
  schemas:
    HeadlessCustomerRecommendationsRequest:
      type: object
      description: >-
        At least one of `customer_id`, `email` or `phone` is required. Unknown
        fields (including `client_id` and `user_id`) are rejected with 400.
      properties:
        customer_id:
          description: >-
            Shopify customer ID, numeric or GID, as a string or a number.
            Reaches every device the customer used, so send it whenever you have
            it.
          oneOf:
            - type: string
              example: '9155793715519'
            - type: integer
              example: 9155793715519
        email:
          type: string
          description: >-
            Customer email. Case and surrounding whitespace are ignored. Also
            matched against the Shopify customer record and against orders, so
            guest checkouts are found.
          example: shopper@example.com
        phone:
          type: string
          description: >-
            Customer phone. Formatting is ignored, so `+1 (555) 010-9999` and
            `+15550109999` are equivalent. Also matched against orders.
          example: '+15550109999'
        cart_product_ids:
          description: >-
            The customer's live cart: up to 10 product IDs, as a JSON array of
            integers or a comma-separated string. When present it replaces
            Glood's add-to-cart history, and `[]` means an empty cart. Omit it
            only when you don't know the cart.
          oneOf:
            - title: integer[]
              type: array
              items:
                type: integer
              maxItems: 10
              example:
                - 9311227838783
                - 9311227904319
            - title: string (CSV)
              type: string
              example: 9311227838783,9311227904319
              description: Comma-separated product IDs
        max_recommendations:
          type: integer
          minimum: 1
          maximum: 50
          default: 10
          description: Products per block.
        view:
          type: string
          enum:
            - product_details
            - product_ids
          default: product_details
          description: Format of each block's `recommendations`.
        blocks:
          type: array
          items:
            type: string
            enum:
              - cart
              - browsing_history
              - purchase_history
              - trending
          minItems: 1
          maxItems: 4
          uniqueItems: true
          default:
            - cart
            - browsing_history
            - purchase_history
            - trending
          description: >-
            Optional. The blocks to return. The response contains only these,
            always in the order cart, browsing_history, purchase_history,
            trending. A block not asked for is not computed and claims no
            products in the cross-block dedupe; without `trending`, short blocks
            are topped up from the very top of the trending list.
          example:
            - browsing_history
            - trending
        context:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 200
          maxItems: 20
          description: >-
            Optional. Free-form labels for where the recommendations will be
            shown. Does not change which products are returned.
          example:
            - email
            - win_back
        publication_ids:
          type: array
          items:
            oneOf:
              - type: string
                pattern: ^[0-9]+$
              - type: integer
          maxItems: 50
          description: >-
            Optional. Numeric Shopify publication (sales channel) ids. When
            present, only products published on at least one of these channels
            are returned and the default "published to the Online Store" gate is
            replaced by this filter; market and B2B filters still apply. A
            single id may be sent without the array wrapper. Each id must be one
            the merchant enabled under Settings → Sales channels; unknown ids
            return 400. The id is the numeric tail of
            gid://shopify/Publication/<id>.
          example:
            - '30085840999'
    HeadlessCustomerRecommendationsResponse:
      type: object
      required:
        - status
        - serve_id
        - customer
        - blocks
      properties:
        status:
          type: string
          enum:
            - ok
        serve_id:
          type: string
          format: uuid
          description: Unique identifier for this request
        customer:
          type: object
          description: >-
            What Glood found about the customer. Email and phone are never
            echoed.
          properties:
            identified:
              type: boolean
              description: True when at least one visitor profile or order matched
            signals:
              type: object
              properties:
                browsing_history:
                  type: object
                  description: Viewed products found
                  properties:
                    available:
                      type: boolean
                      description: '`count > 0`'
                    count:
                      type: integer
                      minimum: 0
                      maximum: 10
                      description: Products found, capped at 10
                cart:
                  type: object
                  description: Cart products found
                  properties:
                    available:
                      type: boolean
                      description: '`count > 0`'
                    count:
                      type: integer
                      minimum: 0
                      maximum: 10
                      description: Products found, capped at 10
                    source:
                      type: string
                      enum:
                        - request
                        - pixel
                      description: >-
                        `request` when you sent `cart_product_ids`, otherwise
                        `pixel` (Glood's add-to-cart history)
                purchase_history:
                  type: object
                  description: Purchased products found
                  properties:
                    available:
                      type: boolean
                      description: '`count > 0`'
                    count:
                      type: integer
                      minimum: 0
                      maximum: 10
                      description: Products found, capped at 10
        blocks:
          type: object
          properties:
            cart:
              $ref: '#/components/schemas/HeadlessCustomerRecommendationsBlock'
            browsing_history:
              $ref: '#/components/schemas/HeadlessCustomerRecommendationsBlock'
            purchase_history:
              $ref: '#/components/schemas/HeadlessCustomerRecommendationsBlock'
            trending:
              $ref: '#/components/schemas/HeadlessCustomerRecommendationsBlock'
          description: >-
            Only the blocks asked for in `blocks` (all four by default), in this
            order.
    HeadlessQueryRecommendationsError:
      type: object
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
                description: Human readable error message
              path:
                type: array
                items:
                  type: string
                description: Path to the field that caused the error
              type:
                type: string
                description: Type of validation error
              context:
                type: object
                properties:
                  limit:
                    type: number
                    description: Maximum allowed value
                  value:
                    type: number
                    description: Actual value provided
                  label:
                    type: string
                    description: Field label
                  key:
                    type: string
                    description: Field key
    HeadlessCustomerRecommendationsBlock:
      type: object
      required:
        - recommendation_serve_id
        - recommendation_type
        - checkpoint
      properties:
        recommendation_serve_id:
          type: string
          format: uuid
          description: Unique identifier for this block's serve
        recommendation_type:
          type: string
          enum:
            - bought_together
            - similar_products
            - cross_sell
            - trending
          description: Algorithm behind the block
        checkpoint:
          $ref: '#/components/schemas/HeadlessCustomerRecommendationsCheckpoint'
        recommendations:
          type: array
          description: >-
            Personalized products first, then trending fillers. Never more than
            `max_recommendations`. Absent when the request has
            `?checkpoints_only=true`.
          items:
            $ref: '#/components/schemas/HeadlessRecommendedProduct'
    HeadlessCustomerRecommendationsCheckpoint:
      type: object
      description: How much of a block came from the customer's own data.
      required:
        - status
        - reason
        - uses_customer_data
        - anchor_product_ids
        - personalized_count
        - fallback_count
        - filled_from
      properties:
        status:
          type: string
          enum:
            - personalized
            - partial
            - fallback
            - trending
          description: >-
            `personalized`: every product came from the customer's data.
            `partial`: some did, the rest are trending. `fallback`: none did.
            `trending`: the trending block itself.
        reason:
          type: string
          nullable: true
          enum:
            - no_customer_data
            - insufficient_results
            - error
            - null
          description: >-
            Why the block is short of personalized products, or null.
            `no_customer_data`: no usable data for this signal.
            `insufficient_results`: the data produced fewer than
            `max_recommendations` products not already shown in an earlier
            block. `error`: the block failed and was filled from trending.
        uses_customer_data:
          type: boolean
          description: >-
            True when at least one product came from the customer's data. Always
            false on the trending block.
        anchor_product_ids:
          type: array
          items:
            type: integer
          maxItems: 2
          description: The customer's products this block was computed from.
        personalized_count:
          type: integer
          description: >-
            The first `personalized_count` entries of `recommendations` are
            personalized.
        fallback_count:
          type: integer
          description: The remaining entries are trending products.
        filled_from:
          type: string
          nullable: true
          enum:
            - trending
            - null
          description: '`trending` when `fallback_count > 0`, otherwise null.'
    HeadlessRecommendedProduct:
      type: object
      properties:
        product_id:
          type: integer
          description: Shopify product ID
        title:
          type: string
          description: Product title (only when view = product_details)
        handle:
          type: string
          description: Product URL handle (only when view = product_details)
        price:
          type: number
          description: Product price (only when view = product_details)
        compare_at_price:
          type: number
          nullable: true
          description: Original price before discount (only when view = product_details)
        image:
          type: object
          description: Product featured image (only when view = product_details)
          properties:
            id:
              type: string
            url:
              type: string
            altText:
              type: string
              nullable: true
            width:
              type: integer
            height:
              type: integer
        tags:
          type: string
          description: Comma-separated product tags (only when view = product_details)
        options:
          type: array
          description: Product options (only when view = product_details)
          items:
            type: object
            properties:
              id:
                type: integer
              name:
                type: string
              position:
                type: integer
              values:
                type: array
                items:
                  type: string
        variants:
          type: array
          description: Product variants (only when view = product_details)
          items:
            type: object
            properties:
              variant_id:
                type: integer
                description: Shopify variant ID
              title:
                type: string
              display_name:
                type: string
              price:
                type: string
                description: Price as string with decimals
              compare_at_price:
                type: string
                nullable: true
              sku:
                type: string
              position:
                type: integer
              is_in_stock:
                type: boolean
              available_for_sale:
                type: boolean
              sellable_online_quantity:
                type: integer
              selected_options:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                    value:
                      type: string
        metafields:
          type: array
          description: Product metafields (only when view = product_details)
          items:
            type: object
        product_type:
          type: string
          description: Product type (only when view = product_details)
        vendor:
          type: string
          description: Product vendor (only when view = product_details)
      description: >-
        A recommended product. With `view: product_ids` only `product_id` is
        present.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.