> ## 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 Headless Recommendations using Query

> Fetch recommendations for up to five queries in one call, personalized to the shopper you identify.

## Identifying the shopper

Every identity field is **optional**. Send whichever ones your storefront has, and Glood
resolves them to a single visitor profile:

| Field | Use when |
| - | - |
| `client_id` | You have the Shopify `_shopify_y` device cookie. |
| `user_id` | You have the Glood-generated user id (returned by [Headless Init](/api-reference/recommendations/headless/init)). |
| `customer_id` | The shopper is logged in and you have their Shopify customer ID. |
| `email` | You have no `customer_id` — resolves to the same profile. |
| `phone` | Same as `email`, for storefronts that identify shoppers by phone. |

`email` and `phone` exist for storefronts that never see a Shopify `customer_id`. They
identify the **same** shopper profile a `customer_id` would, so recommendations are
personalized identically either way.

<Tip>
  Send every identifier you have, not just one. A shopper often has both an anonymous
  browsing profile (under `client_id`) and an identified one (under `customer_id` or
  `email`). Passing both lets Glood pick whichever holds the richer browsing history.
</Tip>

Matching ignores formatting, so you do not need to normalize before sending:

* `email` — case and surrounding whitespace are ignored (`" Shopper@Example.com "` matches `shopper@example.com`)
* `phone` — punctuation and spacing are ignored (`+1 (555) 010-9999` matches `+15550109999`)

<Note>
  Sending no identifier at all is valid. You get the same recommendations, just without
  personalization — no error. An unrecognized `email` or `phone` behaves the same way.
</Note>

## How personalization works

When a request identifies a shopper with browsing history, results are ranked using that
history in addition to the products in `product_ids`:

* **`similar_products`** — stays anchored to the products you asked about; browsing history
  refines the ordering rather than replacing it.
* **`bought_together`** — the same blend, applied to co-purchase candidates.

Only **browsing** history is used. Purchase and cart history do not affect ranking.

To override the automatic behaviour, set `ranking_criteria` on an individual query — for
example `bestsellers` or `new_arrivals`. Leaving it unset is recommended.

<Note>
  Personalization improves as browsing data accumulates. A shopper Glood has not seen before
  receives standard relevance-ranked recommendations.
</Note>

<ResponseExample>
  ```json 200 - product_details view theme={null}
  {
    "status": "ok",
    "serve_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "data": {
      "rec-1": {
        "recommendation_serve_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "recommendation_type": "similar_products",
        "max_recommendations": 10,
        "creation_type": "automatic",
        "product_ids": [123, 456],
        "view": "product_details",
        "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",
            "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": []
          }
        ]
      }
    }
  }
  ```

  ```json 200 - product_ids view theme={null}
  {
    "status": "ok",
    "serve_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "data": {
      "rec-1": {
        "recommendation_serve_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "recommendation_type": "similar_products",
        "max_recommendations": 10,
        "creation_type": "automatic",
        "product_ids": [123, 456],
        "view": "product_ids",
        "recommendations": [
          { "product_id": 9311227838783 },
          { "product_id": 9311227838784 }
        ]
      }
    }
  }
  ```

  ```json 400 theme={null}
  {
    "errors": [
      {
        "message": "\"product_ids\" is required",
        "path": ["queries", 0, "product_ids"],
        "type": "any.required",
        "context": {
          "label": "queries[0].product_ids",
          "key": "product_ids"
        }
      }
    ]
  }
  ```
</ResponseExample>


## OpenAPI

````yaml POST /api/storefront/v3/headless/recommendations
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:
    post:
      description: >-
        Get AI recommendations including Manual, Rules, LLM & AI using Query.


        The `product_ids` field within each query item accepts **either** a JSON
        array of integers (e.g. `[123, 456]`) **or** a comma-separated string
        (e.g. `"123,456"`). The CSV form is provided for clients whose
        serializers cannot construct arrays from variables.
      parameters:
        - name: x-shop
          in: header
          description: Shopify store URL
          required: true
          schema:
            type: string
            example: shop.myshopify.com
      requestBody:
        description: Request body
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HeadlessQueryRecommendationsRequest'
            examples:
              arrayProductIds:
                summary: product_ids as JSON array
                value:
                  client_id: client-abc
                  user_id: user-xyz
                  queries:
                    - id: rec-1
                      recommendation_type: similar_products
                      product_ids:
                        - 123
                        - 456
                      view: product_ids
                      max_recommendations: 10
              csvProductIds:
                summary: product_ids as CSV string
                value:
                  client_id: client-abc
                  user_id: user-xyz
                  queries:
                    - id: rec-1
                      recommendation_type: similar_products
                      product_ids: 123,456
                      view: product_ids
                      max_recommendations: 10
              identifyByEmail:
                summary: Identify the shopper by email instead of customer_id
                value:
                  email: shopper@example.com
                  queries:
                    - id: rec-1
                      recommendation_type: similar_products
                      product_ids:
                        - 123
                      view: product_ids
                      max_recommendations: 10
              identifyByPhone:
                summary: Identify the shopper by phone number
                value:
                  phone: '+15550109999'
                  queries:
                    - id: rec-1
                      recommendation_type: bought_together
                      product_ids:
                        - 123
                      view: product_ids
              identifyWithFallback:
                summary: Send every identifier you have (recommended)
                value:
                  client_id: client-abc
                  user_id: user-xyz
                  email: shopper@example.com
                  queries:
                    - id: rec-1
                      recommendation_type: similar_products
                      product_ids:
                        - 123
                      view: product_details
      responses:
        '200':
          description: Recommendations response
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/HeadlessQueryRecommendationsProductDetailsResponse
              example:
                status: ok
                serve_id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                data:
                  rec-1:
                    recommendation_serve_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    recommendation_type: similar_products
                    max_recommendations: 10
                    creation_type: automatic
                    product_ids:
                      - 123
                      - 456
                    view: product_details
                    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
                        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: []
        '400':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HeadlessQueryRecommendationsError'
components:
  schemas:
    HeadlessQueryRecommendationsRequest:
      type: object
      required:
        - queries
      properties:
        client_id:
          type: string
          description: Client identifier (Shopify `_shopify_y` device cookie). Optional.
        user_id:
          type: string
          description: User identifier generated by Glood. Optional.
        customer_id:
          type: string
          description: Shopify customer ID for a logged-in shopper. Optional.
        email:
          type: string
          description: >-
            Shopper email address. Use this when your storefront has no access
            to a Shopify `customer_id` — it resolves to the same visitor
            profile. Case and surrounding whitespace are ignored. Optional.
          example: shopper@example.com
        phone:
          type: string
          description: >-
            Shopper phone number. Alternative to `customer_id`, with the same
            behaviour as `email`. Formatting is ignored, so `+1 (555) 010-9999`
            and `+15550109999` are equivalent. Optional.
          example: '+15550109999'
        queries:
          type: array
          items:
            type: object
            required:
              - id
              - recommendation_type
              - product_ids
              - view
            properties:
              id:
                type: string
                description: Unique identifier for the query
              recommendation_type:
                type: string
                description: Type of recommendations to retrieve
                enum:
                  - bought_together
                  - similar_products
              max_recommendations:
                type: integer
                description: >-
                  Maximum number of recommendations to return. Minimum is 1 and
                  maximum is 50
                minimum: 1
                maximum: 50
              product_ids:
                description: >-
                  List of product IDs to get recommendations for. Accepts either
                  a JSON array of integers or a comma-separated string. Maximum
                  10 IDs.


                  Examples:

                  - Array: `[123, 456]`

                  - CSV string: `"123,456"`
                oneOf:
                  - title: integer[]
                    type: array
                    items:
                      type: integer
                    maxItems: 10
                    example:
                      - 123
                      - 456
                  - title: string (CSV)
                    type: string
                    example: 123,456
                    description: Comma-separated product IDs (e.g. "123,456")
              creation_type:
                type: string
                description: Type of recommendation creation method
                enum:
                  - manual
                  - automatic
              ranking_criteria:
                type: string
                description: >-
                  How the recommendations are ordered. Optional — leave it unset
                  and Glood picks for you: `personalised` when the request
                  identifies a visitor with browsing history, otherwise the
                  default relevance ordering. Set it explicitly only to override
                  that.
                enum:
                  - personalised
                  - bestsellers
                  - new_arrivals
                  - lowest_priced
                  - highest_priced
                  - random
              view:
                type: string
                description: Format of the recommendations response
                enum:
                  - product_details
                  - product_ids
        publicationIds:
          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'
    HeadlessQueryRecommendationsProductDetailsResponse:
      type: object
      required:
        - status
        - serve_id
        - data
      properties:
        status:
          type: string
          enum:
            - ok
          description: Response status
        serve_id:
          type: string
          format: uuid
          description: Unique identifier for this recommendation serve request
        data:
          type: object
          description: Recommendation results keyed by query ID
          additionalProperties:
            type: object
            properties:
              recommendation_serve_id:
                type: string
                format: uuid
                description: Unique identifier for this specific recommendation serve
              recommendation_type:
                type: string
                enum:
                  - similar_products
                  - bought_together
                description: Type of recommendations returned
              max_recommendations:
                type: integer
                description: Maximum number of recommendations requested
              creation_type:
                type: string
                nullable: true
                enum:
                  - automatic
                  - manual
                  - null
                description: Recommendation creation method used
              product_ids:
                type: array
                items:
                  type: integer
                description: Product IDs from the request (parsed from array or CSV)
              view:
                type: string
                enum:
                  - product_ids
                  - product_details
                description: Response format that was requested
              recommendations:
                type: array
                description: >-
                  List of recommended products. Structure depends on the `view`
                  parameter.
                items:
                  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
      example:
        status: ok
        serve_id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
        data:
          rec-1:
            recommendation_serve_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
            recommendation_type: similar_products
            max_recommendations: 10
            creation_type: automatic
            product_ids:
              - 123
              - 456
            view: product_details
            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
                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: []
    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
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````

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