# Generate handbill for Profile

- Operation ID: `getHandbillForClient_GET`
- HTTP method: `GET`
- Path: `/v4/promotions/promotion/get-for-client/handbill/{handbillUuid}`
- [Human-readable API reference](https://hub.synerise.com/api-reference/loyalty-and-engagement#tag/Handbills/operation/getHandbillForClient_GET)

## Self-contained OpenAPI method

The fenced document below contains this method's documentation and all of its local references. It is self-contained; no category or master specification fetch is required.

```yaml
openapi: 3.0.0
info:
  title: Synerise Public API
  version: 1.9.1
paths:
  /v4/promotions/promotion/get-for-client/handbill/{handbillUuid}:
    get:
      tags:
        - Handbills
      summary: Generate handbill for Profile
      description: |
        Assign handbill promotions to a Profile. They can be randomized or suggested by the AI engine.

        **IMPORTANT**: 
        - The endpoint is limited to 1000 requests per minute (per workspace).
        - The algorithm that selects promotions for assignment candidates applies all the following filters:
            - Promotions must be of the specified type, assigned to a handbill campaign, and with the `PUBLISH` status.
            - Promotions must be available for the entire duration of the handbill assignment, considering `startAt` and `expireAt` dates. For example, when generating assignments on May 1, 2024 at 9:00 a.m. that are expected to last 3 hours, the algorithm will consider promotions whose `startAt` date is equal to or earlier than May 1, 2024 9:00 a.m. and `expireAt` date is equal to or later than May 1, 2024 12:00 p.m. 
            - Promotions can't currently be assigned within another handbill campaign.
            - Promotions must match the filter for the slot (if applicable). Promotions are handled by the `binoculars` service and identified by UUID.
            - Promotions are deduplicated. First they are sorted by priority, then the algorithm rejects promotions with at least one product that occurred earlier. In a special case, if a promotion with a high priority has an extensive catalog of products covering other promotions, it could exclude all promotions with a lower priority.
            - If `excludeByAvailableProducts` is set to `true`, the algorithm rejects promotions for items that are available as part of other promotions (regardless of their type)
            - After sorting promotions by priority, the algorithm rejects promotions for segments that occur after the 100th unique segment is encountered. (only 100 segments can be checked per handbill assignment, consider limiting the number of segments and reusing them).
            - After checking the first 100 unique segments, the algorithm rejects promotions for segments that don't match the user.
            - To ensure the correctness of promotion usage and redemption, the algorithm rejects promotions that are currently in the `ACTIVE` or `REDEEMED` status.
            - Candidate promotions are gathered per handbill slot. For each slot, at most a configurable number of promotions (default 40,000) is read from the database, ordered by priority ascending (`1` = highest); any promotions beyond that limit are not considered for that slot. Promotions sharing the same priority have no guaranteed order between them, so when the limit falls within a group of equal priority it is not defined which of them are kept — assign distinct priorities to control this.
            - When using the AI engine, the total number of candidate promotions sent to the recommendation engine in a single request is capped by a configurable limit (default 45,000). If the combined candidates across all slots exceed this limit, each slot is reduced proportionally to the number of candidates it contributed, but never below a configurable per-slot floor (default 1,000), so the smallest slots are left intact.


        ---

        **API consumers:** <a href="/api-reference/authorization?tag=Authorization&amp;operationId=authenticateUsingPOST_v3" target="_blank" rel="noopener">Profile (Client)</a>, <a href="/api-reference/authorization?tag=Authorization&amp;operationId=LogInAnonymouslyV3" target="_blank" rel="noopener">Anonymous Profile</a>
      operationId: getHandbillForClient_GET
      security:
        - JWT: []
      parameters:
        - name: handbillUuid
          in: path
          required: true
          description: UUID of the handbill configuration
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          description: The number of items to return per page
          required: false
          schema:
            type: integer
            example: 100
            default: 100
            maximum: 1000
        - name: page
          in: query
          description: Page number to return for pagination. The first page has the index `1`.
          required: false
          schema:
            type: integer
            format: int32
            example: 4
            default: 1
        - name: fields
          in: query
          description: Return only specified promotion fields. If `fields` is not specified, all fields are returned.
          required: false
          style: form
          explode: false
          schema:
            example: uuid,requireRedeemedPoints,requireRedeemedPoints,possibleRedeems,status,currentRedeemedQuantity,lastingAt
            type: array
            items:
              type: string
              enum:
                - uuid
                - code
                - status
                - type
                - redeemLimitPerClient
                - redeemQuantityPerActivation
                - currentRedeemedQuantity
                - currentRedeemLimit
                - activationCounter
                - possibleRedeems
                - details
                - discountType
                - discountValue
                - discountMode
                - discountModeDetails
                - requireRedeemedPoints
                - name
                - headline
                - description
                - images
                - startAt
                - expireAt
                - displayFrom
                - displayTo
                - assignedAt
                - lastingTime
                - lastingAt
                - catalogIndexItems
                - params
                - price
                - priority
                - maxBasketValue
                - minBasketValue
                - itemScope
                - tags
                - handbillUuid
      responses:
        "200":
          description: A list of handbill-type promotions assigned to this profile
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    description: An array of promotions
                    items:
                      type: object
                      description: Details of a promotion
                      properties:
                        uuid:
                          type: string
                          description: Unique UUIDv4.
                        code:
                          type: string
                          maxLength: 64
                          description: Unique code
                        status:
                          type: string
                          description: Profile-oriented status of the promotion.
                          enum:
                            - ASSIGNED
                            - ACTIVE
                            - REDEEMED
                        type:
                          type: string
                          description: Promotion type
                          enum:
                            - MEMBERS_ONLY
                            - HANDBILL
                            - CUSTOM
                            - GENERAL
                          default: GENERAL
                        redeemLimitPerClient:
                          type: integer
                          description: Limit how many times a Profile can redeem this promotion.
                          default: 0
                          minimum: 0
                          maximum: 32767
                          nullable: true
                        redeemQuantityPerActivation:
                          type: integer
                          nullable: true
                          description: How many times per activation a multibuy promotion can be redeemed
                          minimum: 0
                          maximum: 8388607
                        currentRedeemedQuantity:
                          type: integer
                          description: Current redeem quantity for the Profile.
                        currentRedeemedLimit:
                          type: integer
                          description: Current redeem limit for the Profile.
                        activationCounter:
                          type: integer
                          description: Number of promotion activation
                        possibleRedeems:
                          type: integer
                          description: Number of available redeems left
                        details:
                          type: object
                          description: Promotion details
                          required:
                            - discountType
                          nullable: true
                          properties:
                            discountType:
                              type: object
                              description: Details that apply for specific discount type
                              required:
                                - name
                                - outerScope
                                - requiredItemsCount
                                - discountedItemsCount
                              properties:
                                name:
                                  type: string
                                  enum:
                                    - BOGO
                                  default: BOGO
                                outerScope:
                                  type: boolean
                                  description: |
                                    This defines whether a defined promotion trigger for discount is based on different item scope.
                                    When set to
                                      * `false` it means items are from the same scope,
                                      * `true` it means items are from outer scope and `requiredItems` should be defined.
                                  default: false
                                  example: true
                                requiredItemsCount:
                                  description: Number of items that should be purchased to meet the promotion condition.
                                  type: integer
                                  format: int32
                                  example: 2
                                discountedItemsCount:
                                  description: Number of items to apply the discount to.
                                  type: integer
                                  format: int32
                                  example: 1
                        discountType:
                          type: string
                          description: The type of discount
                          enum:
                            - PERCENT
                            - POINTS
                            - AMOUNT
                            - NONE
                            - MULTIBUY
                            - 2_FOR_1
                            - EXACT_PRICE
                            - DIGITAL_CASHBACK
                          default: NONE
                        discountValue:
                          type: number
                          description: How much discount to apply
                          default: 0
                          minimum: 0
                          maximum: 100
                        discountMode:
                          type: string
                          description: Promotion discount mode
                          enum:
                            - STATIC
                            - STEP
                          default: STATIC
                        discountModeDetails:
                          type: object
                          properties:
                            steps:
                              type: array
                              nullable: false
                              minItems: 1
                              maxItems: 5
                              items:
                                required:
                                  - discountValue
                                  - usageThreshold
                                type: object
                                properties:
                                  discountValue:
                                    description: Discount value in given step
                                    type: number
                                  usageThreshold:
                                    description: Threshold after current step would apply
                                    type: number
                            discountUsageTrigger:
                              type: string
                              enum:
                                - TRANSACTION
                                - REDEEM
                              nullable: false
                              description: Describe after what action new steps would be applied
                          nullable: true
                          description: 'Applies only when `"discountMode": "STEP"`.'
                        requireRedeemedPoints:
                          type: number
                          nullable: true
                          format: int32
                          description: How many loyalty points are needed to activate the promotion
                        name:
                          type: string
                          maxLength: 255
                          description: Promotion name displayed to viewers
                        headline:
                          type: string
                          nullable: true
                          description: Promotion headline displayed to viewers
                        description:
                          type: string
                          maxLength: 2048
                          nullable: true
                          description: Details of the promotion displayed to viewers
                        images:
                          type: array
                          nullable: true
                          items:
                            required:
                              - url
                              - type
                            type: object
                            properties:
                              url:
                                description: Image or thumbnail source. Must be an absolute HTTP/HTTPS URL.
                                type: string
                                format: uri
                                example: https://www.snrcdn.net/upload/f2afa4d4d7af216196047d1f7f0613f22a50a8c8/default/origin/1537188683527-el-ipadpro.png
                              type:
                                type: string
                                enum:
                                  - image
                                  - thumbnail
                          description: Images and thumbnails for the promotion
                        tags:
                          description: |
                            An array of tags.

                            **IMPORTANT:** To be able to use a tag for promotions, you must first assign the tag to a directory with `"type":"promotion"`. If the directory type does not exist, create it using [this endpoint](https://developers.synerise.com/AssetManagement/AssetManagement.html#operation/createDirectoryType). Then create a directory of that type and assign tags to it.
                          type: array
                          items:
                            type: object
                            properties:
                              hash:
                                type: string
                                description: Hash ID of the tag
                                example: 6f54671d-157f-4c4e-a577-11fac3111293
                          nullable: true
                        startAt:
                          type: string
                          nullable: true
                          format: date-time
                          description: Time when the promotion becomes available. Defaults to current time.
                        expireAt:
                          type: string
                          nullable: true
                          format: date-time
                          description: Time when the promotion ends for all profiles. Defaults to current time. Has to be greater than startAt
                        displayFrom:
                          type: string
                          nullable: true
                          description: Time when the promotion becomes displayable. Defaults to null.
                        displayTo:
                          type: string
                          nullable: true
                          description: Time when the promotion stops being displayed for users. Defaults to null. Has to be greater than displayFrom.
                        assignedAt:
                          type: string
                          nullable: true
                          format: date-time
                          description: Time when promotion becomes active for the Profile.
                        lastingTime:
                          type: integer
                          format: int32
                          nullable: true
                          description: Duration of the promotion in seconds. This countdown starts when the profile activates a promotion and is individual for each profile.
                          default: 0
                        lastingAt:
                          type: string
                          nullable: true
                          format: date-time
                          description: Time when promotion becomes expire for the Profile.
                        params:
                          type: object
                          description: A JSON object with any custom parameters of type string, object, array.
                          nullable: true
                          additionalProperties: true
                        catalogIndexItems:
                          type: array
                          items:
                            type: string
                          description: |
                            
                            'An array of items from the catalog to be included in the promotion if `catalogItemType` is set to `SELECTED`.


                            If `catalogItemType` is set to `ALL`, set `catalogIndexItems` to null.'
                          nullable: true
                          example: []
                        price:
                          description: In single-item promotions, this is the price of the item in the smallest unit of currency. For example, if the currency is USD and `price` is 120, the price is 1 dollar and 20 cents.
                          type: integer
                          default: 0
                          minimum: 0
                          maximum: 2147483647
                        priority:
                          description: Defines the promotion's priority, used both for display order and to order candidate promotions when they are selected during handbill and checkout assignment. Values are ordered ascending, so a lower number means a higher priority and `1` is the highest. When the per-slot read limit or the AI request cap truncates the candidate list, the higher-priority (lower-numbered) promotions are the ones kept. Promotions that share the same priority have no further guaranteed ordering between them, so when a truncation boundary falls inside a group of equal priority it is not defined which of them are kept — assign distinct priorities to the promotions that must always win.
                          type: integer
                          minimum: 1
                          maximum: 500
                          default: 250
                        itemScope:
                          type: string
                          description: |-
                            The scope of of the promotion.
                            * LINE_ITEM is a promotion used for certain items in the basket
                            * BASKET is a promotion that applies to the entire basket
                          enum:
                            - LINE_ITEM
                            - BASKET
                          default: LINE_ITEM
                        minBasketValue:
                          type: number
                          nullable: true
                          default: null
                          minimum: 0
                          description: |
                            Minimal basket value required to trigger the application of the promotion. This is the basket value after calculating other promotions that apply to the items in the basket. 

                            `minBasketValue` must be lower than `maxBasketValue`.
                        maxBasketValue:
                          type: number
                          nullable: true
                          default: null
                          minimum: 0
                          description: |
                            
                            The maximum basket value to apply the promotion to. Any amount above the maximum is not discounted. This is the basket value after calculating other promotions that apply to the items in the basket.

                            `maxBasketValue` must be greater than `minBasketValue`

                            **Example:**<br/>
                            The maximum basket value is set to 500 USD. The discount is 10%. A basket's total is 700 USD. The discount is 50 USD.
                        vouchers:
                          type: array
                          description: Vouchers redeemed successfully
                          items:
                            type: object
                            required:
                              - code
                              - status
                              - autoGenerated
                              - lastingAt
                              - redeemedAt
                              - assignedAt
                            properties:
                              code:
                                type: string
                                description: Voucher code
                                example: 6f54671d-157f-4c4e-a577-11fac3111293
                              status:
                                type: string
                                description: Status of the voucher
                                example: ASSIGNED
                                enum:
                                  - ASSIGNED
                                  - REDEEMED
                                  - CANCELED
                              autoGenerated:
                                type: boolean
                                example: false
                                description: "`true` if the voucher was generated by an algorithm"
                              lastingAt:
                                type: string
                                nullable: true
                                example: 2026-01-01
                                format: date-time
                                description: Time when the voucher expires.
                              redeemedAt:
                                type: string
                                nullable: true
                                example: null
                                format: date-time
                                description: Time when the voucher was redeemed.
                              assignedAt:
                                type: string
                                nullable: true
                                example: 2025-01-01
                                format: date-time
                                description: Time when the voucher was assigned.
                        extra:
                          type: object
                          nullable: true
                          description: |
                            Assignment provenance when the promotion was assigned from a handbill. Absent otherwise. Reflects the handbill config at assignment time. Always returned regardless of the `fields` query param.
                          properties:
                            slot:
                              type: integer
                              minimum: 0
                              description: Index in the handbill variant's `slotFilters.slots` the item filled.
                            assignmentSource:
                              type: string
                              enum:
                                - ai
                                - ai_relaxed_filter
                                - random
                                - fallback_random
                                - fallback_pool
                              description: |
                                How the item was selected. `ai_relaxed_filter` marks items the AI engine added itself to fill the slot (e.g. to complete a distinct-filtered slot). Extensible — clients must tolerate new values.
                  meta:
                    type: object
                    description: Optional metadata
                    properties:
                      code:
                        type: integer
                        description: HTTP code
                      limit:
                        type: integer
                        description: The number of items per page
                      link:
                        type: array
                        description: Links to other pages
                        items:
                          type: object
                          description: Link to another page on the list
                          properties:
                            rel:
                              type: string
                              enum:
                                - first
                                - last
                                - next
                                - prev
                              description: The type of relationship to the current page
                            url:
                              type: string
                              description: The URL of the page
                      page:
                        type: integer
                        description: The current page
                      totalCount:
                        type: integer
                        description: The total number of items on all pages
                      totalPages:
                        type: integer
                        description: The total number of pages
        "400":
          description: Request body invalid/malformed/missing elements
          content:
            application/json:
              schema:
                anyOf:
                  - type: object
                    title: JSON content issue
                    properties:
                      message:
                        type: string
                        description: Summary of the error
                      error:
                        description: Details of the error
                        anyOf:
                          - type: array
                            description: An array of objects with error details
                            items:
                              type: object
                              description: Details of an error
                              properties:
                                message:
                                  type: string
                                  description: Short description of the error
                                  example: Internal Error
                                additionalProperties:
                                  description: Additional information, if applicable
                          - type: string
                            description: Description of the error
                  - type: object
                    title: JSON structure issue
                    properties:
                      message:
                        type: string
                        description: Summary of the error
                      code:
                        type: string
                        description: String-type code of the error
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    description: HTTP code of the problem
                  error:
                    type: string
                    description: Summary of the error
                  message:
                    type: string
                    description: Error details
                  timestamp:
                    type: string
                    description: Time when the error occurred
        "403":
          description: Forbidden
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: integer
                    description: HTTP code of the problem
                  error:
                    type: string
                    description: Summary of the error
                  message:
                    type: string
                    description: Error details
                  timestamp:
                    type: string
                    description: Time when the error occurred
        "409":
          description: Waiting for profile lock release
          content:
            application/json:
              schema:
                type: object
                title: JSON content issue
                properties:
                  message:
                    type: string
                    description: Summary of the error
                  error:
                    description: Details of the error
                    anyOf:
                      - type: array
                        description: An array of objects with error details
                        items:
                          type: object
                          description: Details of an error
                          properties:
                            message:
                              type: string
                              description: Short description of the error
                              example: Internal Error
                            additionalProperties:
                              description: Additional information, if applicable
                      - type: string
                        description: Description of the error
      x-snr-doc-urls:
        - /api-reference/loyalty-and-engagement#tag/Handbills/operation/getHandbillForClient_GET
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |-
            curl --request GET \
              --url 'https://api.synerise.com/v4/promotions/promotion/get-for-client/handbill/%7BhandbillUuid%7D?limit=100&page=4&fields=uuid%2CrequireRedeemedPoints%2CrequireRedeemedPoints%2CpossibleRedeems%2Cstatus%2CcurrentRedeemedQuantity%2ClastingAt' \
              --header 'Authorization: Bearer REPLACE_BEARER_TOKEN'
        - lang: Python
          label: Python
          source: |-
            import http.client

            conn = http.client.HTTPSConnection("api.synerise.com")

            headers = { 'Authorization': "Bearer REPLACE_BEARER_TOKEN" }

            conn.request("GET", "/v4/promotions/promotion/get-for-client/handbill/%7BhandbillUuid%7D?limit=100&page=4&fields=uuid%2CrequireRedeemedPoints%2CrequireRedeemedPoints%2CpossibleRedeems%2Cstatus%2CcurrentRedeemedQuantity%2ClastingAt", headers=headers)

            res = conn.getresponse()
            data = res.read()

            print(data.decode("utf-8"))
        - lang: JavaScript
          label: JavaScript
          source: |-
            const data = null;

            const xhr = new XMLHttpRequest();
            xhr.withCredentials = true;

            xhr.addEventListener("readystatechange", function () {
              if (this.readyState === this.DONE) {
                console.log(this.responseText);
              }
            });

            xhr.open("GET", "https://api.synerise.com/v4/promotions/promotion/get-for-client/handbill/%7BhandbillUuid%7D?limit=100&page=4&fields=uuid%2CrequireRedeemedPoints%2CrequireRedeemedPoints%2CpossibleRedeems%2Cstatus%2CcurrentRedeemedQuantity%2ClastingAt");
            xhr.setRequestHeader("Authorization", "Bearer REPLACE_BEARER_TOKEN");

            xhr.send(data);
        - lang: Node.js
          label: Node.js
          source: |-
            const http = require("https");

            const options = {
              "method": "GET",
              "hostname": "api.synerise.com",
              "port": null,
              "path": "/v4/promotions/promotion/get-for-client/handbill/%7BhandbillUuid%7D?limit=100&page=4&fields=uuid%2CrequireRedeemedPoints%2CrequireRedeemedPoints%2CpossibleRedeems%2Cstatus%2CcurrentRedeemedQuantity%2ClastingAt",
              "headers": {
                "Authorization": "Bearer REPLACE_BEARER_TOKEN"
              }
            };

            const req = http.request(options, function (res) {
              const chunks = [];

              res.on("data", function (chunk) {
                chunks.push(chunk);
              });

              res.on("end", function () {
                const body = Buffer.concat(chunks);
                console.log(body.toString());
              });
            });

            req.end();
        - lang: PHP
          label: PHP
          source: |-
            <?php

            $request = new HttpRequest();
            $request->setUrl('https://api.synerise.com/v4/promotions/promotion/get-for-client/handbill/%7BhandbillUuid%7D');
            $request->setMethod(HTTP_METH_GET);

            $request->setQueryData([
              'limit' => '100',
              'page' => '4',
              'fields' => 'uuid,requireRedeemedPoints,requireRedeemedPoints,possibleRedeems,status,currentRedeemedQuantity,lastingAt'
            ]);

            $request->setHeaders([
              'Authorization' => 'Bearer REPLACE_BEARER_TOKEN'
            ]);

            try {
              $response = $request->send();

              echo $response->getBody();
            } catch (HttpException $ex) {
              echo $ex;
            }
        - lang: Java
          label: Java
          source: |-
            HttpResponse<String> response = Unirest.get("https://api.synerise.com/v4/promotions/promotion/get-for-client/handbill/%7BhandbillUuid%7D?limit=100&page=4&fields=uuid%2CrequireRedeemedPoints%2CrequireRedeemedPoints%2CpossibleRedeems%2Cstatus%2CcurrentRedeemedQuantity%2ClastingAt")
              .header("Authorization", "Bearer REPLACE_BEARER_TOKEN")
              .asString();
servers:
  - description: Microsoft Azure EU
    url: https://api.synerise.com
  - description: Microsoft Azure USA
    url: https://api.azu.synerise.com
  - description: Google Cloud Platform
    url: https://api.geb.synerise.com
tags:
  - name: Handbills
components:
  securitySchemes:
    JWT:
      type: http
      scheme: bearer
      description: |-
        JWT Bearer token. The header looks like this: `Bearer {JWT}`

        Remember to include the space between 'Bearer' and the token.

        Generate a token via the **Authorization** endpoints.
```
